python opencv 调用 海康威视工业相机(又全又细又简洁)

1.准备工作

准备一个海康相机

下载MVS 和SDK

2.python MVS示例

(说明:MVS里有很多python示例,可以直接运行,但没有用opencv)

下载完MVS后,我们打开路径安装路径

我的:

D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo

D:\soft\MVS\MVS\Development\Samples\Python\MvImport

可以看到有很多现成的示例。

我们借用一下"D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo\BasicDemo.py"

创建 python项目test_HKcamera

复制BasicDemo.py

发现一片红,

我们把

D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo

D:\soft\MVS\MVS\Development\Samples\Python\MvImport

里面的文件都复制过来

复制后,如图所示:

运行后:

成功输出画面。

3. python opencv 调用

创建test_HKcamera_opencv文件夹

创建test_hk_opecv.py文件

把第二节的文件复制进来

如图:

test_hk_opecv.py完整代码如下:

import cv2
import numpy as np
from MvCameraControl_class import *
from CameraParams_header import *


#-------------------opencv操作部分--------------------------------------
def opencv_action(img):
    #自己定义操作
    result_img = img
    return result_img

#-----------------------海康相机设置部分---------------------------------------

ret = MvCamera.MV_CC_Initialize()
if ret != 0:
    print(f"初始化SDK失败,错误码: {ret}")
    exit()

# 枚举设备
deviceList = MV_CC_DEVICE_INFO_LIST()
n_layer_type = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE
ret = MvCamera.MV_CC_EnumDevices(n_layer_type, deviceList)
if ret != 0:
    print("枚举设备失败")
    exit()

print(f"找到 {deviceList.nDeviceNum} 台设备")
if deviceList.nDeviceNum == 0:
    exit()

stDeviceList = cast(deviceList.pDeviceInfo[0], POINTER(MV_CC_DEVICE_INFO)).contents

camera = MvCamera()

ret = camera.MV_CC_CreateHandle(stDeviceList)

# 打开设备(使用已创建的句柄)
ret = camera.MV_CC_OpenDevice()
if ret != 0:
    print(f"打开设备失败,错误码: {ret}")
    exit()



# 获取相机参数
width = c_uint()
height = c_uint()
pixel_format = c_uint()
payload_size = c_uint()
stParam = MVCC_INTVALUE()

ret = camera.MV_CC_GetIntValue("PayloadSize", stParam)
if ret != 0:
    print(f"获取PayloadSize失败,错误码: {ret}")
    exit()
payload_size.value = stParam.nCurValue

# 获取宽度
ret = camera.MV_CC_GetIntValue("Width", stParam)
if ret != 0:
    print(f"获取宽度失败,错误码: {ret}")
    exit()
width.value = stParam.nCurValue

# 获取高度
ret = camera.MV_CC_GetIntValue("Height", stParam)
if ret != 0:
    print(f"获取高度失败,错误码: {ret}")
    exit()
height.value = stParam.nCurValue

print(width.value,height.value)



pixel_format.value = 17301505  # RGB8
# 或
#pixel_format.value = 17301514  # Mono8

#曝光时间
exposure_time = 15000  # 单位:微秒
ret = camera.MV_CC_SetFloatValue("ExposureTime", exposure_time)



# 开始抓图
ret = camera.MV_CC_StartGrabbing()
if ret != 0:
    print(f"开始抓图失败,错误码: {ret}")
    exit()

# 分配缓冲区
data_buf = (c_ubyte * payload_size.value)()
data_size = c_uint(payload_size.value)

stFrameInfo = MV_FRAME_OUT_INFO_EX()

#-----------------------------------------------运行部分---------------------------



# 创建OpenCV窗口
cv2.namedWindow("Camera", cv2.WINDOW_NORMAL)

try:
    while True:
        data_buf = (c_ubyte * payload_size.value)()
        ret = camera.MV_CC_GetOneFrameTimeout(
            byref(data_buf),
            payload_size.value,
            stFrameInfo,
            1000
        )

        if ret == 0:
            #print(f"获取到帧: 宽度={stFrameInfo.nWidth}, 高度={stFrameInfo.nHeight}, "f"像素格式={stFrameInfo.enPixelType}, 帧大小={stFrameInfo.nFrameLen}")

            frame = np.frombuffer(data_buf, dtype=np.uint8)
            actual_width = stFrameInfo.nWidth
            actual_height = stFrameInfo.nHeight

            if stFrameInfo.enPixelType == 17301505:  # RGB8
                expected_size = actual_width * actual_height * 3
                if len(frame) != expected_size:
                    print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
                    continue

                frame = frame.reshape((actual_height, actual_width, 3))
                frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            elif stFrameInfo.enPixelType == 17301514:  # Mono8
                expected_size = actual_width * actual_height
                if len(frame) != expected_size:
                    print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
                    continue

                frame = frame.reshape((actual_height, actual_width))
            elif stFrameInfo.enPixelType == 17301513:  # 可能是 Bayer 格式
                expected_size = actual_width * actual_height
                if len(frame) != expected_size:
                    print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
                    continue

                frame = frame.reshape((actual_height, actual_width))
                frame = cv2.cvtColor(frame, cv2.COLOR_BayerGB2BGR)

                frame = opencv_action(frame)
            else:
                print(f"不支持的像素格式: {stFrameInfo.enPixelType}")
                break

            cv2.imshow("Camera", frame)

            if cv2.waitKey(1) & 0xFF == ord("q"):
                break

        else:
            print(f"获取图像失败,错误码: {ret}")
            break



finally:
    # 停止抓图
    camera.MV_CC_StopGrabbing()
    # 关闭设备
    camera.MV_CC_CloseDevice()
    # 销毁句柄
    camera.MV_CC_DestroyHandle()
    # 销毁窗口
    cv2.destroyAllWindows()

完整代码如下:

通过网盘分享的文件:py_opencv_HK
链接:https://pan.baidu.com/s/1DmrVSV1LT9zGBCRx3nIKAQ

提取码: usii

4.花絮

不知道哪个教程教的=-=

# 创建设备句柄

handle = c_void_p()

stDeviceList = cast(deviceList.pDeviceInfo[0], POINTER(MV_CC_DEVICE_INFO)).contents

# 创建相机实例并调用方法(关键修正点)
camera = MvCamera()  # 实例化 MvCamera 类

#方法一:
ret = camera.MV_CC_CreateHandle(stDeviceList)
#报错:TypeError: MvCamera.MV_CC_GetIntValue() takes 3 positional arguments but 4 were given

#方法二:
#ret = MvCamera.MV_CC_CreateHandle(byref(handle), stDeviceList)
#报错AttributeError: '_ctypes.CArgObject' object has no attribute 'handle'

#方法三:
#ret = MvCamera.MV_CC_CreateHandle(byref(stDeviceList))
#报错TypeError: MvCamera.MV_CC_CreateHandle() missing 1 required positional argument: 'stDevInfo'

#方法四:
#ret = camera.MV_CC_OpenDevice(byref(handle),byref(stDeviceList))
#报错TypeError: MvCamera.MV_CC_CreateHandle() missing 1 required positional argument: 'stDevInfo'



# 打开设备(使用已创建的句柄)
ret = MvCamera.MV_CC_OpenDevice(handle)
if ret != 0:
    print(f"打开设备失败,错误码: {ret}")
    exit()

创建

handle = c_void_p()

就疯狂报错。

### 使用PythonOpenCV调用海康威视工业相机 对于使用PythonOpenCV调用海康威视工业相机的操作,通常情况下,直接通过OpenCV可能无法实现这一目标,因为这涉及到特定厂商设备的接口协议。然而,可以借助于海康威视官方提供的SDK或者第三方库如`imutils`、`opencv-python`以及网络摄像头URL流的方式间接达成目的。 一种常见方法是利用海康威视提供的ONVIF协议支持来进行开发。ONVIF是一个全球性的开放型行业论坛,旨在推动安防设备之间的互操作性。许多现代IP摄像机都遵循此标准,允许开发者通过标准化API与其交互[^1]。 具体到编程层面: #### 安装必要的依赖包 为了能够连接并控制兼容ONVIF的Hikvision IP Camera,在项目环境中需先安装几个重要的Python库: ```bash pip install onvif-zeep h264decoder requests zeep ``` 这些工具可以帮助解析SOAP消息并与基于Web服务定义语言(WSDL)的服务端点通信。 #### 连接至海康威视工业相机 下面给出一段简单的代码片段用于演示如何初始化一个针对指定地址的ONVIF客户端实例,并尝试获取视频流URI以便后续处理: ```python from onvif import ONVIFCamera, ONVIFService mycam = ONVIFCamera('camera_ip', 80, 'username', 'password') media_service = mycam.create_media_service() profiles = media_service.GetProfiles() token = profiles[0].token stream_uri = media_service.GetStreamUri({ 'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'RTSP'} }, 'ProfileToken': token }) print(stream_uri.Uri) ``` 上述脚本会打印出可用于播放或进一步分析的数据源链接。一旦获得了有效的RTSP URL路径,则可以通过如下方式将其引入OpenCV框架内进行实时预览或其他高级运算任务: ```python import cv2 cap = cv2.VideoCapture(stream_uri.Uri) while True: ret, frame = cap.read() if not ret: break # Convert BGR color (which is the default format of OpenCV images) to RGB before displaying. rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) cv2.imshow('Frame from Hikvision Industrial Camera', rgb_frame) key = cv2.waitKey(1) & 0xFF if key == ord("q"): break cv2.destroyAllWindows() cap.release() ``` 这段程序展示了基本的工作流程:建立与远程硬件资源间的联系;读取每一帧画面数据;转换色彩模式以适应显示需求;最后呈现给用户查看直至按下键盘上的'q'键退出循环停止捕获过程[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值