OpenCV调用工业相机

本文档详细介绍了如何使用Python结合OpenCV库调用Gige接口的工业相机,并展示了两种不同的方法:自动打开0号相机和检测所有相机。主要步骤包括设备枚举、设备信息获取、相机实例创建、句柄创建、打开设备、设置相机参数、图像采集和显示。此外,还提供了回调取流和主动取流两种图像获取方式。

OpenCV调用工业相机

python调用海康工业相机并用opencv显示(整体实现)

python调用Gige网口工业相机 opencv


前言

OpenCV可以简单的调用USB相机,只需通过cap = cv2.VideoCapture(0)即可。
可一旦调用Gige等网口连接的工业相机时,使用cap = cv2.VideoCapture(0)或是cap = cv2.VideoCapture(1)、cap = cv2.VideoCapture(2)等等都无法调用。
通过查阅众多文章后,本人根据自身使用要求整理了一份程序

一、MVS 3.4.1下载

不能使用百度上所能搜到的3.1.0版本,Python编程时缺少参数

直接上链接:MVS3.4.1-for-windows
MVS-2.1.2-for-Linux

二、安装

1. 傻瓜式安装,只需记得安装路径即可(环境变量可加可不加)

在这里插入图片描述

2. 用Pycharm打开

在这里插入图片描述
若没正确安装
C:\Program Files (x86)\Common Files\MVS\Runtime\Win64_x64里的MvCameraControl.dll可能会缺失
出现该问题就把MvCameraControl.dll复制到上述的Python文件夹

在这里插入图片描述

3. 创建GigeOpencv.py文件

在这里插入图片描述

import sys
import threading
import msvcrt
import cv2
import numpy as np
import time

from ctypes import *
from MvCameraControl_class import *
# from tfoddetect import *

g_bExit = False

def main():
    deviceList = MV_CC_DEVICE_INFO_LIST()
    # 选择计算机所使用的相机类型,选越多越慢
    # tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_UNKNOW_DEVICE | MV_1394_DEVICE | MV_CAMERALINK_DEVICE
    tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE

    # ch:枚举设备 | en:Enum device
    ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
    if ret != 0:
        print("enum devices fail! ret[0x%x]" % ret)
        sys.exit()
    if deviceList.nDeviceNum == 0:
        print("find no device!")
        sys.exit()
    print("Find %d devices!" % deviceList.nDeviceNum)


    for i in range(0, deviceList.nDeviceNum):
        mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
        if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
            print("\ngige device: [%d]" % i)
            strModeName = ""
            for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                strModeName = strModeName + chr(per)
            print("device model name: %s" % strModeName)

            # 取得相机IP地址
            nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
            nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
            nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
            nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
            print("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))

    # nConnectionNum = input("please input the number of the device to connect:")
    # 根据需求直接指定要打开的相机
    nConnectionNum = 0
    if int(nConnectionNum) >= deviceList.nDeviceNum:
        print("intput error!")
        sys.exit()

    # ch:创建相机实例 | en:Creat Camera Object
    cam = MvCamera()
    # ch:选择设备并创建句柄 | en:Select device and create handle
    stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents
    ret = cam.MV_CC_CreateHandle(stDeviceList)
    if ret != 0:
        print("create handle fail! ret[0x%x]" % ret)
        sys.exit()
    # ch:打开设备 | en:Open device
    ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
    if ret != 0:
        print("open device fail! ret[0x%x]" % ret)
        sys.exit()
    # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
    if stDeviceList.nTLayerType == MV_GIGE_DEVICE:
        nPacketSize = cam.MV_CC_GetOptimalPacketSize()
        if int(nPacketSize) > 0:
            ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
            if ret != 0:
                print("Warning: Set Packet Size fail! ret[0x%x]" % ret)
        else:
            print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)
    stBool = c_bool(False)
    ret = cam.MV_CC_GetBoolValue("AcquisitionFrameRateEnable", stBool)
    if ret != 0:
        print("get AcquisitionFrameRateEnable fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:设置触发模式为off | en:Set trigger mode as off
    ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
    if ret != 0:
        print("set trigger mode fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:开始取流 | en:Start grab image
    ret = cam.MV_CC_StartGrabbing()
    if ret != 0:
        print("start grabbing fail! ret[0x%x]" % ret)
        sys.exit()

    # 常规化窗口大小以及实时显示
    # cv2.namedWindow('1', cv2.WINDOW_NORMAL)
    while cv2.waitKey(10) != ord('q'):
        src = GetImage(cam)

        # src即为图片,可通过numpy变换数组
        # 此处可根据需要载入tensorflow模型检测
        # tfod(src)
        cv2.imshow("1", src)


    # 只保存图片就直接频闭上段
    # src = GetImage(cam)
    cv2.imwrite('1.png', src)
    cv2.destroyAllWindows()

    # ch:停止取流 | en:Stop grab image
    ret = cam.MV_CC_StopGrabbing()
    if ret != 0:
        print("stop grabbing fail! ret[0x%x]" % ret)
        sys.exit()
    # ch:关闭设备 | Close device
    ret = cam.MV_CC_CloseDevice()
    if ret != 0:
        print("close deivce fail! ret[0x%x]" % ret)
        sys.exit()
    # ch:销毁句柄 | Destroy handle
    ret = cam.MV_CC_DestroyHandle()
    if ret != 0:
        print("destroy handle fail! ret[0x%x]" % ret)
        sys.exit()
    cv2.destroyAllWindows()


def GetImage(cam):
    sec = 0
    data_buf = None
    stOutFrame = MV_FRAME_OUT()
    memset(byref(stOutFrame), 0, sizeof(stOutFrame))
    ret = cam.MV_CC_GetImageBuffer(stOutFrame, 1000)
    if None != stOutFrame.pBufAddr and 0 == ret:
        if data_buf == None:
            data_buf = (c_ubyte * stOutFrame.stFrameInfo.nFrameLen)()
        cdll.msvcrt.memcpy(byref(data_buf), stOutFrame.pBufAddr, stOutFrame.stFrameInfo.nFrameLen)
        temp = np.asarray(data_buf)

        # print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (
        #     stOutFrame.stFrameInfo.nWidth, stOutFrame.stFrameInfo.nHeight, stOutFrame.stFrameInfo.nFrameNum))
        # print(temp.shape)
        # 可以用上述print来获取数据总大小 如 6291456 = 2048 * 3072 * 1   即得channel为1
        # 也可以打开MVS来查看相机分辨率
        # 改成使用相机的宽和高以及通道
        temp = temp.reshape((2048, 3072, 1))
        temp = cv2.cvtColor(temp, cv2.COLOR_BayerBG2BGR)
        nRet = cam.MV_CC_FreeImageBuffer(stOutFrame)
        return temp
    else:
        print("no data[0x%x]" % ret)

if __name__ == "__main__":
    main()

该段代码是自动打开0号相机,若提示错误检查MvCameraControl.dll是否导入
注意最后的temp.reshape操作,需要完全安装相机配置来更改
此代码仅仅针对Gige工业相机

3. 创建AllOpencv.py文件

此代码所有相机可检测,不过搜索时间会很久

import os
import sys
import numpy as np
from os import getcwd
import cv2
import msvcrt
from ctypes import *

sys.path.append("../MvImport")
from MvCameraControl_class import *


# 枚举设备
def enum_devices(device=0, device_way=False):
    """
    device = 0  枚举网口、USB口、未知设备、cameralink 设备
    device = 1 枚举GenTL设备
    """
    if device_way == False:
        if device == 0:
            tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_UNKNOW_DEVICE | MV_1394_DEVICE | MV_CAMERALINK_DEVICE
            deviceList = MV_CC_DEVICE_INFO_LIST()
            # 枚举设备, 若是查找unknown设备会很久
            ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
            if ret != 0:
                print("enum devices fail! ret[0x%x]" % ret)
                sys.exit()
            if deviceList.nDeviceNum == 0:
                print("find no device!"
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值