HikVision SDK: C++ 至 Python

问题点

把 SDK 从 C++ 搬到 Python 需要解决两个主要问题,一个是从 IP 摄像头中获取图像(码流),另一个是对云台进行控制(角度、倍率等)。为了解决以上两个问题,一共尝试了三个方案,实现过程从简单到复杂,在此总结一下其中各自的利弊。1. RTSP 协议获取图像在选择 HikVision 之前也关注了这方面的支持。RTSP 是流媒体协议,可以很方便地通过 URL 获取码流。它的协议如下1:

// 说明:
// username:用户名,例如admin
// passwd:密码,例如12345
// ip:设备的ip地址,例如192.0.0.64
// port:端口号默认554,若为默认可以不写
// codec:有h264、MPEG-4、mpeg4这几种
// channel:通道号,起始为1
// subtype:码流类型,主码流为main,子码流为sub
rtsp://[username]:[passwd]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream

在 OpenCV 中,很简单就能读取 IP 摄像头。

import cv2
cam = cv2.VideoCapture("rtsp://[username]:[passwd]@[ip]:554/h264/ch1/sub/av_stream")
while True:
    ret, frame = cam.read()
    cv2.imshow("test", frame)
    key = cv2.waitKey(100) & 0xff
    if key == 27: # ESC
        break
cam.release()
cv2.destroyAllWindows()

然而这么做存在一个很大的缺陷,即通过流媒体协议获得的码流没有办法满足实时要求,返回图像存在 3-5 秒延时,在实际项目中并不可行。另一方面,仅仅取得码流对于实际项目也并不足够,还需要想方设法对云台进行控制。于是,找到了下一种解决方案。

解决方案

swig 封装库

既然已经到走投无路的阶段,只能考虑利用 C++ 实现功能,再自行封装 Python 库了。这种实现方案确实很费劲,操作十分繁琐,但毕竟 SDK 有给出 C++ 的实现,算是最靠谱的方案,所以万不得已的我尝试了这种解决方案。

1.安装 Swig。

Swig 用于封装库,在 Windows 系统下,对应的「swigwin」版本,解压后将目录添加到系统「环境变量」。
HikVision SDK: C++ 至 Python_第1张图片

2.下载 OpenCV-swig 接口文件。

该文件用于预编译 OpenCV 相关函数,是一系列.i后缀的文件。点击下载并解压

3.转移文件

将上述接口文件中 lib 文件夹的所有文件拷贝到项目所在目录,并与三个源文件放置在一起。(注:源文件包括HKIPcamera.cpp、HKIPcamera.h和HKIPcamera.i,请回顾出处原文。代码基本与原文一致,需要新增功能也在HKIPcamera.cpp中实现,所以不在此展示。)

4.生成cxx文件

通过命令行使用 swig 生成HKIPcamera_wrap.cxx文件。cd到HKIPcamera.i源文件文件夹下,并修改 OpenCV 路径。如:

cd OpenCV Project\HKIPCamera\HKIPCamera
swig -I"D:\Open CV\opencv\build\include" -python -c++ HKIPCamera.i

5.修改文件

修改plaympeg4.h文件。这一问题在原文章中有所提及:在extern “C” __declspec(dllexport)的"C"和__之间需要增加空格,否则会导致编译报错。

6.下载boost

下载 boost 库。boost 库提供了一系列扩展的 C++ 方法,文件稍大。点击下载(Windows 平台)

7.配置vs工程

编译动态链接库。新建Visual Studio 动态链接库工程并配置如下:
配置包含目录:
HikVision SDK: C++ 至 Python_第2张图片
配置库目录:
HikVision SDK: C++ 至 Python_第3张图片
配置依赖项:
HikVision SDK: C++ 至 Python_第4张图片
不使用预编译头:
HikVision SDK: C++ 至 Python_第5张图片
文件配置
HikVision SDK: C++ 至 Python_第6张图片

8.编译

在「属性管理器」添加 Python 头文件目录和库目录。再将HKIPcamera.h文件添加到头文件、HKIPcamera_wrap.cxx和HKIPcamera.cpp添加到源文件 、HKIPcamera.i 添加到工程目录下,进行编译。将生成的.dll文件改名为_HKIPcamera.pyd,并与HKIPcamera.py放置在同一文件目录下,即可在 Python 中引用。

9.配置环境变量

HikVision SDK: C++ 至 Python_第7张图片

注意:

由于 Python 只能接收Mat类型,原文3中解码回调DecCBFun部分可以改写为:

void CALLBACK DecCBFun(long nPort, char* pBuf, long nSize, FRAME_INFO* pFrameInfo, long nReserved1, long nReserved2)
{
	long lFrameType = pFrameInfo->nType;
	Mat g_BGRImage;
	if (lFrameType == T_YV12)
	{
		if (g_BGRImage.empty())
		{
			g_BGRImage.create(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3);
		}
		Mat YUVImage(pFrameInfo->nHeight + pFrameInfo->nHeight / 2, 				pFrameInfo->nWidth, 	CV_8UC1, (unsigned char*)pBuf);
		cvtColor(YUVImage, g_BGRImage, COLOR_YUV2BGR_YV12);
		EnterCriticalSection(&g_cs_frameList);
		g_frameList.push_back(g_BGRImage);
 		LeaveCriticalSection(&g_cs_frameList);
	 }
 }

你可能感兴趣的:(计算机视觉)