(202103更新)海康威视网络摄像头sdk python版 (报错排查) 移动物体检测 多通道海康威视网洛摄像头后台检测 海康威视网络摄像头Python SDK

海康威视网络摄像头Python SDK+移动物体位置检测

 

文末附 海康威视网络摄像头Python SDK 下载链接

 

本文参考博客

https://blog.csdn.net/c20081052/article/details/95082377

https://blog.csdn.net/pengpengloveqiaoqiao/article/details/89487049

 

注意:摄像头要在镜头上贴红外滤光片 过滤掉可见光

 

效果展示,已经过滤到大部分波长可见光,手在镜头前来回移动,红框即检测到移动物体的位置,并框出来(海康威视的摄像头可见光好像不能完全被滤光片过滤掉,但是可以过滤到投影机的画面或者屏幕的画面,不影响使用)

 

目录

1.将海康威视的C++  sdk 转化为 Python sdk

2.调用海康威视Python SDK

3.调用多个海康威视摄像头

4. 将多个摄像头画面拼接成一个

5.挨个摄像头透视变换

6. 透视变换完后再在拼接后的画面上做动态物体检测,参考博客


1.将海康威视的C++  sdk 转化为 Python sdk  (本文已经处理完了)

如何将海康威视的C++  sdk 转化为 Python 可用的sdk ,请参考博主 ciky奇 的文章,链接如下

https://blog.csdn.net/c20081052/article/details/95082377  如果最后一步Python调用时遇到报错,尝试将所有相关的文件全部复制到Python工程的路径下

环境:

1. windows10  64位

2. opecv

3. python3

4.海康威视网络摄像头64位 C++ sdk

    https://www.hikvision.com/cn/download_61.html

    下载SDK_Win64

5.其他库文件:

   5.1 opencv-python

   5.2 numpy

   5.3 multiprocessing (多进程使用)

本文已将海康威视C++ sdk转为Python sdk处理好,可以直接下载使用,文末网址分享

 

如果HKIPCamera 一直报错,找不到模块    ,首先 python 和 opencv要安装好,并且设置好环境变量,如果还是报错:

 

一般是缺少VC++库的运行时组件,两个方案:

 

1. 从微软官网下载VC++库的运行时组件:  

此组件也可以解决其他项目上的很多疑难杂症

官网链接: https://visualstudio.microsoft.com/zh-hans/downloads/

 

2、下载一个DirectX修复工具

链接:https://pan.baidu.com/s/1thfI2SyCpQoToBxuwFnxuA 
提取码:8aza 

 

打开后点击   工具----> 选项---->扩展---->开始扩展

 

 

 

扩展完了以后,此时会默认选中同时更新C++,点击检测并修复,

如果缺少组件就会自动安装,如果已经安装了但是不是最新的,会自动更新,

等修复完了,再尝试运行Python程序

 

 

如果还是一直存在问题,请回头参考博文https://blog.csdn.net/c20081052/article/details/95082377一步一步重新操作

 

2.调用海康威视Python SDK

 

import cv2
import numpy as np
import HKIPcamera

def get_cam_frame(ip, account, password):

    ip = str(ip)  # 摄像头IP地址,要和本机IP在同一局域网
    name = str(account)       # 管理员用户名
    pw = str(password)        # 管理员密码

    HKIPcamera.init(ip, name, pw)

    while(True): 
        fram = HKIPcamera.getframe()     
        frame = np.array(fram)
        cv2.imshow('frame',frame)
        c = cv2.waitKey(10)
        if c == 27:
            break;
    HKIPcamera.release()
   

if __name__ == '__main__':

    get_cam_frame('192.168.1.64', 'admin', '123456')


 

 

3.调用多个海康威视摄像头

    调用多个摄像头需要用到多进程,多线程不起作用

    在第一步的代码基础上修改一下

 

import cv2
import numpy as np
import HKIPcamera
from multiprocessing import Process, Queue

def get_cam_frame(frameName, ip, account, password):
    ip = str(ip)  # 摄像头IP地址,要和本机IP在同一局域网
    name = str(account)  # 管理员用户名
    pw = str(password)  # 管理员密码

    HKIPcamera.init(ip, name, pw)

    while True:
        fram = HKIPcamera.getframe()
        frame = np.array(fram)
        cv2.imshow(frameName, frame)
        c = cv2.waitKey(10)
        if c == 27:
             break;
    HKIPcamera.release()


if __name__ == '__main__':

    
     p0 = Process(target=get_cam_frame, args=('frame0', '192.168.1.64', 'admin', '123456',))
     p0.start()

    
     p1 = Process(target=get_cam_frame, args=('frame1', '192.168.1.65', 'admin', '123456',))
     p1.start()
     
     # 以此类推   p2 p3 ... pn







 

    

4. 将多个摄像头画面拼接成一个

 

       再在上述的代码基础上修改

 

import cv2
import numpy as np
import HKIPcamera
from multiprocessing import Process, Queue
import os
import signal

def get_cam_frame(frameName, ip, account, password, n):
    ip = str(ip)  # 摄像头IP地址,要和本机IP在同一局域网
    name = str(account)  # 管理员用户名
    pw = str(password)  # 管理员密码

    HKIPcamera.init(ip, name, pw)

    while True:
        fram = HKIPcamera.getframe()
        frame = np.array(fram)
        # 由于摄像头画面是1920*1080,多个拼接的话,画面会非常大,所有重置一下每个摄像头的画面
        frame = cv2.resize(frame, (768, 540), interpolation=cv2.INTER_CUBIC)
        n.put(frame)
        cv2.imshow(frameName, frame)
        c = cv2.waitKey(10)
        if c == 27:
             break;
    HKIPcamera.release()


if __name__ == '__main__':

     q0 = Queue(3)
     p0 = Process(target=get_cam_frame, args=('frame0', '192.168.1.64', 'admin', '123456', q0,))
     p0.start()

     q1 = Queue(3)
     p1 = Process(target=get_cam_frame, args=('frame1', '192.168.1.65', 'admin', '12345', q1,))
     p1.start()

     while True:
         if p0.is_alive() and p1.is_alive():
             frame0 = q0.get()
             frame1 = q1.get()
             # 横着拼
             full_frame = np.hstack([frame0, frame1])
             # 竖着拼
             # full_frame = np.vstack([frame0, frame1])
             cv2.imshow('full_frame', full_frame)
             c = cv2.waitKey(10)
             if c==27:
                 os.kill(p0.pid, signal.SIGTERM)
                 os.kill(p1.pid, signal.SIGTERM)
                 break;










 

5.挨个摄像头透视变换

   如果不了解opencv-python透视变换函数的参数,请先看下此博客的透视变换函数介绍,链接如下:

   https://blog.csdn.net/wsp_1138886114/article/details/83374333

   

import cv2
import numpy as np
import HKIPcamera
from multiprocessing import Process, Queue
import os
import signal

def get_cam_frame(frameName, ip, account, password, n):
    ip = str(ip)  # 摄像头IP地址,要和本机IP在同一局域网
    name = str(account)  # 管理员用户名
    pw = str(password)  # 管理员密码

    HKIPcamera.init(ip, name, pw)

    while True:
        fram = HKIPcamera.getframe()
        frame = np.array(fram)
        # 由于摄像头画面是1920*1080,多个拼接的话,画面会非常大,所有重置一下每个摄像头的画面
        frame = cv2.resize(frame, (768, 540), interpolation=cv2.INTER_CUBIC)
        n.put(frame)
        cv2.imshow(frameName, frame)
        c = cv2.waitKey(10)
        if c == 27:
             break;
    HKIPcamera.release()



#第一个摄像头透视变化的四个点
frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3 = 0, 0, 0, 0, 0, 0, 0, 0
#第二个摄像头透视变化的四个点
frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3 = 0, 0, 0, 0, 0, 0, 0, 0


#简单来写,按照从第一个摄像头开始,鼠标每点击一次,获取一个点
#例如鼠标第一次点击,就等于给坐标frame0_x0, frame0_y0 赋值, 第二次点击就是给坐标frame0_x1, frame0_y1赋值,以此类推

clickNum = 0

def draw_point(event, x, y, flags, param):
    global frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3
    global frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3, clickNum
    if event == cv2.EVENT_LBUTTONDOWN:
        if clickNum == 0:
            frame0_x0 = x
            frame0_y0 = y
        elif clickNum == 1:
            frame0_x1 = x
            frame0_y1 = y
        elif clickNum == 2:
            frame0_x2 = x
            frame0_y2 = y
        elif clickNum == 3:
            frame0_x3 = x
            frame0_y3 = y
        elif clickNum == 4:
            frame1_x0 = x
            frame1_y0 = y
        elif clickNum == 5:
            frame1_x1 = x
            frame1_y1 = y
        elif clickNum == 6:
            frame1_x2 = x
            frame1_y2 = y
        elif clickNum == 7:
            frame1_x3 = x
            frame1_y3 = y

        clickNum += 1


# 透视变换
def perspective_transform():
    global frame0, frame1, clickNum
    global frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3
    global frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3
    
    if clickNum==8:
        W_cols, H_rows = frame0.shape[:2]

        pts0_1 = np.float32(
            [[frame0_x0, frame0_y0], [frame0_x1, frame0_y1],
             [frame0_x2, frame0_y2], [frame0_x3, frame0_y3]])
        pts0_2 = np.float32([[0, 0], [W_cols, 0], [0, H_rows], [W_cols, H_rows]])
        M0 = cv2.getPerspectiveTransform(pts0_1, pts0_2)
        frame0 = cv2.warpPerspective(frame0, M0, (W_cols, H_rows))

        # 这里的变换需要减去第一个摄像头的画面的宽度,768
        pts1_1 = np.float32(
            [[frame1_x0-768, frame1_y0], [frame1_x1-768, frame1_y1],
             [frame1_x2-768, frame1_y2], [frame1_x3-768, frame1_y3]])
        pts1_2 = np.float32([[0, 0], [W_cols, 0], [0, H_rows], [W_cols, H_rows]])
        M1 = cv2.getPerspectiveTransform(pts1_1, pts1_2)
        frame1 = cv2.warpPerspective(frame1, M1, (W_cols, H_rows))
 

if __name__ == '__main__':

     q0 = Queue(3)
     p0 = Process(target=get_cam_frame, args=('frame0', '192.168.1.64', 'admin', '123456', q0,))
     p0.start()

     q1 = Queue(3)
     p1 = Process(target=get_cam_frame, args=('frame1', '192.168.1.65', 'admin', '123456', q1,))
     p1.start()

     cv2.namedWindow('full_frame')
     # 鼠标点击事件
     cv2.setMouseCallback('full_frame', draw_point)

     while True:
         if p0.is_alive() and p1.is_alive():
             frame0 = q0.get()
             frame1 = q1.get()

             # 透视变换
             perspective_transform()
             # 透视变换完再拼接
             # 横着拼
             full_frame = np.hstack([frame0, frame1])
             # 竖着拼
             #full_frame = np.vstack([frame0, frame1])
             cv2.imshow('full_frame', full_frame)
             c = cv2.waitKey(10)
             if c==27:
                 os.kill(p0.pid, signal.SIGTERM)
                 os.kill(p1.pid, signal.SIGTERM)
                 break;










 

 

6. 透视变换完后再在拼接后的画面上做动态物体检测,参考博客

 https://blog.csdn.net/pengpengloveqiaoqiao/article/details/89487049

   

import cv2
import numpy as np
import HKIPcamera
from multiprocessing import Process, Queue
import os
import signal

def get_cam_frame(frameName, ip, account, password, n):
    ip = str(ip)  # 摄像头IP地址,要和本机IP在同一局域网
    name = str(account)  # 管理员用户名
    pw = str(password)  # 管理员密码

    HKIPcamera.init(ip, name, pw)

    while True:
        fram = HKIPcamera.getframe()
        frame = np.array(fram)
        # 由于摄像头画面是1920*1080,多个拼接的话,画面会非常大,所有重置一下每个摄像头的画面
        frame = cv2.resize(frame, (768, 540), interpolation=cv2.INTER_CUBIC)
        n.put(frame)
        cv2.imshow(frameName, frame)
        c = cv2.waitKey(10)
        if c == 27:
             break;
    HKIPcamera.release()



#第一个摄像头透视变化的四个点
frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3 = 0, 0, 0, 0, 0, 0, 0, 0
#第二个摄像头透视变化的四个点
frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3 = 0, 0, 0, 0, 0, 0, 0, 0


#简单来写,按照从第一个摄像头开始,鼠标每点击一次,获取一个点
#例如鼠标第一次点击,就等于给坐标frame0_x0, frame0_y0 赋值, 第二次点击就是给坐标frame0_x1, frame0_y1赋值,以此类推

clickNum = 0

def draw_point(event, x, y, flags, param):
    global frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3
    global frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3, clickNum
    if event == cv2.EVENT_LBUTTONDOWN:
        if clickNum == 0:
            frame0_x0 = x
            frame0_y0 = y
        elif clickNum == 1:
            frame0_x1 = x
            frame0_y1 = y
        elif clickNum == 2:
            frame0_x2 = x
            frame0_y2 = y
        elif clickNum == 3:
            frame0_x3 = x
            frame0_y3 = y
        elif clickNum == 4:
            frame1_x0 = x
            frame1_y0 = y
        elif clickNum == 5:
            frame1_x1 = x
            frame1_y1 = y
        elif clickNum == 6:
            frame1_x2 = x
            frame1_y2 = y
        elif clickNum == 7:
            frame1_x3 = x
            frame1_y3 = y

        clickNum += 1


# 透视变换
def perspective_transform():
    global frame0, frame1, clickNum
    global frame0_x0, frame0_y0, frame0_x1, frame0_y1, frame0_x2, frame0_y2, frame0_x3, frame0_y3
    global frame1_x0, frame1_y0, frame1_x1, frame1_y1, frame1_x2, frame1_y2, frame1_x3, frame1_y3

    if clickNum==8:
        W_cols, H_rows = frame0.shape[:2]

        pts0_1 = np.float32(
            [[frame0_x0, frame0_y0], [frame0_x1, frame0_y1],
             [frame0_x2, frame0_y2], [frame0_x3, frame0_y3]])
        pts0_2 = np.float32([[0, 0], [W_cols, 0], [0, H_rows], [W_cols, H_rows]])
        M0 = cv2.getPerspectiveTransform(pts0_1, pts0_2)
        frame0 = cv2.warpPerspective(frame0, M0, (W_cols, H_rows))

        # 这里的变换需要减去第一个摄像头的画面的宽度,768
        pts1_1 = np.float32(
            [[frame1_x0-768, frame1_y0], [frame1_x1-768, frame1_y1],
             [frame1_x2-768, frame1_y2], [frame1_x3-768, frame1_y3]])
        pts1_2 = np.float32([[0, 0], [W_cols, 0], [0, H_rows], [W_cols, H_rows]])
        M1 = cv2.getPerspectiveTransform(pts1_1, pts1_2)
        frame1 = cv2.warpPerspective(frame1, M1, (W_cols, H_rows))





if __name__ == '__main__':

     q0 = Queue(3)
     p0 = Process(target=get_cam_frame, args=('frame0', '192.168.1.64', 'admin', '123456', q0,))
     p0.start()

     q1 = Queue(3)
     p1 = Process(target=get_cam_frame, args=('frame1', '192.168.1.65', 'admin', '123456', q1,))
     p1.start()

     cv2.namedWindow('full_frame')
     # 鼠标点击事件
     cv2.setMouseCallback('full_frame', draw_point)

     kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
     fgbg = cv2.createBackgroundSubtractorMOG2()
     while True:
         if p0.is_alive() and p1.is_alive():
             frame0 = q0.get()
             frame1 = q1.get()

             # 透视变换
             perspective_transform()
             # 透视变换完再拼接
             # 横着拼
             full_frame = np.hstack([frame0, frame1])
             # 竖着拼
             #full_frame = np.vstack([frame0, frame1])

             fgmask = fgbg.apply(full_frame)
             mask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
             contours, _ = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

             for c in contours:
                 if 100 < cv2.contourArea(c) < 40000:
                     x, y, w, h = cv2.boundingRect(c)
                     cv2.rectangle(full_frame, (x, y), (x + w, y + h), (0, 0, 255))


             cv2.imshow('full_frame', full_frame)
             c = cv2.waitKey(10)
             if c==27:
                 os.kill(p0.pid, signal.SIGTERM)
                 os.kill(p1.pid, signal.SIGTERM)
                 break;










 

 

最后再写个Json或者XML(我没写)保存一下透视变换的点位信息完整工程分享

链接:https://pan.baidu.com/s/1zHwWCW5dW-XR6a98RfEuew 
提取码:6gfc

 

 

 

 

  • 5
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 要在Windows下使用Python调用海康威视网络摄像头SDK,可以按照以下步骤操作: 1. 安装海康威视网络摄像头SDK:首先,从海康威视官方网站下载并安装最新本的SDK。确保SDK与你的Python本兼容。 2. 设置环境变量:打开控制面板,进入系统属性,点击“高级系统设置”,选择“环境变量”。在系统变量中,找到“Path”变量,并将SDK的安装路径添加到该变量中。这样Python才能找到SDK的库文件。 3. 安装Python海康威视SDK库:通过pip安装Python海康威视SDK库,可以在命令提示符中运行以下命令: ``` pip install hikvisionapi ``` 这样就能将海康威视SDK库安装到Python环境中。 4. 使用Python调用SDK:在Python脚本中导入SDK库并使用其中的函数和类来调用摄像头功能。例如,你可以使用SDK提供的函数初始化摄像头设备、打开视频流、进行图像处理等操作。 需要注意的是,在使用SDK之前,你需要先了解SDK提供的函数和类的使用方法。可以参考SDK的官方文档或样例代码来了解如何正确地调用SDK的各项功能。 总之,通过安装SDK、设置环境变量、安装PythonSDK库,并使用Python脚本来调用SDK的函数和类,你就能在Windows下使用Python调用海康威视网络摄像头SDK了。 ### 回答2: 在Windows操作系统下,可以使用Python调用海康威视网络摄像头SDK来实现摄像头的控制和影像数据的获取。下面是一个简单的示例代码: 首先,确保已经安装了Python和相应的海康威视网络摄像头SDK。 ```python # 导入相关库 from ctypes import * # 加载SDK的动态链接库 hk_sdk = cdll.LoadLibrary('hk_sdk.dll') # 设置登录参数 addr = b'IP地址' # 摄像头的IP地址 port = 8000 # 摄像头的端口号 user = b'用户名' # 登录用户名 password = b'密码' # 登录密码 # 登录摄像头 login_info = hk_sdk.NET_DVR_USER_LOGIN_INFO() # 定义登录信息结构体 login_info.sDeviceAddress = addr # 摄像头的IP地址 login_info.wPort = port # 摄像头的端口号 login_info.sUserName = user # 登录用户名 login_info.sPassword = password # 登录密码 login_info.cbLoginResult = None # 登录结果回调函数 login_info.pUser = None # 用户参数 lUserID = hk_sdk.NET_DVR_Login_V40(byref(login_info), None) # 调用登录函数,获取登录ID # 检查登录是否成功 if lUserID < 0: print('设备登录失败') hk_sdk.NET_DVR_Cleanup() # 释放资源 else: print('设备登录成功') # 进行相关操作,如实时预览或录像等 # 登出摄像头 hk_sdk.NET_DVR_Logout_V30(lUserID) hk_sdk.NET_DVR_Cleanup() # 释放资源 ``` 以上代码首先通过`cdll.LoadLibrary()`函数加载SDK的动态链接库。然后创建一个`NET_DVR_USER_LOGIN_INFO`结构体,并设置登录参数,包括IP地址、端口号、用户名和密码。接着调用`NET_DVR_Login_V40()`函数进行登录,并获取登录ID。如果登录成功,则可以进行相关操作,如实时预览或录像等。最后,调用`NET_DVR_Logout_V30()`函数登出摄像头,并使用`NET_DVR_Cleanup()`函数释放资源。 需要注意的是,具体的操作和功能需根据海康威视网络摄像头SDK的文档进行相关配置和调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值