Python file to slow, how peed up ? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Python file to slow, how peed up ? (/thread-15107.html) |
Python file to slow, how peed up ? - Leon - Jan-04-2019 Hello, I've built a Python script to make pictures and cut them in the right size automatic. Everything works ok only it is very slow. One picture takes about 7 sec. to make and cut. Is it possible to speed things up a little ? I've read about Numba and Cython only i'm not a programmer so it is not so easy for me. Maby somebody has some tips and tricks for me ? from PIL import Image,ImageChops import glob import os import sys import threading import time import datetime ######################################################### from ctypes import * from pathlib import Path import pythoncom import datetime ######################################################## global fileName global trimVariable global c old_path = None global image_to_save global image_path global cam edsdk = windll.edsdk def AddTime(fname): now = datetime.datetime.now() nname = fname[:-4]+'_'+now.isoformat()[:-7].replace(':','-')+fname[-4:] return nname class EDSDKError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) def EDErrorMsg(code): return "EDSDK error code"+hex(code) def Call(code): if code!=0: raise Exception(EDSDKError, EDErrorMsg(code)) def Release(ref): edsdk.EdsRelease(ref) def GetChildCount(ref): i = c_int() Call(edsdk.EdsGetChildCount(ref,byref(i))) return i.value def GetChild(ref,number): c = c_void_p() Call(edsdk.EdsGetChildAtIndex(ref,number,byref(c))) return c kEdsObjectEvent_DirItemRequestTransfer = 0x00000208 kEdsObjectEvent_DirItemCreated = 0x00000204 ObjectHandlerType = WINFUNCTYPE (c_int,c_int,c_void_p,c_void_p) def ObjectHandler_py(event,object,context): if event==kEdsObjectEvent_DirItemRequestTransfer: DownloadImage(object) return 0 ObjectHandler = ObjectHandlerType(ObjectHandler_py) kEdsStateEvent_WillSoonShutDown = 0x00000303 StateHandlerType = WINFUNCTYPE (c_int,c_int,c_int,c_void_p) def StateHandler_py(event,state,context): if event==kEdsStateEvent_WillSoonShutDown: print ("cam about to shut off") Call(edsdk.EdsSendCommand(context,1,0)) return 0 StateHandler = StateHandlerType(StateHandler_py) PropertyHandlerType = WINFUNCTYPE (c_int,c_int,c_int,c_int,c_void_p) def PropertyHandler_py(event,property,param,context): return 0 PropertyHandler = PropertyHandlerType(PropertyHandler_py) class DirectoryItemInfo(Structure): _fields_ = [("size", c_int), ("isFolder", c_int), ("groupID",c_int), ("option",c_int), ("szFileName",c_char*256), ("format",c_int)] WaitingForImage = False ImageFilename = None def DownloadImage(Image,): dirinfo = DirectoryItemInfo() Call(edsdk.EdsGetDirectoryItemInfo(Image,byref(dirinfo))) stream = c_void_p() global ImageFilename if ImageFilename is None: print ("Image was taken manually") ImageFilename = AddTime(".jpg") print (("Saving as"),ImageFilename) Call(edsdk.EdsCreateFileStream(ImageFilename,1,2,byref(stream))) print (ImageFilename) Call(edsdk.EdsDownload(Image,dirinfo.size,ImageFilename,stream)) Call(edsdk.EdsDownloadComplete(Image)) Release(stream) p = Path('I') p.rename (ImageFilename) global WaitingForImage WaitingForImage = False kEdsSaveTo_Camera = 1 kEdsSaveTo_Host = 2 kEdsSaveTo_Both = kEdsSaveTo_Camera | kEdsSaveTo_Host kEdsPropID_SaveTo = 0x0000000b class EdsCapacity(Structure): _fields_ = [("numberOfFreeClusters", c_int), ("bytesPerSector", c_int), ("reset",c_int)] class Camera: def __init__(self,camnum=0): self.cam = None l = CameraList() self.cam = l.GetCam(camnum) Call(edsdk.EdsSetObjectEventHandler(self.cam,0x200,ObjectHandler,None)) Call(edsdk.EdsSetPropertyEventHandler(self.cam,0x100,PropertyHandler,None)) Call(edsdk.EdsSetCameraStateEventHandler(self.cam,0x300,StateHandler,self.cam)) Call(edsdk.EdsOpenSession(self.cam)) self.SetProperty(kEdsPropID_SaveTo,kEdsSaveTo_Host) #set large capacity cap = EdsCapacity(10000000,512,1) Call(edsdk.EdsSetCapacity(self.cam,cap)) def __del__(self): if self.cam is not None: Call(edsdk.EdsCloseSession(self.cam)) Call(Release(self.cam)) def SetProperty(self,property,param): d = c_int(param) Call(edsdk.EdsSetPropertyData(self.cam,property,0,4,byref(d))) def AutoFocus(self): # kEdsCameraCommand_ShutterButton_OFF = 0x00000000, # kEdsCameraCommand_ShutterButton_Halfway = 0x00000001, # kEdsCameraCommand_ShutterButton_Completely = 0x00000003, # kEdsCameraCommand_ShutterButton_Halfway_NonAF = 0x00010001, # kEdsCameraCommand_ShutterButton_Completely_NonAF = 0x00010003, # note that this can fail when AF fails (error code 0x8D01) self.SendCommand(4,1) def Shoot(self,fname=None): # set saving flag global WaitingForImage WaitingForImage = True # set filename global ImageFilename if fname is None: ImageFilename = AddTime("IMG.jpg") else: ImageFilename = fname # note that this can fail when AF fails (error code 0x8D01) self.SendCommand(0) # capture succeeded so go on to download image while WaitingForImage: pythoncom.PumpWaitingMessages() return ImageFilename def KeepOn(self): # important command - keeps the camera connected when not used self.SendCommand(1) def SendCommand(self,command,param=0): #define kEdsCameraCommand_TakePicture 0x00000000 #define kEdsCameraCommand_ExtendShutDownTimer 0x00000001 #define kEdsCameraCommand_BulbStart 0x00000002 #define kEdsCameraCommand_BulbEnd 0x00000003 #define kEdsCameraCommand_DoEvfAf 0x00000102 #define kEdsCameraCommand_DriveLensEvf 0x00000103 #define kEdsCameraCommand_DoClickWBEvf 0x00000104 #define kEdsCameraCommand_PressShutterButton 0x00000004 Call(edsdk.EdsSendCommand(self.cam,command,param)) class CameraList: def __init__(self): self.list = c_void_p(None) Call(edsdk.EdsGetCameraList(byref(self.list))) print (("found"),GetChildCount(self.list),"cameras") def Count(self): return GetChildCount(self.list) def GetCam(self,number=0): print ("get cam") if self.Count()<(number+1): raise (ValueError,("Camera not found, make sure it's on and connected")) return GetChild(self.list,number) def __del__(self): Release(self.list) ######################################################### #BUFFER_SIZE = 1024 def setConnection(): global c global trimVariable f= open("instellingen.txt","r") fl =f.readlines() f.close() trimVariable=fl[4].rstrip("\n") h=fl[0].rstrip("\n") p=int(fl[1].rstrip("\n")) c = ModbusClient(host=h, port=p, auto_open=True) def getLastImage(): f= open("instellingen.txt","r") fl =f.readlines() f.close() list_of_files = glob.glob(fl[2].rstrip("\n")+'/*.JPG') # * means all if need specific format then *.csv if not list_of_files==[]: latest_file = max(list_of_files, key=os.path.getctime) return latest_file else: return None def extractFileName(qrCode): s=str(qrCode) filname='' for i in range(10,21): filname+=s[i] return str(filname) def trim1(im): bg = Image.new(im.mode, im.size, im.getpixel((0,0))) diff = ImageChops.difference(im, bg) diff = ImageChops.add(diff, diff, float(trimVariable), -100) bbox = diff.getbbox() if bbox: return im.crop(bbox) def makeItSequare(im): bg = Image.new(im.mode, im.size, im.getpixel((0,0))) diff = ImageChops.difference(im, bg) diff = ImageChops.add(diff, diff, float(trimVariable), -100) bbox = diff.getbbox() left,top,right,bottom=bbox left=left-50 #geef wat ruimte om foto right=right+50 top=top-50 width=right-left height=4000-top big_size=max(width,height) small_size=min(width,height) dif=(big_size-small_size)/2 tot=(big_size-small_size) if big_size==width: top=top-tot else: left=left-dif right=right+dif cropped_img = im.crop((left,top,right, 4000)) return cropped_img from PyQt5 import QtCore, QtGui, QtWidgets import sys app=0 app = QtWidgets.QApplication(sys.argv) class Ui_ScannerApp(object): def setupUi(self, ScannerApp): ScannerApp.setObjectName("ScannerApp") ScannerApp.resize(1350, 690) self.input = QtWidgets.QLineEdit(ScannerApp) self.input.setGeometry(QtCore.QRect(20, 30, 261, 20)) self.input.setObjectName("input") self.input.textChanged.connect(self.scanCode) self.codebare = QtWidgets.QLabel(ScannerApp) self.codebare.setGeometry(QtCore.QRect(390, 30, 301, 21)) self.codebare.setText("") self.codebare.setObjectName("codebare") self.qrtest = QtWidgets.QLabel(ScannerApp) self.qrtest.setGeometry(QtCore.QRect(800, 30, 131, 21)) self.qrtest.setText("Wacht op Code") self.qrtest.setObjectName("qrtest") self.checkBox = QtWidgets.QCheckBox(ScannerApp) self.checkBox.setGeometry(QtCore.QRect(20, 70, 211, 31)) self.checkBox.setObjectName("checkBox") self.checkBox.setChecked(True) # updates #----------------------- self.make_button = QtWidgets.QPushButton(ScannerApp) self.make_button.setGeometry(QtCore.QRect(350, 70, 150, 30)) self.make_button.setText("Make picture") self.make_button.setEnabled(False) self.make_button.clicked.connect(self.remake_image) #----- ####################### self.imageDisplayer = QtWidgets.QLabel(ScannerApp) self.imageDisplayer.setGeometry(QtCore.QRect(20, 120,1700, 571)) self.imageDisplayer.setText("") self.imageDisplayer.setObjectName("imageDisplayer") self.logoDisplayer = QtWidgets.QLabel(ScannerApp) self.logoDisplayer.setGeometry(QtCore.QRect(950,50,1500,100)) #logo plaats self.logoDisplayer.setText("") self.logoDisplayer.setObjectName("logoDisplayer") self.retranslateUi(ScannerApp) QtCore.QMetaObject.connectSlotsByName(ScannerApp) def retranslateUi(self, ScannerApp): _translate = QtCore.QCoreApplication.translate ScannerApp.setWindowTitle(_translate("ScannerApp", "Form")) self.checkBox.setText(_translate("ScannerApp", "Maak foto vierkant")) def setLogo(self): pixmap = QtGui.QPixmap() st=r'logo Mooij Techniek.png'#plaats logo pixmap.load(st) pixmap = pixmap.scaledToWidth(1500) #logo maat pixmap = pixmap.scaledToHeight(100) self.logoDisplayer.setPixmap(pixmap) def imageCropping(self,fileName): f= open("instellingen.txt","r") fl =f.readlines() f.close() directory =fl[3].rstrip("\n") path=getLastImage() if path is not None: original=Image.open(path) if self.checkBox.isChecked(): sequareImage=makeItSequare(original) st=str(directory+'/'+fileName+'.jpg') sequareImage.save(st) sequareImage.save ("voorbeeld.jpg") else: im=trim1(original) st=str(directory+'/'+fileName+'.jpg') im.save(st) im.save ("voorbeeld.jpg") os.remove(path) pixmap = QtGui.QPixmap() pixmap.load("voorbeeld.jpg") pixmap = pixmap.scaledToWidth(700) pixmap = pixmap.scaledToHeight(571) self.imageDisplayer.setPixmap(pixmap) def remake_image(self): global cam cam.Shoot() while True: #time.sleep(0.1) self.imageCropping(fileName) self.display_image() break def display_image(self): pixmap = QtGui.QPixmap() pixmap.load("voorbeeld.jpg") pixmap = pixmap.scaledToWidth(700) pixmap = pixmap.scaledToHeight(571) self.imageDisplayer.setPixmap(pixmap) def scanCode(self): scan=self.input.text() if len(scan)<31: return None else: return scan def verifiyQR(self,entry): global c global fileName if entry: self.codebare.setText(str(entry)) self.qrtest.setStyleSheet('color: green') self.qrtest.setText('Code OK') fileName=extractFileName(entry) while True: self.input.setText('') self.codebare.setText('') self.qrtest.setStyleSheet('color: black') self.qrtest.setText('Wacht op code') break def backgroundThread(self): #old_path while True: app.processEvents() code =self.scanCode() time.sleep(0.1) if code is not None: self.make_button.setEnabled(True) print(' Just checking the code ') self.verifiyQR(code) time.sleep(0.1) def activateScan(self): thread=threading.Thread(name='backgroundThread', target=self.backgroundThread) thread.start() edsdk.EdsInitializeSDK() if __name__ == "__main__": global cam pythoncom.CoInitialize() cam = Camera() ScannerApp = QtWidgets.QWidget() ui = Ui_ScannerApp() ui.setupUi(ScannerApp) setConnection() ui.setLogo() ui.activateScan() ScannerApp.show() app.exec_() edsdk.EdsTerminateSDK() RE: Python file to slow, how peed up ? - buran - Jan-04-2019 You don't really expect that someone will dig in 450 lines of spaghetti code - mixing GUI and logic, without comments, using global variables and full of magic numbers... RE: Python file to slow, how peed up ? - metulburr - Jan-04-2019 Do you really need those time sleeps in your threads? Is there a reason you are using PIL and not pillow? I do not use PIL/pillow, but just googling around it appears that pillow-SIMD may be faster than PIL and pillow http://www.dragcitycasting.com/pillow-simd/ https://www.reddit.com/r/Python/comments/4j5mla/pillowsimd_is_25_times_faster_than_pillow_and_10/ (Jan-04-2019, 05:13 PM)Leon Wrote: I've built a Python script to make pictures and cut them in the right size (Jan-04-2019, 05:13 PM)Leon Wrote: I've read about Numba and Cython only i'm not a programmer so it is not so easy for me.You've built this script but your not a programmer? A lot of your coding style makes me wonder if there are bottlenecks that you are unaware of. I would first check that before anything. The only people who are going to know the bottlenecks are yourself and any programmer that knows PIL and wants to devote the time to get into it. RE: Python file to slow, how peed up ? - Leon - Jan-05-2019 I'm using PILLOW not PIL. You must import PIL not Pillow if your using Pillow. Pillow simd is for rezising not for cropping. I'm sure there are bottlenecks, because this is my first project with Python. What is the best way to find the Bottlenecks ? RE: Python file to slow, how peed up ? - Gribouillis - Jan-05-2019 Quote:What is the best way to find the Bottlenecks ?Use the profiler (profile module). Here is an introduction with links. |