丹东东方测控技术股份有限公司 辽宁 丹东 118000
海康威视的监控产品在工业企业内应用十分广泛,如何利用海康威视产品实现专有定制化视频监控系统是十分有意义的。Python语言易学易用,简单高效,但目前海康官方还未提供Python版SDK。本文介绍了在Windows系统下Python编程环境中,结合海康威视SDK设计和开发工业设备实时视频监控软件的方法。
(1)Python简介。Python是一种跨平台的计算机程序设计语言。无论是桌面开发序、Web开发、人工智能、自动化运维、科学运算,Python都有着丰富的扩展模块,使用Python开发应用程序,无疑是高效的。
(2)海康SDK。海康威视SDK即海康提供的开发包,主要包含设备网络SDK和播放库SDK(以下简称SDK)。海康威视设备网络SDK是基于设备私有网络通信协议开发的,为嵌入式网络硬盘录像机、网络摄像机等网络产品服务的配套模块,提供Windows和Linux两个版本,用于远程访问和控制设备软件的二次开发[1]。
模块Ctypes是Python内建的用于调用动态链接库函数的功能模块,一定程度上可以用于Python与其他语言的混合编程,可以说Ctypes模块是Python应用程序与SDK之间的桥梁。
DLL(动态链接库)是Dynamic Link Library的缩写,在Windows下Python环境中使用ctypes.windll.loadLibrary()函数进行DLL的装载。本例中海康SDK的DLL载入方法为:sdk=windll.LoadLibrary("HCNetSDK.dll")。
Ctypes提供和c语言兼容的数据类型,可以很方便地调用DLL中的函数。如Ctypes中的cbyte对应c语言中的char及Python中的int/long。
海康SDK头文件中包含了大量的结构体,在Python中,结构体必须继承自Ctypes模块的Structure类。每个子类必须定义_fields_属性,该属性是2元素元组的列表,包含字段名和字段类型,其中字段类型必须是Ctypes类型。
在海康SDK头文件中存在大量的宏定义,在Python中可用全局变量来实现。如云台控制:TILT_UP=21,TILT_DOWN=22。
回调函数是一个通过函数指针调用的函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于对该事件或条件进行响应。如回调函数的原型为:CMPFUNC=CFUNCTYPE(c_int,POINTER(c_int),POINTER(c_int)),第一个参数c_int表示函数返回值是int类型。
海康SDK调用流程通常为:初始化SDK,用户登录,预览、云台控制等操作,注销设备,释放SDK资源。
初始化函数用于完成初始内存分配等工作,Python中调用方法为sdk.NET_DVR_Init()。
用户登录实现用户的注册功能,返回用户ID,该用户ID具有唯一性,后续对设备的操作都需要通过此ID实现。Python调用方法为,sdk.NET_DVR_Login_V30(sDVRIP,wDVRPort,sUserName,sPassword,Ctypes.byref(DeviceInfo)),byref()用来传递引用参数,DeviceInfo为设备信息结构体,继承至Ctypes.Structure。
视频预览模块实现从网络设备取实时码流解码显示以及播放控制等功能,Python中调用方法为sdk.NET_DVR_RealPlay_V40(lUserID,Ctypes.byref(lpPreviewInfo),callBack,pUser) 。其中lpPreviewInfo是Ctypes构造的结构体,结构体中lpPreviewInfo.hPlayWnd=hwnd为窗口句柄,用于播放图像。
云台控制实现摄像机的镜头方位调整及变焦变倍等操作,Python中的调用方法为:sdk.NET_DVR_PTZControl(lRealHandle,dwPTZCommand,dwStop)。
建立报警通道函数在Python中调用方法为sdk.NET_DVR_SetupAlarmChan_V41(lUserID,Ctypes.byref(struAlarmParam)),struAlarmParam是Ctypes构造的报警布放参数结构体。启动布防前,需要调用注册回调函数的接口NET_DVR_SetDVRMessageCallBack_V30(),注册回调函数的格式为“回调函数实例=回调函数类型(具体回调函数)”,然后将回调函数实例作为参数传给注册接口。
用户注销函数在Python中的调用方法为sdk.NET_DVR_Logout(lUserID)。
释放资源函数在Python中的调用方法为sdk.NET_DVR_Cleanup(),在程序结束前使用。
将SDK提供的接口进一步封装到类(class)里,从而简化SDK接口,解除上层代码与SDK之间的耦合关系。由于海康SDK只需初始化一次,故这里将类设计为单例模式,将类的函数设计为静态函数。
利用上述方法实现了Python语言与海康SDK的联合开发。用此方法编写的设备监控应用程序运行良好,为后续系统引入智能识别技术打下了坚实的基础。