GrabImage.py
GrabImage.py抓取了一帧图片,是数据流,我们要解析成图片输入到YOLO里,图片是通过MvCameraControl_class类里的MV_CC_GetOneFrameTimeout函数抓取的,MV_CC_GetOneFrameTimeout是通过动态库MvCameraControl.dll封装的,不过我们只需要解流就好,看 ConvertPixelType.py里的解流过程,解流是通过MvCameraControl_class类里的MV_CC_ConvertPixelType函数实现的,同样是在MvCameraControl.dll,我们需要反编译看下dll文件中函数的实现,反编译失败,都是乱码,海康那边说也不能给源码
stDeviceList = MV_FRAME_OUT_INFO_EX()
memset(byref(stDeviceList), 0, sizeof(stDeviceList))
data_buf = (c_ubyte * nPayloadSize)()
ret = cam.MV_CC_GetOneFrameTimeout(byref(data_buf), nPayloadSize, stDeviceList, 1000)
#MvCameraControl_class类的函数实现,没有什么内容,基本上都是在dll里,完全封装好了
def MV_CC_GetOneFrameTimeout(self, pData, nDataSize, stFrameInfo, nMsec=1000):
MvCamCtrldll.MV_CC_GetOneFrameTimeout.argtype = (c_void_p, c_void_p, c_uint, c_void_p, c_uint)
MvCamCtrldll.MV_CC_GetOneFrameTimeout.restype = c_uint
# C原型:int MV_CC_GetOneFrameTimeout(void* handle, unsigned char * pData , unsigned int nDataSize, MV_FRAME_OUT_INFO_EX* pFrameInfo, unsigned int nMsec)
return MvCamCtrldll.MV_CC_GetOneFrameTimeout(self.handle, pData, nDataSize, byref(stFrameInfo), nMsec)
后来和海康的人沟通询问他们这个流的解码方式,他们说可以自己设置图片格式,然后我就开启了MVS软件把图片设为RGB,解码较为方便。后面发现其实我们只要对返回的pdata指向的data_buf的c_ubyte字节数组进行操作,可以不关心具体的实现过程,因为现在知道了码流的格式。有关c_ubyte的资料蛮少的,我开始是一个个读取字节,每次耗时0.27秒,性能太差,后面诸多尝试,最后发现直接用deepcopy拷贝到一个list再转化为numpy的array,进行reshape为三位矩阵再转化为图片,即可进行检测,帧率由2帧/s提高到20帧/s,还有有一个关键点是把数组转化为np.uint8的类型
#硬着头皮读,0.27s
a = []
for i in range(nPayloadSize):
a.append(data_buf[i])
a = np.array(a)
a = a.reshape(720,1280,3)
a = a.astype(np.uint8)
Img = Image.fromarray(a,"RGB")
#利用deepcopy复制,但是存在小bug,有时候启动设备失败
Piexl = []
Piexl = copy.deepcopy(data_buf)
Piexl = np.array(Piexl)
Piexl = Piexl.reshape(720,1280,3)
Piexl_RGB = Piexl.astype(np.uint8)
Img = Image.fromarray(Piexl_RGB,"RGB")
image = yolo.detect_image(Img)