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()
