基于python及c++的海康摄像头二次开发

在工程应用中特别是图像处理领域数据的来源就是摄像头,为了更好地利用这个摄像头资源可能需要调用摄像头的SDK对摄像头的行为进行控制,以下针对海康摄像头,从python和c++两种语言讲解海康摄像头SDK的调用方法。

环境部署及资源下载(c++)

基于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
    38
    import 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/