工业相机设计图像处理和方案实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工业相机设计图像处理和方案实现相关的知识,希望对你有一定的参考价值。

最近在学习工业相机相关知识,需求是这样的:800 X 600的图像大小、40FPS、灰度图、BMP输出格式、20倍定焦镜头。由于刚接触这个,有许多不懂的,现向各位大神请教几个问题。1、我选用的单色SENSOR,输出灰度图需要做图像较正吗? 2、我采用的定焦镜头拍运动的物体,需要做3A算法吗? 3、ISP芯片+SENSOR的方案和FPGA + SENSOR的方案,那种更靠谱。还请各位大神不吝赐教,非常感谢!!

具体看图像处理的要求和想实现什么样的方案,详情可通过官方微信平台(微信公众号:RegemMarr Regem Marr 研祥金码),您可以第一时间掌握公司最新动态及各种行业资讯,也可以即时互动。同时您可以在线报修、查询网点、保修期等,快速获得专业服务。

经常会有一些机器视觉工程师认为USB接口的工业相机会造成丢帧现象。一般而言,工业相机丢帧与工业相机所采用的传输接口是没有关系的,无论是USB,还是1394、GigE、或者是CameraLink。设计不良的驱动程序或工业相机硬件才是造成丢帧的真正原因:设计不良的工业相机之所以会发生丢帧的现象,其实就是资料通道的堵塞,无法及时处理,所以新的图像进来时,前一张可能被迫丢弃,或是新的图像被迫丢弃。要解决这问题,需要设计者针对驱动程序与工业相机硬件资料传输的每个环节进行精密的设计。想了解更多关于工业相机的内容,可通过官方网站(www.evocjm.com),可在线获取相关技术文件、工具、驱动及常见问答库,即时享受专业官方服务。您还可以通过在线沟通工具,直接发起对话申请,或提交留言,我们的客服人员将第一时间与您取得联系。
参考技术A 这个需要看客户的具体需求,每个客户所要求的是不一样的。工业相机会提供一些开发包,支持很多种语言的。我是做技术支持的,共同学习埃望采纳,有关工业相机的问题可以随时来问我。追问

谢谢大虾的回复!我现在打算用SONY IMX290 + HISI 3516AV200来做方案。我最担心的就是图像的曝光和3A算法还有畸变校正能不能符合最后图像识别的要求

参考技术B 嗯你是男是女你是开始上课看 参考技术C 是否可以接受别人意见建议?你是怎么回事!你在干嘛我也睡不着我不是滋味!你是谁呀、这种事情是因为他们没有什么事情可以做什么地方的经济呢!你的孩子都不一样吧!你在一起了么!你是谁了!你在干嘛呀!你们要吃的什么地方好玩好睡不好,不能再没有你想象不成事就是说不出口、不能再去看看吧、这么好了没有时间的推移和一些朋友都不可能成为我朋友这里是我们生活水平和好,这样可以理解一下自己是一个人

大华工业相机图像采集Python代码实现

  1 #!/usr/bin/env python
  2 # coding: utf-8
  3 ‘‘‘
  4 Created on 2017-10-25
  5 
  6 @author: 
  7 ‘‘‘
  8 
  9 from ImageConvert import *
 10 from MVSDK import *
 11 import time
 12 import numpy
 13 import gc
 14 from PIL import Image
 15 from queue import Queue
 16 # from Helper import MessageBox
 17 
 18 
 19 class Camera:
 20 
 21     def __init__(self):
 22 
 23         self.g_cameraStatusUserInfo = b"statusInfo"
 24         self.g_Image_Grabbing_Timer = 10  # unit : s
 25         self.g_isStop = 0
 26         self.connectCallBackFuncEx = connectCallBackEx(self.deviceLinkNotify)
 27         self.frameCallbackFuncEx = callbackFuncEx(self.onGetFrameEx)
 28         self.dev = None
 29         self.qimage = Queue(maxsize=0)
 30         self.userInfo = b"test"
 31         # self.messagebox = MessageBox()
 32 
 33     def onGetFrameEx(self, frame, userInfo):
 34         """ 取流回调函数Ex """
 35         if (self.g_isStop == 1):
 36             return
 37 
 38         nRet = frame.contents.valid(frame)
 39         if (nRet != 0):
 40             print("frame is invalid!")
 41             # 释放驱动图像缓存资源
 42             frame.contents.release(frame)
 43             return
 44 
 45         print("BlockId = {}".format(str(frame.contents.getBlockId(frame))))
 46 
 47         #此处客户应用程序应将图像拷贝出使用
 48         # 给转码所需的参数赋值
 49         imageParams = IMGCNV_SOpenParam()
 50         imageParams.dataSize    = frame.contents.getImageSize(frame)
 51         imageParams.height      = frame.contents.getImageHeight(frame)
 52         imageParams.width       = frame.contents.getImageWidth(frame)
 53         imageParams.paddingX    = frame.contents.getImagePaddingX(frame)
 54         imageParams.paddingY    = frame.contents.getImagePaddingY(frame)
 55         imageParams.pixelForamt = frame.contents.getImagePixelFormat(frame)
 56 
 57         # 将裸数据图像拷出
 58         imageBuff = frame.contents.getImage(frame)
 59         userBuff = c_buffer(b, imageParams.dataSize)
 60         memmove(userBuff, c_char_p(imageBuff), imageParams.dataSize)
 61 
 62         # 释放驱动图像缓存资源
 63         frame.contents.release(frame)
 64 
 65         # 如果图像格式是 Mono8 直接使用
 66         if imageParams.pixelForamt == EPixelType.gvspPixelMono8:
 67             grayByteArray = bytearray(userBuff)
 68             cvImage = numpy.array(grayByteArray).reshape(imageParams.height, imageParams.width)
 69         else:
 70             # 转码 => BGR24
 71             rgbSize = c_int()
 72             rgbBuff = c_buffer(b, imageParams.height * imageParams.width * 3)
 73 
 74             nRet = IMGCNV_ConvertToBGR24(cast(userBuff, c_void_p),  75                                          byref(imageParams),  76                                          cast(rgbBuff, c_void_p),  77                                          byref(rgbSize))
 78 
 79             colorByteArray = bytearray(rgbBuff)
 80             cvImage = numpy.array(colorByteArray).reshape(imageParams.height, imageParams.width, 3)
 81 
 82         img = Image.fromarray(cvImage)
 83         self.qimage.put(img)
 84         gc.collect()
 85 
 86     def deviceLinkNotify(self, connectArg, linkInfo):
 87         """  相机连接状态回调函数 """
 88         if ( EVType.offLine == connectArg.contents.m_event ):
 89             print("camera has off line, userInfo [%s]" %(c_char_p(linkInfo).value))
 90         elif ( EVType.onLine == connectArg.contents.m_event ):
 91             print("camera has on line, userInfo [%s]" %(c_char_p(linkInfo).value))
 92 
 93     def subscribeCameraStatus(self, camera):
 94         """ 注册相机连接状态回调 注册上下线通知"""
 95         eventSubscribe = pointer(GENICAM_EventSubscribe())
 96         eventSubscribeInfo = GENICAM_EventSubscribeInfo()
 97         eventSubscribeInfo.pCamera = pointer(camera)
 98         nRet = GENICAM_createEventSubscribe(byref(eventSubscribeInfo), byref(eventSubscribe))
 99         if ( nRet != 0):
100             print("create eventSubscribe fail!")
101             return -1
102 
103         nRet = eventSubscribe.contents.subscribeConnectArgsEx(eventSubscribe, self.connectCallBackFuncEx, self.g_cameraStatusUserInfo)
104         if ( nRet != 0 ):
105             print("subscribeConnectArgsEx fail!")
106             # 释放相关资源
107             eventSubscribe.contents.release(eventSubscribe)
108             return -1
109 
110         # 不再使用时,需释放相关资源
111         eventSubscribe.contents.release(eventSubscribe)
112         return 0
113 
114     def unsubscribeCameraStatus(self, camera):
115         """反注册相机连接状态回调 反注册上下线通知"""
116         eventSubscribe = pointer(GENICAM_EventSubscribe())
117         eventSubscribeInfo = GENICAM_EventSubscribeInfo()
118         eventSubscribeInfo.pCamera = pointer(camera)
119         nRet = GENICAM_createEventSubscribe(byref(eventSubscribeInfo), byref(eventSubscribe))
120         if ( nRet != 0):
121             print("create eventSubscribe fail!")
122             return -1
123 
124         nRet = eventSubscribe.contents.unsubscribeConnectArgsEx(eventSubscribe, self.connectCallBackFuncEx, self.g_cameraStatusUserInfo)
125         if ( nRet != 0 ):
126             print("unsubscribeConnectArgsEx fail!")
127             # 释放相关资源
128             eventSubscribe.contents.release(eventSubscribe)
129             return -1
130 
131         # 不再使用时,需释放相关资源
132         eventSubscribe.contents.release(eventSubscribe)
133         return 0
134 
135     def setSoftTriggerConf(self):
136         """设置软触发"""
137         if self.dev is None:
138             print("camera is None!")
139             return -1
140 
141         # 创建control节点
142         acqCtrlInfo = GENICAM_AcquisitionControlInfo()
143         acqCtrlInfo.pCamera = pointer(self.dev)
144         acqCtrl = pointer(GENICAM_AcquisitionControl())
145         nRet = GENICAM_createAcquisitionControl(pointer(acqCtrlInfo), byref(acqCtrl))
146         if ( nRet != 0 ):
147             print("create AcquisitionControl fail!")
148             return -1
149 
150         # 设置触发源为软触发
151         trigSourceEnumNode = acqCtrl.contents.triggerSource(acqCtrl)
152         nRet = trigSourceEnumNode.setValueBySymbol(byref(trigSourceEnumNode), b"Software")
153         if ( nRet != 0 ):
154             print("set TriggerSource value [Software] fail!")
155             # 释放相关资源
156             trigSourceEnumNode.release(byref(trigSourceEnumNode))
157             acqCtrl.contents.release(acqCtrl)
158             return -1
159 
160         # 需要释放Node资源
161         trigSourceEnumNode.release(byref(trigSourceEnumNode))
162 
163         # 设置触发方式
164         trigSelectorEnumNode = acqCtrl.contents.triggerSelector(acqCtrl)
165         nRet = trigSelectorEnumNode.setValueBySymbol(byref(trigSelectorEnumNode), b"FrameStart")
166         if ( nRet != 0 ):
167             print("set TriggerSelector value [FrameStart] fail!")
168             # 释放相关资源
169             trigSelectorEnumNode.release(byref(trigSelectorEnumNode))
170             acqCtrl.contents.release(acqCtrl)
171             return -1
172 
173         # 需要释放Node资源
174         trigSelectorEnumNode.release(byref(trigSelectorEnumNode))
175 
176         # 打开触发模式
177         trigModeEnumNode = acqCtrl.contents.triggerMode(acqCtrl)
178         nRet = trigModeEnumNode.setValueBySymbol(byref(trigModeEnumNode), b"On")
179         if ( nRet != 0 ):
180             print("set TriggerMode value [On] fail!")
181             # 释放相关资源
182             trigModeEnumNode.release(byref(trigModeEnumNode))
183             acqCtrl.contents.release(acqCtrl)
184             return -1
185 
186         # 需要释放相关资源
187         trigModeEnumNode.release(byref(trigModeEnumNode))
188         acqCtrl.contents.release(acqCtrl)
189         return 0
190 
191     def grabContinue(self):
192         """自由拉流"""
193         if self.dev is None:
194             print("camera is None!")
195             return -1
196 
197         # 创建流对象
198         streamSourceInfo = GENICAM_StreamSourceInfo()
199         streamSourceInfo.channelId = 0
200         streamSourceInfo.pCamera = pointer(self.dev)
201 
202         streamSource = pointer(GENICAM_StreamSource())
203         nRet = GENICAM_createStreamSource(pointer(streamSourceInfo), byref(streamSource))
204         if (nRet != 0):
205             print("create StreamSource fail!")
206             return -1
207 
208         # 通用属性设置:设置触发模式为off --根据属性类型,直接构造属性节点。如触发模式是 enumNode,构造enumNode节点
209         # 自由拉流:TriggerMode 需为 off
210         trigModeEnumNode = pointer(GENICAM_EnumNode())
211         trigModeEnumNodeInfo = GENICAM_EnumNodeInfo()
212         trigModeEnumNodeInfo.pCamera = pointer(self.dev)
213         trigModeEnumNodeInfo.attrName = b"TriggerMode"
214         nRet = GENICAM_createEnumNode(byref(trigModeEnumNodeInfo), byref(trigModeEnumNode))
215         if ( nRet != 0 ):
216             print("create TriggerMode Node fail!")
217             # 释放相关资源
218             streamSource.contents.release(streamSource)
219             return -1
220 
221         nRet = trigModeEnumNode.contents.setValueBySymbol(trigModeEnumNode, b"Off")
222         if ( nRet != 0 ):
223             print("set TriggerMode value [Off] fail!")
224             # 释放相关资源
225             trigModeEnumNode.contents.release(trigModeEnumNode)
226             streamSource.contents.release(streamSource)
227             return -1
228 
229         # 需要释放Node资源
230         trigModeEnumNode.contents.release(trigModeEnumNode)
231 
232     def setLineTriggerConf(self):
233         """设置外触发"""
234         if self.dev is None:
235             print("camera is None!")
236             return -1
237 
238         # 创建control节点
239         acqCtrlInfo = GENICAM_AcquisitionControlInfo()
240         acqCtrlInfo.pCamera = pointer(self.dev)
241         acqCtrl = pointer(GENICAM_AcquisitionControl())
242         nRet = GENICAM_createAcquisitionControl(pointer(acqCtrlInfo), byref(acqCtrl))
243         if ( nRet != 0 ):
244             print("create AcquisitionControl fail!")
245             return -1
246 
247         # 设置触发源为软触发
248         trigSourceEnumNode = acqCtrl.contents.triggerSource(acqCtrl)
249         nRet = trigSourceEnumNode.setValueBySymbol(byref(trigSourceEnumNode), b"Line1")
250         if ( nRet != 0 ):
251             print("set TriggerSource value [Line1] fail!")
252             # 释放相关资源
253             trigSourceEnumNode.release(byref(trigSourceEnumNode))
254             acqCtrl.contents.release(acqCtrl)
255             return -1
256 
257         # 需要释放Node资源
258         trigSourceEnumNode.release(byref(trigSourceEnumNode))
259 
260         # 设置触发方式
261         trigSelectorEnumNode = acqCtrl.contents.triggerSelector(acqCtrl)
262         nRet = trigSelectorEnumNode.setValueBySymbol(byref(trigSelectorEnumNode), b"FrameStart")
263         if ( nRet != 0 ):
264             print("set TriggerSelector value [FrameStart] fail!")
265             # 释放相关资源
266             trigSelectorEnumNode.release(byref(trigSelectorEnumNode))
267             acqCtrl.contents.release(acqCtrl)
268             return -1
269 
270         # 需要释放Node资源
271         trigSelectorEnumNode.release(byref(trigSelectorEnumNode))
272 
273         # 打开触发模式
274         trigModeEnumNode = acqCtrl.contents.triggerMode(acqCtrl)
275         nRet = trigModeEnumNode.setValueBySymbol(byref(trigModeEnumNode), b"On")
276         if ( nRet != 0 ):
277             print("set TriggerMode value [On] fail!")
278             # 释放相关资源
279             trigModeEnumNode.release(byref(trigModeEnumNode))
280             acqCtrl.contents.release(acqCtrl)
281             return -1
282 
283         # 需要释放Node资源
284         trigModeEnumNode.release(byref(trigModeEnumNode))
285 
286         # 设置触发沿
287         trigActivationEnumNode = acqCtrl.contents.triggerActivation(acqCtrl)
288         nRet = trigActivationEnumNode.setValueBySymbol(byref(trigActivationEnumNode), b"RisingEdge")
289         if ( nRet != 0 ):
290             print("set TriggerActivation value [RisingEdge] fail!")
291             # 释放相关资源
292             trigActivationEnumNode.release(byref(trigActivationEnumNode))
293             acqCtrl.contents.release(acqCtrl)
294             return -1
295 
296         # 需要释放Node资源
297         trigActivationEnumNode.release(byref(trigActivationEnumNode))
298         acqCtrl.contents.release(acqCtrl)
299         return 0
300 
301     def openCamera(self):
302         """打开相机"""
303 
304         # 发现相机
305         cameraCnt, cameraList = self.enumCameras()
306         if cameraCnt is None:
307             return -1
308 
309         # 显示相机信息
310         for index in range(0, cameraCnt):
311             camera = cameraList[index]
312             print("
Camera Id = " + str(index))
313             print("Key           = " + str(camera.getKey(camera)))
314             print("vendor name   = " + str(camera.getVendorName(camera)))
315             print("Model  name   = " + str(camera.getModelName(camera)))
316             print("Serial number = " + str(camera.getSerialNumber(camera)))
317 
318         camera = cameraList[0]
319         self.dev = camera
320 
321         # 连接相机
322         nRet = camera.connect(camera, c_int(GENICAM_ECameraAccessPermission.accessPermissionControl))
323         if ( nRet != 0 ):
324             print("camera connect fail!")
325             # self.messagebox.Error("camera connect fail!")
326             return -1
327         else:
328             print("camera connect success.")
329 
330         # 注册相机连接状态回调
331         nRet = self.subscribeCameraStatus(camera)
332         if ( nRet != 0 ):
333             print("subscribeCameraStatus fail!")
334             return -1
335 
336         # 创建流对象
337         streamSourceInfo = GENICAM_StreamSourceInfo()
338         streamSourceInfo.channelId = 0
339         streamSourceInfo.pCamera = pointer(camera)
340 
341         streamSource = pointer(GENICAM_StreamSource())
342         nRet = GENICAM_createStreamSource(
343             pointer(streamSourceInfo),
344             byref(streamSource))
345         if (nRet != 0):
346             print("create StreamSource fail!")
347             return -1
348 
349         # 注册拉流回调函数
350         nRet = streamSource.contents.attachGrabbingEx(streamSource, self.frameCallbackFuncEx, self.userInfo)
351         if (nRet != 0):
352             print("attachGrabbingEx fail!")
353             # 释放相关资源
354             streamSource.contents.release(streamSource)
355             return -1
356 
357         # 开始拉流
358         nRet = streamSource.contents.startGrabbing(streamSource, c_ulonglong(0), 359                                                    c_int(GENICAM_EGrabStrategy.grabStrartegySequential))
360         if (nRet != 0):
361             print("startGrabbing fail!")
362             # 释放相关资源
363             streamSource.contents.release(streamSource)
364             return -1
365 
366         return 0
367 
368     def closeCamera(self):
369         """关闭相机"""
370         if self.dev is None:
371             print("camera is None!")
372             return -1
373 
374         # 反注册相机连接状态回调
375         nRet = self.unsubscribeCameraStatus(self.dev)
376         if ( nRet != 0 ):
377             print("unsubscribeCameraStatus fail!")
378             return -1
379 
380         # 断开相机
381         nRet = self.dev.disConnect(byref(self.dev))
382         if ( nRet != 0 ):
383             print("disConnect camera fail!")
384             return -1
385         print("camera is closed")
386         return 0
387 
388     def setExposureTime(self, dVal):
389         """设置曝光时间"""
390         if self.dev is None:
391             print("camera is None!")
392             return -1
393 
394         # 通用属性设置:设置曝光 --根据属性类型,直接构造属性节点。如曝光是 double类型,构造doubleNode节点
395         exposureTimeNode = pointer(GENICAM_DoubleNode())
396         exposureTimeNodeInfo = GENICAM_DoubleNodeInfo()
397         exposureTimeNodeInfo.pCamera = pointer(self.dev)
398         exposureTimeNodeInfo.attrName = b"ExposureTime"
399         nRet = GENICAM_createDoubleNode(byref(exposureTimeNodeInfo), byref(exposureTimeNode))
400         if ( nRet != 0 ):
401             print("create ExposureTime Node fail!")
402             return -1
403 
404         # 设置曝光时间
405         nRet = exposureTimeNode.contents.setValue(exposureTimeNode, c_double(dVal))
406         if ( nRet != 0 ):
407             print("set ExposureTime value [%f]us fail!"  % (dVal))
408             # 释放相关资源
409             exposureTimeNode.contents.release(exposureTimeNode)
410             return -1
411         else:
412             print("set ExposureTime value [%f]us success." % (dVal))
413 
414         # 释放节点资源
415         exposureTimeNode.contents.release(exposureTimeNode)
416         return 0
417 
418     def enumCameras(self):
419         """枚举相机 网络中搜索可连接的设备"""
420         # 获取系统单例
421         system = pointer(GENICAM_System())
422         nRet = GENICAM_getSystemInstance(byref(system))
423         if ( nRet != 0 ):
424             print("getSystemInstance fail!")
425             return None, None
426 
427         # 发现相机
428         cameraList = pointer(GENICAM_Camera())
429         cameraCnt = c_uint()
430         nRet = system.contents.discovery(system, byref(cameraList), byref(cameraCnt), c_int(GENICAM_EProtocolType.typeAll));
431         if ( nRet != 0 ):
432             print("discovery fail!")
433             return None, None
434         elif cameraCnt.value < 1:
435             print("discovery no camera!")
436             # self.messagebox.Info("discovery no camera!")
437             return None, None
438         else:
439             print("cameraCnt: " + str(cameraCnt.value))
440             return cameraCnt.value, cameraList
441 
442     def grabOne(self):
443         """单次触发"""
444         if self.dev is None:
445             print("camera is None!")
446             return -1
447 
448         # 创建流对象
449         streamSourceInfo = GENICAM_StreamSourceInfo()
450         streamSourceInfo.channelId = 0
451         streamSourceInfo.pCamera = pointer(self.dev)
452 
453         streamSource = pointer(GENICAM_StreamSource())
454         nRet = GENICAM_createStreamSource(pointer(streamSourceInfo), byref(streamSource))
455         if ( nRet != 0 ):
456             print("create StreamSource fail!")
457             return -1
458 
459         # 创建control节点
460         acqCtrlInfo = GENICAM_AcquisitionControlInfo()
461         acqCtrlInfo.pCamera = pointer(self.dev)
462         acqCtrl = pointer(GENICAM_AcquisitionControl())
463         nRet = GENICAM_createAcquisitionControl(pointer(acqCtrlInfo), byref(acqCtrl))
464         if ( nRet != 0 ):
465             print("create AcquisitionControl fail!")
466             # 释放相关资源
467             streamSource.contents.release(streamSource)
468             return -1
469 
470         # 打开触发模式
471         trigModeEnumNode = acqCtrl.contents.triggerMode(acqCtrl)
472         nRet = trigModeEnumNode.setValueBySymbol(byref(trigModeEnumNode), b"On")
473         if (nRet != 0):
474             print("set TriggerMode value [On] fail!")
475             # 释放相关资源
476             trigModeEnumNode.release(byref(trigModeEnumNode))
477             acqCtrl.contents.release(acqCtrl)
478             return -1
479 
480         # 需要释放相关资源
481         trigModeEnumNode.release(byref(trigModeEnumNode))
482 
483         # 执行一次软触发
484         trigSoftwareCmdNode = acqCtrl.contents.triggerSoftware(acqCtrl)
485         nRet = trigSoftwareCmdNode.execute(byref(trigSoftwareCmdNode))
486         if( nRet != 0 ):
487             print("Execute triggerSoftware fail!")
488             # 释放相关资源
489             trigSoftwareCmdNode.release(byref(trigSoftwareCmdNode))
490             acqCtrl.contents.release(acqCtrl)
491             streamSource.contents.release(streamSource)
492             return -1
493 
494         # 释放相关资源
495         trigSoftwareCmdNode.release(byref(trigSoftwareCmdNode))
496         acqCtrl.contents.release(acqCtrl)
497         streamSource.contents.release(streamSource)
498         return 0
499 
500     def setROI(self, OffsetX, OffsetY, nWidth, nHeight):
501         """设置感兴趣区域  --- 感兴趣区域的宽高 和 xy方向的偏移量  入参值应符合对应相机的递增规则"""
502         #获取原始的宽度
503         widthMaxNode = pointer(GENICAM_IntNode())
504         widthMaxNodeInfo = GENICAM_IntNodeInfo()
505         widthMaxNodeInfo.pCamera = pointer(self.dev)
506         widthMaxNodeInfo.attrName = b"WidthMax"
507         nRet = GENICAM_createIntNode(byref(widthMaxNodeInfo), byref(widthMaxNode))
508         if ( nRet != 0 ):
509             print("create WidthMax Node fail!")
510             return -1
511 
512         oriWidth = c_longlong()
513         nRet = widthMaxNode.contents.getValue(widthMaxNode, byref(oriWidth))
514         if ( nRet != 0 ):
515             print("widthMaxNode getValue fail!")
516             # 释放相关资源
517             widthMaxNode.contents.release(widthMaxNode)
518             return -1
519 
520         # 释放相关资源
521         widthMaxNode.contents.release(widthMaxNode)
522 
523         # 获取原始的高度
524         heightMaxNode = pointer(GENICAM_IntNode())
525         heightMaxNodeInfo = GENICAM_IntNodeInfo()
526         heightMaxNodeInfo.pCamera = pointer(self.dev)
527         heightMaxNodeInfo.attrName = b"HeightMax"
528         nRet = GENICAM_createIntNode(byref(heightMaxNodeInfo), byref(heightMaxNode))
529         if ( nRet != 0 ):
530             print("create HeightMax Node fail!")
531             return -1
532 
533         oriHeight = c_longlong()
534         nRet = heightMaxNode.contents.getValue(heightMaxNode, byref(oriHeight))
535         if ( nRet != 0 ):
536             print("heightMaxNode getValue fail!")
537             # 释放相关资源
538             heightMaxNode.contents.release(heightMaxNode)
539             return -1
540 
541         # 释放相关资源
542         heightMaxNode.contents.release(heightMaxNode)
543 
544         # 检验参数
545         if ( ( oriWidth.value < (OffsetX + nWidth)) or ( oriHeight.value < (OffsetY + nHeight)) ):
546             print("please check input param!")
547             return -1
548 
549         # 设置宽度
550         widthNode = pointer(GENICAM_IntNode())
551         widthNodeInfo = GENICAM_IntNodeInfo()
552         widthNodeInfo.pCamera = pointer(self.dev)
553         widthNodeInfo.attrName = b"Width"
554         nRet = GENICAM_createIntNode(byref(widthNodeInfo), byref(widthNode))
555         if ( nRet != 0 ):
556             print("create Width Node fail!")
557             return -1
558 
559         nRet = widthNode.contents.setValue(widthNode, c_longlong(nWidth))
560         if ( nRet != 0 ):
561             print("widthNode setValue [%d] fail!" % (nWidth))
562             # 释放相关资源
563             widthNode.contents.release(widthNode)
564             return -1
565 
566         # 释放相关资源
567         widthNode.contents.release(widthNode)
568 
569         # 设置高度
570         heightNode = pointer(GENICAM_IntNode())
571         heightNodeInfo = GENICAM_IntNodeInfo()
572         heightNodeInfo.pCamera = pointer(self.dev)
573         heightNodeInfo.attrName = b"Height"
574         nRet = GENICAM_createIntNode(byref(heightNodeInfo), byref(heightNode))
575         if ( nRet != 0 ):
576             print("create Height Node fail!")
577             return -1
578 
579         nRet = heightNode.contents.setValue(heightNode, c_longlong(nHeight))
580         if ( nRet != 0 ):
581             print("heightNode setValue [%d] fail!" % (nHeight))
582             # 释放相关资源
583             heightNode.contents.release(heightNode)
584             return -1
585 
586         # 释放相关资源
587         heightNode.contents.release(heightNode)
588 
589         # 设置OffsetX
590         OffsetXNode = pointer(GENICAM_IntNode())
591         OffsetXNodeInfo = GENICAM_IntNodeInfo()
592         OffsetXNodeInfo.pCamera = pointer(self.dev)
593         OffsetXNodeInfo.attrName = b"OffsetX"
594         nRet = GENICAM_createIntNode(byref(OffsetXNodeInfo), byref(OffsetXNode))
595         if ( nRet != 0 ):
596             print("create OffsetX Node fail!")
597             return -1
598 
599         nRet = OffsetXNode.contents.setValue(OffsetXNode, c_longlong(OffsetX))
600         if ( nRet != 0 ):
601             print("OffsetX setValue [%d] fail!" % (OffsetX))
602             # 释放相关资源
603             OffsetXNode.contents.release(OffsetXNode)
604             return -1
605 
606         # 释放相关资源
607         OffsetXNode.contents.release(OffsetXNode)
608 
609         # 设置OffsetY
610         OffsetYNode = pointer(GENICAM_IntNode())
611         OffsetYNodeInfo = GENICAM_IntNodeInfo()
612         OffsetYNodeInfo.pCamera = pointer(self.dev)
613         OffsetYNodeInfo.attrName = b"OffsetY"
614         nRet = GENICAM_createIntNode(byref(OffsetYNodeInfo), byref(OffsetYNode))
615         if ( nRet != 0 ):
616             print("create OffsetY Node fail!")
617             return -1
618 
619         nRet = OffsetYNode.contents.setValue(OffsetYNode, c_longlong(OffsetY))
620         if ( nRet != 0 ):
621             print("OffsetY setValue [%d] fail!" % (OffsetY))
622             # 释放相关资源
623             OffsetYNode.contents.release(OffsetYNode)
624             return -1
625 
626         # 释放相关资源
627         OffsetYNode.contents.release(OffsetYNode)
628         return 0
629 
630     def demo(self):
631         # 发现相机
632         cameraCnt, cameraList = self.enumCameras()
633         if cameraCnt is None:
634             return -1
635 
636         # 显示相机信息
637         for index in range(0, cameraCnt):
638             camera = cameraList[index]
639             print("
Camera Id = " + str(index))
640             print("Key           = " + str(camera.getKey(camera)))
641             print("vendor name   = " + str(camera.getVendorName(camera)))
642             print("Model  name   = " + str(camera.getModelName(camera)))
643             print("Serial number = " + str(camera.getSerialNumber(camera)))
644 
645         # 选择第一个相机
646         camera = cameraList[0]
647         self.dev = camera
648 
649         # 打开相机
650         nRet = self.openCamera(self.dev)
651         if ( nRet != 0 ):
652             print("openCamera fail.")
653             self.messagebox.Error("openCamera fail !")
654             return -1
655 
656         self.setSoftTriggerConf()
657 
658         # 创建流对象
659         streamSourceInfo = GENICAM_StreamSourceInfo()
660         streamSourceInfo.channelId = 0
661         streamSourceInfo.pCamera = pointer(camera)
662 
663         streamSource = pointer(GENICAM_StreamSource())
664         nRet = GENICAM_createStreamSource(pointer(streamSourceInfo), byref(streamSource))
665         if ( nRet != 0 ):
666             print("create StreamSource fail!")
667             self.messagebox.Error("create StreamSource fail!")
668             return -1
669 
670         # # 通用属性设置:设置触发模式为off --根据属性类型,直接构造属性节点。如触发模式是 enumNode,构造enumNode节点
671         # # 自由拉流:TriggerMode 需为 off
672         # trigModeEnumNode = pointer(GENICAM_EnumNode())
673         # trigModeEnumNodeInfo = GENICAM_EnumNodeInfo()
674         # trigModeEnumNodeInfo.pCamera = pointer(camera)
675         # trigModeEnumNodeInfo.attrName = b"TriggerMode"
676         # nRet = GENICAM_createEnumNode(byref(trigModeEnumNodeInfo), byref(trigModeEnumNode))
677         # if ( nRet != 0 ):
678         #     print("create TriggerMode Node fail!")
679         #     # 释放相关资源
680         #     streamSource.contents.release(streamSource)
681         #     return -1
682         #
683         # nRet = trigModeEnumNode.contents.setValueBySymbol(trigModeEnumNode, b"On")
684         # if ( nRet != 0 ):
685         #     print("set TriggerMode value [Off] fail!")
686         #     # 释放相关资源
687         #     trigModeEnumNode.contents.release(trigModeEnumNode)
688         #     streamSource.contents.release(streamSource)
689         #     return -1
690         #
691         # # 需要释放Node资源
692         # trigModeEnumNode.contents.release(trigModeEnumNode)
693 
694         # 注册拉流回调函数
695         nRet = streamSource.contents.attachGrabbingEx(streamSource, self.frameCallbackFuncEx, self.userInfo)
696         if ( nRet != 0 ):
697             print("attachGrabbingEx fail!")
698             self.messagebox.Error("attachGrabbingEx fail!")
699             # 释放相关资源
700             streamSource.contents.release(streamSource)
701             return -1
702 
703         # 开始拉流
704         nRet = streamSource.contents.startGrabbing(streamSource, c_ulonglong(0), 705                                                    c_int(GENICAM_EGrabStrategy.grabStrartegySequential))
706         if( nRet != 0):
707             print("startGrabbing fail!")
708             self.messagebox.Error("startGrabbing fail!")
709             # 释放相关资源
710             streamSource.contents.release(streamSource)
711             return -1
712 
713         # 循环触发
714         # while True:
715         #     self.grabOne(camera)
716         #     time.sleep(1)
717         #
718         # # 反注册回调函数
719         # nRet = streamSource.contents.detachGrabbingEx(streamSource, self.frameCallbackFuncEx, userInfo)
720         # if ( nRet != 0 ):
721         #     print("detachGrabbingEx fail!")
722         #     # 释放相关资源
723         #     streamSource.contents.release(streamSource)
724         #     return -1
725         #
726         # # 停止拉流
727         # nRet = streamSource.contents.stopGrabbing(streamSource)
728         # if ( nRet != 0 ):
729         #     print("stopGrabbing fail!")
730         #     # 释放相关资源
731         #     streamSource.contents.release(streamSource)
732         #     return -1
733         #
734         # # 关闭相机
735         # nRet = self.closeCamera(camera)
736         # if ( nRet != 0 ):
737         #     print("closeCamera fail")
738         #     # 释放相关资源
739         #     streamSource.contents.release(streamSource)
740         #     return -1
741         #
742         # # 释放相关资源
743         # streamSource.contents.release(streamSource)
744         # return 0
745 
746 
747 if __name__ == "__main__":
748 
749     cam = Camera()
750     nRet = cam.demo()
751     if nRet != 0:
752         print("Some Error happend")
753     print("--------- Demo end ---------")
754     # 3s exit
755     time.sleep(3)

 

以上是关于工业相机设计图像处理和方案实现的主要内容,如果未能解决你的问题,请参考以下文章

一种RK3399+MIPI+FPGA的高速工业相机的设计方案

Baumer工业相机堡盟相机如何使用BGAPI SDK和Opencv联动实现图像转换成视频(C#)

基于cyclone V的USB3.0/GIGE工业相机模块设计方案

视觉软件halcon可以支持那些工业相机?

一种RK3399+MIPI+FPGA的高速工业相机的设计方案

大华工业相机图像采集Python代码实现