Jan-04-2019, 05:13 PM
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 ?
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()