一、安装驱动程序和测试软件(IC Capture)
本文章记录在windows系统下如何使用python打开IMAGSOURCE工业相机,项目中使用的是DFK 33UX250型号相机,为USB3.0彩色工业相机。这个是它的官网介绍:https://www.theimagingsource.cn 在window下打开相机需要安装相应的驱动软件,并安装它的测试软件,如下图所示: 网页链接在这:https://www.theimagingsource.cn/%E6%94%AF%E6%8C%81/%E8%BD%AF%E4%BB%B6%E4%B8%8B%E8%BD%BD-windows/ 这里驱动程序选择usb33u即可,测试程序可以下载IC capture软件,下载网页链接:https://www.theimagingsource.cn/%E4%BA%A7%E5%93%81/%E8%BD%AF%E4%BB%B6/%E7%BB%88%E7%AB%AF%E7%94%A8%E6%88%B7%E8%BD%AF%E4%BB%B6/ 成功下载并安装后,将相机插到电脑的usb3.0的口,打开IC Capturer软件,观察是否能找寻到接入的设备,成功打开即可。
二、使用python程序打开多个33ux250相机
话不多说,官方在github上给出了示例程序,地址:https://github.com/TheImagingSource/IC-Imaging-Control-Samples 它包含c#,java等语言的示例程序,找到它的关于python的示例,如下图所示: 示例中给出了如何打开设备,枚举设备等等的方法。主要是利用tisgrabber.py文件,它去调用底层链接库,将sample中下图中的文件放在你的文件目录中即可调用。 下面是我参考其中的程序,修改后使用的代码,实现同时打开三台相机并显示它们的型号:
import cv2
import ctypes
import tisgrabber as tis
ic = ctypes.cdll.LoadLibrary("./tisgrabber_x64.dll")
tis.declareFunctions(ic)
class list_device(object):
def __init__(self):
ic.IC_InitLibrary(0)
self.devicecount = ic.IC_GetDeviceCount()
self.grabbers = []
self.name=[]
for i in range(0, self.devicecount):
print("Device {}".format(tis.D(ic.IC_GetDevice(i))))
self.uniquename = tis.D(ic.IC_GetUniqueNamefromList(i))
print("Unique Name : {}".format(self.uniquename))
self.g = ic.IC_CreateGrabber()
ic.IC_OpenDevByUniqueName(self.g, tis.T(self.uniquename))
self.name.append(self.uniquename)
self.grabbers.append(self.g)
print(self.name)
print(self.grabbers)
def select_device_demo(self,num):
grabber=self.grabbers[num]
if (ic.IC_IsDevValid(grabber)):
ic.IC_SetVideoFormat(grabber, tis.T("RGB32 (1216x1024)"))
ic.IC_SetFrameRate(grabber, ctypes.c_float(25.0))
ic.IC_StartLive(grabber, 1)
ic.IC_MsgBox(tis.T("Click OK to stop"), tis.T("Simple Live Video"))
ic.IC_StopLive(grabber)
else:
ic.IC_MsgBox(tis.T("No device opened"), tis.T("Simple Live Video"))
ic.IC_ReleaseGrabber(grabber)
def all_device_demo(self):
for grabber in self.grabbers:
if (ic.IC_IsDevValid(grabber)):
ic.IC_SetVideoFormat(grabber, tis.T("RGB32 (1216x1024)"))
ic.IC_SetFrameRate(grabber, ctypes.c_float(25.0))
ic.IC_StartLive(grabber, 1)
ic.IC_MsgBox(tis.T("Stop'em all!"), tis.T("Live Video"))
for grabber in self.grabbers:
if (ic.IC_IsDevValid(grabber)):
ic.IC_StopLive(grabber)
for grabber in self.grabbers:
if (ic.IC_IsDevValid(grabber)):
ic.IC_ReleaseGrabber(grabber)
if __name__ == '__main__':
device=list_device()
device.all_device_demo()
注意:同时打开多台相机需要考虑你的电脑usb接口是否有这么大的带宽,不能将一个usb3.0的接口直接连一个扩展接口出来。 这是官方的tisgrabber.py程序,也放在这里:
import ctypes
from enum import Enum
class SinkFormats(Enum):
Y800 = 0
RGB24 = 1
RGB32 = 2
UYVY = 3
Y16 = 4
class FRAMEFILTER_PARAM_TYPE(Enum):
eParamLong = 0
eParamBoolean = 1
eParamFloat = 2
eParamString = 3
eParamData = 4
ImageFileTypes = {'BMP': 0, 'JPEG': 1}
IC_SUCCESS = 1
IC_ERROR = 0
IC_NO_HANDLE = -1
IC_NO_DEVICE = -2
IC_NOT_AVAILABLE = -3
IC_NO_PROPERTYSET = -3
IC_DEFAULT_WINDOW_SIZE_SET = -3
IC_NOT_IN_LIVEMODE = -3
IC_PROPERTY_ITEM_NOT_AVAILABLE = -4
IC_PROPERTY_ELEMENT_NOT_AVAILABLE = -5
IC_PROPERTY_ELEMENT_WRONG_INTERFACE = -6
IC_INDEX_OUT_OF_RANGE = -7
IC_WRONG_XML_FORMAT = -1
IC_WRONG_INCOMPATIBLE_XML = -3
IC_NOT_ALL_PROPERTIES_RESTORED = -4
IC_DEVICE_NOT_FOUND = -5
IC_FILE_NOT_FOUND = 35
class HGRABBER(ctypes.Structure):
'''
This class is used to handle the pointer to the internal
Grabber class, which contains the camera.
A pointer to this class is used by tisgrabber DLL.
'''
_fields_ = [('unused', ctypes.c_int)]
class HCODEC(ctypes.Structure):
'''
This class is used to handle the pointer to the internal
codec class for AVI capture
A pointer to this class is used by tisgrabber DLL.
'''
_fields_ = [('unused', ctypes.c_int)]
class FILTERPARAMETER(ctypes.Structure):
'''
This class implements the structure of a frame filter
parameter used by the HFRAMEFILTER class
'''
_fields_ = [
('Name', ctypes.c_char*30),
('Type', ctypes.c_int)
]
class HFRAMEFILTER(ctypes.Structure):
'''
This class implements the structure of a frame filter used
by the tisgrabber.dll.
'''
_fields_ = [
('pFilter', ctypes.c_void_p),
('bHasDialog', ctypes.c_int),
('ParameterCount', ctypes.c_int),
('Parameters', ctypes.POINTER(FILTERPARAMETER))
]
def declareFunctions(ic):
'''
Functions returning a HGRABBER Handle must set their restype to POINTER(HGRABBER)
:param ic: The loaded tisgrabber*.dll
'''
ic.IC_ShowDeviceSelectionDialog.restype = ctypes.POINTER(HGRABBER)
ic.IC_ReleaseGrabber.argtypes = (ctypes.POINTER(ctypes.POINTER(HGRABBER)),)
ic.IC_LoadDeviceStateFromFile.restype = ctypes.POINTER(HGRABBER)
ic.IC_CreateGrabber.restype = ctypes.POINTER(HGRABBER)
ic.IC_GetPropertyValueRange.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_long),
ctypes.POINTER(ctypes.c_long), )
ic.IC_GetPropertyValue.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_long), )
ic.IC_GetPropertyAbsoluteValue.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_float),)
ic.IC_GetPropertyAbsoluteValueRange.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_float),
ctypes.POINTER(ctypes.c_float),)
ic.IC_GetPropertySwitch.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_long), )
ic.IC_GetImageDescription.argtypes = (ctypes.POINTER(HGRABBER),
ctypes.POINTER(ctypes.c_long),
ctypes.POINTER(ctypes.c_long),
ctypes.POINTER(ctypes.c_int),
ctypes.POINTER(ctypes.c_int),)
ic.IC_GetImagePtr.restype = ctypes.c_void_p
ic.IC_SetHWnd.argtypes = (ctypes.POINTER(HGRABBER), ctypes.c_int)
ic.FRAMEREADYCALLBACK = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.POINTER(HGRABBER), ctypes.POINTER(ctypes.c_ubyte), ctypes.c_ulong, ctypes.py_object)
ic.DEVICELOSTCALLBACK = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.POINTER(HGRABBER), ctypes.py_object)
ic.IC_SetFrameReadyCallback.argtypes = [ctypes.POINTER(HGRABBER), ic.FRAMEREADYCALLBACK, ctypes.py_object]
ic.IC_SetCallbacks.argtypes = [ctypes.POINTER(HGRABBER),
ic.FRAMEREADYCALLBACK,
ctypes.py_object,
ic.DEVICELOSTCALLBACK,
ctypes.py_object]
ic.IC_Codec_Create.restype = ctypes.POINTER(HCODEC)
ic.ENUMCODECCB = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.py_object)
ic.IC_enumCodecs.argtypes = (ic.ENUMCODECCB, ctypes.py_object)
ic.IC_GetDeviceName.restype = ctypes.c_char_p
ic.IC_GetDevice.restype = ctypes.c_char_p
ic.IC_GetUniqueNamefromList.restype = ctypes.c_char_p
ic.IC_CreateFrameFilter.argtypes = (ctypes.c_char_p, ctypes.POINTER(HFRAMEFILTER))
def T(instr):
''' Helper function
Encodes the input string to utf-8
:param instr: Python string to be converted
:return: converted string
'''
return instr.encode("utf-8")
def D(instr):
''' Helper function
Decodes instr utf-8
:param instr: Python string to be converted
:return: converted string
'''
return instr.decode('utf-8', 'ignore')
def openDevice(ic):
''' Helper functions
Open a camera. If a file with a device state exists, it will be used.
If not, the device selection dialog is shown and if a valid devices
was selected, the device state file is created.
:return: a HGRABBER
'''
try:
hGrabber = ic.IC_LoadDeviceStateFromFile(None, T("device.xml"))
if not ic.IC_IsDevValid(hGrabber):
hGrabber = ic.IC_ShowDeviceSelectionDialog(None)
except Exception as ex:
hGrabber = ic.IC_ShowDeviceSelectionDialog(None)
if(ic.IC_IsDevValid(hGrabber)):
ic.IC_SaveDeviceStateToFile(hGrabber, T("device.xml"))
return hGrabber
|