Python海康相机API入门指南:超简单学习,新手必看

1.准备工作

海康官网下载相机驱动海康机器人-机器视觉-下载中心

安装好以后找到Python的开发文件目录参考:D:\MVS\MVS\Development\Samples\Python\MvImport这几个文件很重要,想调用海康相机取图会用到.

为了写代码方便可以把这几个文件拷贝一下,跟你的api主文件放在同一个文件夹下可以减少80%的烦恼.

2.打开相机

1.枚举设备

我这里枚举了两种设备USB和网口:

2.实例化相机

好多刚入坑的人会忽略这一步

3.选择相机

这里选择用编号来连接相机,后边更深入学习后可改用ip链接相机,我电脑就插入了一个海康的网口相机,所以int(0)直接写0就好了

4.设置触发方式

因为海康相机触发方式有可能是on,off才可以打开相机,所以为了避免新手遇到一堆报错,这里直接代码设置触发方式为off,(也可以通过mvs把相机触发方式设置为off).

5.打开相机

连接相机

6.开始取流

到取流这一步可以想象成已经打开了相机实时取图这一步

3.获取一张图像

获取一张图像数据

4.关闭相机

停止取流—关闭设备—销毁句柄

5.完整代码

把最后注释掉的代码释放掉运行,就可以看到你相机拍摄的图片了
 

from.MvCameraControl_class import *
# from.CameraParams_header import *
from ctypes import *
import time
import cv2
import numpy as np
# sys.path.append("./Become a master in a hundred days/CAMapi")
class CameraManager:

    def __init__(self):
        self.cam = None
        self.data_buf = None
        self.device_status = False
        self.stOutFrame = None

    def data_camera(self):

        # 枚举设备
        tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE
        deviceList = MV_CC_DEVICE_INFO_LIST()
        # 实例相机
        self.cam = MvCamera()
        ret = self.cam.MV_CC_EnumDevices(tlayerType, deviceList)
        if ret is None:
            print("错误")
            return
        else:
            print(ret)
        # 选择设备
        stDeviceList = cast(deviceList.pDeviceInfo[int(0)], POINTER(MV_CC_DEVICE_INFO)).contents
        # 创建句柄
        ret = self.cam.MV_CC_CreateHandleWithoutLog(stDeviceList)
        # start_time = time.time()
        # 获取设备名称,返回是一个内存地址,循环遍历用chr把每个字符码转换为字符
        # strModeName = ""
        # for per in stDeviceList.SpecialInfo.stGigEInfo.chModelName:
        #     strModeName = strModeName + chr(per)
        # print(f"device model name:{strModeName}")
        # 获取设备名称,ctypes.string_at 函数直接将内存地址中的内容读取为字节字符串,然后使用 decode('utf-8') 进行解码。
        strModeName = ctypes.string_at(stDeviceList.SpecialInfo.stGigEInfo.chModelName).decode('utf-8')
        print(f"设备名称:{strModeName}")
        # end_time = time.time()
        # camera_time = round(abs(start_time - end_time) * 1000, 3)  # 保留小数点后3为,拍照时间
        # print(f"获取设备名称时间:{camera_time}ms")
        # 设置触发方式
        ret = self.cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
        # 打开相机
        ret = self.cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        print("打开相机执行码:[0x%x]" % ret)
        # 开始取流
        ret = self.cam.MV_CC_StartGrabbing()
        self.device_status = True
        return self.cam


    def get_image(self):

        # 获取一张图像
        self.stOutFrame = MV_FRAME_OUT()  # 图像结构体,输出图像地址&信息
        start_time = time.time()
        ret = self.cam.MV_CC_GetImageBuffer(self.stOutFrame, 300)  # 图像获取函数
        print("图像获取执行码:[0x%x]" % ret)
        end_time = time.time()
        camera_time = round(abs(start_time - end_time) * 1000, 3)  # 保留小数点后3为,拍照时间
        print(f"获取图像时间:{camera_time}ms")

        # 获取图像数据的长度和指针
        nPayloadSize = self.stOutFrame.stFrameInfo.nFrameLen
        pData = self.stOutFrame.pBufAddr

        # 将数据存储在 data_buf 中
        self.data_buf = (c_ubyte * nPayloadSize)()
        cdll.msvcrt.memcpy(byref(self.data_buf), pData, nPayloadSize)

        end_time = time.time()
        camera_time = round(abs(start_time - end_time) * 1000, 3)  # 保留小数点后3为,拍照时间
        print(f"获取图像储存时间:{camera_time}ms")
        #释放图像缓存
        self.cam.MV_CC_FreeImageBuffer(self.stOutFrame)
        return self.data_buf


    def off_camera(self):

        # 停止取流
        ret = self.cam.MV_CC_StopGrabbing()
        print("停止取流执行码:[0x%x]" % ret)

        # 关闭设备
        ret = self.cam.MV_CC_CloseDevice()
        print("关闭设备执行码:[0x%x]" % ret)

        # 销毁句柄
        ret = self.cam.MV_CC_DestroyHandle()
        print("销毁句柄执行码:[0x%x]" % ret)
        self.device_status = False
        return self.device_status
    



# #实例化类
# CAM = CameraManager()
# deta_CAM = input("输入1链接相机:")
# if deta_CAM == "1":
#     CAM.data_camera()
#     print(f"当前相机链接状态:{CAM.device_status}")
# else:
#     print("链接相机错误!")



# deta_CAM = input("输入2获取图片:")
# if deta_CAM == "2":
#     CAM.get_image()
#     print(f"当前相机链接状态:{CAM.device_status}获取图片!")
# else:
#     print("获取图片错误!")

# # 将 c_ubyte 数组转换为 numpy 数组
# temp = np.frombuffer(CAM.data_buf, dtype=np.uint8)

# # 检查图像的分辨率信息,假设它是 2048x1024x3
# # 但首先需要确认图像的真实分辨率和像素格式,这里假设为 RGB 格式
# # 你可能需要根据实际情况调整 reshape 的参数
# # 使用正确的分辨率信息进行重塑
# width = CAM.stOutFrame.stFrameInfo.nWidth
# height = CAM.stOutFrame.stFrameInfo.nHeight
# channels = 3  # 假设是 RGB 图像,如果是其他格式,请修改
# print(width)
# print(height)
# try:
#     temp = temp.reshape((height, width, channels))
# except Exception as e:
#     print(f"Reshape error: {e}")


# # 将 BGR 转换为 RGB
# temp = cv2.cvtColor(temp, cv2.COLOR_RGB2BGR)


# # 转换为灰度图像
# gray = cv2.cvtColor(temp, cv2.COLOR_RGB2GRAY)


# # 显示图像
# cv2.namedWindow("ori", cv2.WINDOW_NORMAL)
# cv2.imshow("ori", temp)


# # 显示灰度图像
# cv2.namedWindow("gray", cv2.WINDOW_NORMAL)
# cv2.imshow("gray", gray)


# cv2.waitKey(0)



# deta_CAM = input("输入3关闭相机设备:")
# if deta_CAM == "3":
#     CAM.off_camera()
#     print(f"当前相机链接状态:{CAM.device_status}")
# else:
#     print("关闭相机错误!")

作者:不惑之年~

物联沃分享整理
物联沃-IOTWORD物联网 » Python海康相机API入门指南:超简单学习,新手必看

发表回复