|
一、序:dahua_url="rtsp://用户名:密码@192.168.1.108/cam/realmonitor?channel=1&subtype=0?tcp"cap=cv2.VideoCapture(dahua_url)12想用大华网络摄像头做目标检测,但是使用上述CV方法获取大华网络摄像头无法达到实时检测效果(延迟2秒左右),故想找其他办法解决这个问题。困扰多日,想要实时检测,必须使用大华SDK进行二次开发,使用搜索大法,发现使用pyhon获取大华摄像头SDK的方法寥寥无几,今灵光乍现,解决该问题,故写此文,告诉给位道友。二、下载大华SDK:大华SDK下载点击此处1.选择SDK开发,选择设备SDK2.选择第2页,找到pythonwin64版本,点击下载3.解压文件,点进入,找到dist点击去4.在NetSDK封装库.whl文件存放目录下打开命令终端,运行以下命令安装插件。(放入项目虚拟环境)pipinstallNetSDK-2.0.0.1-py3-none-win_amd64.whl至此,安装完毕!三、大华SDK二次开发:1.在刚刚解压的SDK文件中,点击Demo文件,选择RealPlayDemo项目,使用Pycharm打开该项目2.SDK手册在Doc文件中,大家可以看看RealPlayDemo项目的一些官方讲解,我这里只讲重点,具体可以看看官方手册(关键是它也不具体)。(1).项目环境:主要是PyQt5和SDK环境,然后就是目标检测的环境(我用的YOLOv8),都下好测试一下。(2).配置好项目环境后,先检测项目能不能直接运行,点击run,能成功显示UI,证明环境配置好了(3).修改IP,端口,用户名,密码(这部分可以在代码中改,后续就不需要填了)。端口我是用的是代码默认的37777,可以运行。然后点击登录、再点击预览,出现此画面后,说明摄像头配置成功了,至此马上开始开发SDK。3.二次开发SDK先说一下运行流程:SDK进行实时监控是使用的回调函数(拉流回调),然后绑定UI窗口句柄id,摄像头每收到1帧图画,回调函数就会运行一次,画面就会显示到UI窗口上,我们现在想要做的就是,如何截取摄像头接受的1帧图画,将其转换为RGB格式,然后进行目标检测,最后矩形框显示到播放窗口中。但是现在出现一个问题,传入到窗口句柄id的数据是码流数据,没有解码,我们不太好直接使用该数据,其中的数据还是以地址的方式传送,python不太好操作地址(用ctypes标准库是可以的),我们得找一下SDK现成解码方法。刚好在拉流回调函数得下面就找到了解码回调函数,该函数也是1帧图像被自动调用1次。我们就从此处切入,从文档和注释可以知道该解码函数得到的是一个YUV420格式数据,那么我们就是将YUV420转化为RGB格式即可。上面图片中的data就是YUV420数据,我们先打印看一下data=cast(pBuf,POINTER(c_ubyte*nSize)).contentsprint("data:",data)结果:data:123data是c_ubyte格式数组的地址,道友无须担心,然我们一起揭开该妖孽的真面目。先将data数据转化为我们熟悉的array数组,打印看一下#使用numpy.frombuffer将c_ubyte_Array对象转换为numpy数组numpy_array=np.frombuffer(data,dtype=np.uint8)print(numpy_array)print(len(numpy_array))结果:[195195195...123123123]31104001234567YUV格式图像的高是RGB的1.5倍(这里需要补YUV图像格式的基础,此处不展开讲,你需要知道要这么做),我们先把numpy_array转化为2维数组(2维数组是YUV标准格式,后续方便调用cv2函数),info是回调函数中给的一个变量,直接用就行,可以获取图像高宽,代码如下:yuv=numpy_array.reshape(int(info.nHeight*1.5),info.nWidth)1后面调用cv2转换函数,大功告成!rgb=cv2.cvtColor(yuv,cv2.COLOR_YUV2BGR_I420)print(rgb.shape)cv2.imshow('RGBImage',rgb)cv2.waitKey(1)结果:(1080,1920,3)123456最后我们运行函数看一下效果:两个画面都成功显示,我们拿到了RGB图片,后续就可以方便的进行目标检测操作,后续内容我就不细讲了,SDK使用告一段落。四、尾声:完整代码(只需要修改Demo中的解码回调函数即可):#PLAYSDK解码回调函数功能defDecodingCallBack(self,nPort,pBuf,nSize,pFrameInfo,pUserData,nReserved2):#heregetYUVdata,pBufisYUVdataIYUV/YUV420,sizeisnSize,pFrameInfoisframeinfowithheight,width.#对于planar的YUV格式,先连续存储所有相速度的Y,紧接着存储所有像素点的U,随后是V#对于packed的YUV格式,每个像素点的Y,U,V是连续交叉存储的#uv的排列格式分为p、sp,错误会导致颜色不对data=cast(pBuf,POINTER(c_ubyte*nSize)).contents#print(data)info=pFrameInfo.contents#info.nType==3isYUVdata,othersardaudiodata.#youcanparseYUV420datatoRGBifinfo.nType==3:##使用numpy.frombuffer将c_ubyte_Array对象转换为numpy数组numpy_array=np.frombuffer(data,dtype=np.uint8)yuv=numpy_array.reshape(int(info.nHeight*1.5),info.nWidth)rgb=cv2.cvtColor(yuv,cv2.COLOR_YUV2BGR_I420)##如果需要显示图像,可以使用以下代码cv2.imshow('RGBImage',rgb)cv2.waitKey(1)12345678910111213141516171819202122'运行运行转载请标明出处,文章有问题请留言,我看到会修改,中途出现问题也可以留言,我有时间就会解答。如果比较着急,可以+我微信,咨询费1杯奶茶的价格,备注:大华SDK。
|
|