在工程应用中特别是图像处理领域数据的来源就是摄像头,为了更好地利用这个摄像头资源可能需要调用摄像头的SDK对摄像头的行为进行控制,以下针对海康摄像头,从python和c++两种语言讲解海康摄像头SDK的调用方法。
环境部署及资源下载(c++)
- 首先去海康官网下载设备网络SDK和SDK手册
- 配置c++开发环境,主要是配置头文件及库文件路径,参考:https://blog.csdn.net/m0_66518283/article/details/128406667
- 结合SDK手册和SDK中的demo熟悉SDK调用流程,基本都是先初始化,然后再调用云控制台函数等相关函数控制摄像头:新建项目–>配置头文件,库文件–>把dll文件,以及相关文件夹复制到运行目录 –>根据sdk文档开发相应功能
- 如果出现报错,可以根据错误码排查问题:https://open.hikvision.com/hardware/definitions/NET_DVR_GetLastError.html
- 比如我在开发的时候发现报107,原来是资源文件没有配置好,参见:https://blog.csdn.net/weixin_42076938/article/details/103195484
基于python的海康摄像头SDK开发
- 深度学习一般使用的python框架进行开发,因此还需要考虑对c++与python的交互
- 海康SDK提供了python的demo代码,原理也是用的ctypes,参考:https://www.ryannn.com/archives/hikvision/comment-page-4
- 利用ctypes包实现python调用c++代码,大致原理就是将所有的dll文件添加到一个list中,然后一个个遍历调用指定的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import os, ctypes
import cv2
# 遍历动态链接库目录
def add_dll(path, dll_list):
files = os.listdir(path)
for file in files:
if not os.path.isdir(path + file):
if file.endswith(".dll"):
dll_list.append(path + file)
else:
add_dll(path + file + "/", dll_list)
# 载入动态链接库
def callCpp(func_name, *args):
for so_lib in so_list:
try:
lib = ctypes.cdll.LoadLibrary(so_lib)
try:
value = eval("lib.%s" % func_name)(*args)
# print("调用的库:" + so_lib)
# print("执行成功,返回值:" + str(value))
return value
except:
continue
except:
print("库文件载入失败:" + so_lib)
continue
print("没有找到接口!")
return False
# 云台控制操作
def NET_DVR_PTZControl_Other(lUserID, lChannel, dwPTZCommand, dwStop):
res = callCpp("NET_DVR_PTZControl_Other", lUserID, lChannel, dwPTZCommand, dwStop)
if res:
print("控制成功")
else:
print("控制失败: " + str(callCpp("NET_DVR_GetLastError"))) - 如果SDK中的函数输入是结构体,则在python中需要进行如下构造:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 抓图数据结构体
class NET_DVR_JPEGPARA(ctypes.Structure):
_fields_ = [
("wPicSize", ctypes.c_ushort), # WORD
("wPicQuality", ctypes.c_ushort)] # WORD
# jpeg 抓图
# hPlayWnd 显示窗口可以为 none;存在缺点采集图片速度慢
def NET_DVR_CaptureJPEGPicture():
sJpegPicFileName = bytes("pytest.jpg", "ascii")
lpJpegPara = NET_DVR_JPEGPARA()
lpJpegPara.wPicSize = 2
lpJpegPara.wPicQuality = 1
res = callCpp("NET_DVR_CaptureJPEGPicture", lUserID, lChannel, ctypes.byref(lpJpegPara), sJpegPicFileName)
if res == False:
error_info = callCpp("NET_DVR_GetLastError")
print("抓图失败:" + str(error_info))
else:
print("抓图成功") - 设计到结构体时可能python的类型和c++的类型不知道怎么设置,可以参考:https://www.codenong.com/jsc3c4bf3d1ef8/