OpenCV调用工业相机
python调用海康工业相机并用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!"

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





