官网

https://www.hikrobotics.com/cn/machinevision/productdetail?id=1730

MV-CA050-20UC

海康USB相机开发(1)ubuntu18下python转化opencv_mvc

海康USB相机开发(1)ubuntu18下python转化opencv_bash_02

海康USB相机开发(1)ubuntu18下python转化opencv_bash_03

https://www.hikrobotics.com/cn2/source/vision/document/2021/9/7/%E6%B5%B7%E5%BA%B7%E6%9C%BA%E5%99%A8%E4%BA%BAUSB3.0%E5%B7%A5%E4%B8%9A%E9%9D%A2%E9%98%B5%E7%9B%B8%E6%9C%BA%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8CV2.1.0.pdf

海康USB相机开发(1)ubuntu18下python转化opencv_ios_04

海康USB相机开发(1)ubuntu18下python转化opencv_bash_05

2 软件

1. 请从海康机器人官网 www.hikrobotics.com“服务支持”>“下载中心”>“机器视觉” 中下载 MVS 客户端安装包及 SDK 开发包。

https://www.hikrobotics.com/cn/machinevision/service/download?module=0

海康USB相机开发(1)ubuntu18下python转化opencv_bash_06

注意下载linux的最新版本压缩包

海康USB相机开发(1)ubuntu18下python转化opencv_bash_07

下载后解压

linux找到x86的压缩包 解压

海康USB相机开发(1)ubuntu18下python转化opencv_ios_08

打开执行安装脚本

海康USB相机开发(1)ubuntu18下python转化opencv_bash_09

安装命令 step.sh中的内容

从其中看出,被安装在 opt/文件夹下



#!/bin/bash

DIRNAME=`dirname $0`
#PWD = `pwd`

cd $DIRNAME

#sed -i "s/export LD_LIBRARY_PATH/#export LD_LIBRARY_PATH/g" ~/.bashrc
source ~/.bashrc
if [ ! -d "/opt/MVS" ]; then
echo "Install MVS,Please wait..."
tar -C /opt -xzf ./MVS.tar.gz
else
echo "Uninstall MVS,Please wait..."
rm -rf /opt/MVS
echo "Install MVS,Please wait..."
tar -C /opt -xzf ./MVS.tar.gz
fi
#
if [ ! -d "/usr/local/Qt-5.6.3/lib/fonts" ]; then
mkdir -p /usr/local/Qt-5.6.3/lib/fonts
cp -r /opt/MVS/bin/fonts/* /usr/local/Qt-5.6.3/lib/fonts
else
echo "path exist..."
fi
#

#if cat ~/.bashrc | grep -c "export LD_LIBRARY_PATH=/opt/MVS/bin" > /dev/null
#then
# echo "Include path exist"
#else
# echo "export LD_LIBRARY_PATH=/opt/MVS/bin" >> ~/.bashrc
#fi

#source ~/.bashrc

echo "Set up the SDK environment..."

sh $DIRNAME/set_usb_priority.sh
source $DIRNAME/set_env_path.sh
sh $DIRNAME/set_sdk_version.sh

if [ -f /opt/MVS/driver/unload.sh ]; then
sh /opt/MVS/driver/unload.sh
fi

sh /opt/MVS/logserver/RemoveServer.sh


sh /opt/MVS/logserver/InstallServer.sh


echo "Install MVS complete!"
echo "Tips: You should be launch a new terminal or execute source command for the bash environment!"
cd $PWD


打开软件

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_10

sdk文件

安装的时候被解压在 opt/ 文件夹

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_11

打开相机

设备列表会自动显示当前枚举到的设备。也可通过点击 USB 接口处的刷新按钮 , 对设备列表中显示的设备进行手动刷新,如图 2-7 所示。

海康USB相机开发(1)ubuntu18下python转化opencv_数据_12

枚举到设备后,双击连接设备,MVS 客户端主界面如图 2-8 所示。

海康USB相机开发(1)ubuntu18下python转化opencv_bash_13

海康USB相机开发(1)ubuntu18下python转化opencv_数据_14

其他说明

海康USB相机开发(1)ubuntu18下python转化opencv_句柄_15

海康USB相机开发(1)ubuntu18下python转化opencv_数据_16

海康USB相机开发(1)ubuntu18下python转化opencv_ios_17

海康USB相机开发(1)ubuntu18下python转化opencv_ios_18

SDK开发

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_19

开发样例 海康USB相机开发(1)ubuntu18下python转化opencv_mvc_20

海康USB相机开发(1)ubuntu18下python转化opencv_ios_21

说明



工业相机Linux SDK使用说明。Build20180531
===========================================================================
版本号: 2.4.0.5

支持相机:GigE相机和U3V相机

支持系统:ubuntu 14.04(32和64位)、ubuntu 16.04(32和64位)、centos7(32和64位)、
redhat(64位)
===========================================================================

运行环境配置
===========================================================================
在编译示例程序之前,确认LD_LIBRARY_PATH和MVCAM_COMMON_RUNENV两个环境变量已经生效.
eg: echo $LD_LIBRARY_PATH
输出:/opt/MVS/lib/xxx:...

echo $MVCAM_COMMON_RUNENV
输出:/opt/MVS/lib
如果当前环境不存在以上两个环境变量或者变量中不包含/opt/MVS/lib相关值时,需要跳转到安装包所在路径,并输入:
source ./set_env_path.sh
===========================================================================

程序演示
===========================================================================
Display:图像显示例程。
使用前请先安装X11相关库:sudo apt-get install libx11-dev.
创建的显示窗口不支持拉伸。
1. 使用xlib库来创建图像窗口
2. 枚举设备,选择设备并创建句柄,打开设备
3. 开始取流,调用显示函数传入窗口句柄
4. 输入enter结束取流

===========================================================================
ForceIP:设置forceip
1. 枚举设备,选择设备并创建句柄
2. 设置forceip
3. 输入enter结束取流

===========================================================================
Grab_ImageCallback:回调方式抓取图像
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置触发模式为off
3. 开始取流
4. 若有图像数据,ImageCallBackEx会被调用
5. 输入enter结束取流

===========================================================================
GrabImage:主动方式抓取图像
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置触发模式为off
3. 开始取流,开线程用来获取图像数据
4. 若有图像数据,MV_CC_GetOneFrameTimeout会返回MV_OK
5. 输入enter结束取流

===========================================================================
GrabMultipleCamera:多相机取流
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置触发模式为off
3. 开始取流,开线程用来获取图像数据
4. 若有图像数据,MV_CC_GetOneFrameTimeout会返回MV_OK
5. 输入enter结束取流

===========================================================================
ImageProcess:图像处理(存图和像素格式转换)
1. 枚举设备,选择设备并创建句柄,打开设备
2. 开始取流,若有图像数据,MV_CC_GetOneFrameTimeout会返回MV_OK
3. 选择case 0、1或2来进行不同图像处理方式
4. 输入enter结束取流

===========================================================================
ReconnectDemo:重连示例
1. 开线程,用于重连相机,线程中有枚举、创建句柄、打开相机、注册异常回调功能
2. 若有相机异常断线,则会重新枚举相机并连接第0个相机,
3. 输入enter结束程序

===========================================================================
SetIO:设置IO
1. 枚举设备,选择设备并创建句柄,打开设备
2. 获取LineSelector,设置LineSelector
3. 获取LineMode,设置LineMode
4. 输入enter结束程序

===========================================================================
SetParam:设置参数
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置int型变量,获取int型变量
3. 设置float型变量,获取float型变量
4. 设置enum型变量,获取enum型变量
5. 设置bool型变量,获取bool型变量
6. 设置string型变量,获取string型变量
7. 输入enter结束程序

===========================================================================
Trigger_Image:触发方式取流
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置触发模式为on,设置触发源为软触发
3. 开始取流,开线程用来发送触发命令以及获取图像数据
4. 输入enter结束取流

===========================================================================
Trigger_ImageCallback: 触发回调方式取流
1. 枚举设备,选择设备并创建句柄,打开设备
2. 设置触发模式为on,设置触发源为软触发
3. 开始取流,开线程用来发送触发命令
4. 若有图像数据,ImageCallBackEx会被调用
5. 输入enter结束取流

===========================================================================
ConnectSpecCamera: 无枚举连接相机(相当于MVS中的远程连接相机)
1. 填充相机ip、网卡ip
2. 创建句柄,连接相机
3. 开始取流

===========================================================================
Events: 使用相机事件
1. 枚举设备,选择设备并创建句柄,打开设备
2. 开启Event
3. 注册Event事件回调(可注册单个、多个、全部事件)
4. 开启取流,当事件来临时会在回调中响应

===========================================================================
MultiCast: 组播取流
1. 枚举设备,选择设备并创建句柄,打开设备
2. 选择control或monitor模式
3. 输入组播组ip和端口
4. 开始取流(若是m端需c端开启取流命令)

===========================================================================
ParametrizeCamera_FileAccess:
1. 枚举设备,选择设备并创建句柄,打开设备
2. 开线程,使用FileAccess读取相机配置文件
3. 开线程,使用FileAccess将配置文件写入相机


===========================================================================
ParametrizeCamera_LoadAndSave:
需要确保代码编辑器输入的路径为UTF-8编码格式
1. 枚举设备,选择设备并创建句柄,打开设备
2. 将相机属性导出到文件中
3. 从文件中导入相机属性


python开发样例(1) 获取原始视频流-无法opencv显示

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_22

海康USB相机开发(1)ubuntu18下python转化opencv_bash_23

参考其SDK提供的流程图我们可以看出,相机控制分成枚举、打开、参数设置、关闭,销毁句柄五个步骤

海康USB相机开发(1)ubuntu18下python转化opencv_数据_24

python开发样例(2) 获取原始视频流-opencv显示

1设置相机输出像素格式

链接相机-属性树-Image Format Control-pixel format - RGB8

海康USB相机开发(1)ubuntu18下python转化opencv_ios_25

2设置相机分辨率

链接相机-属性树-Image Format Control- width max   height max

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_26

保存

海康USB相机开发(1)ubuntu18下python转化opencv_句柄_27

用户设置保存-执行

海康USB相机开发(1)ubuntu18下python转化opencv_mvc_28

断开相机链接,不然占用导致后续无法程序连接

海康USB相机开发(1)ubuntu18下python转化opencv_数据_29

保险一点重新链接相机,查看默认参数是否为上次保存的。

创建和 执行代码

海康USB相机开发(1)ubuntu18下python转化opencv_ios_30



# -- coding: utf-8 --

import sys
import threading
import os
import termios
import time
import cv2
import numpy as np
from ctypes import *

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

g_bExit = False

img_w=1920
img_h=1080
img_c=3

# 显示图像
def image_show(image):
image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
cv2.imshow('test', image)
k = cv2.waitKey(1) & 0xff




# 源程序-为线程定义一个函数
def work_thread(cam=0, pData=0, nDataSize=0):
stFrameInfo = MV_FRAME_OUT_INFO_EX()
memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))
while True:
ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)
if ret == 0:
print ("get one frame: Width[%d], Height[%d], PixelType[0x%x], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.enPixelType,stFrameInfo.nFrameNum))
else:
print ("no data[0x%x]" % ret)
if g_bExit == True:
break

#opencv转换显示
def work_thread_rgb82bgr(cam=0, pData=0, nDataSize=0):
stFrameInfo = MV_FRAME_OUT_INFO_EX()
memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))
while True:
ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)
if ret == 0:
print ("get one frame: Width[%d], Height[%d], PixelType[0x%x], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.enPixelType,stFrameInfo.nFrameNum))
print('----', stFrameInfo.enPixelType)
#if stFrameInfo.enPixelType=='PixelType_Gvsp_RGB8_Packed':
temp = np.asarray(pData)
temp = temp.reshape((img_h, img_w, img_c))
temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)
cv2.namedWindow("temp", cv2.WINDOW_NORMAL)
cv2.imshow('temp',temp)
cv2.waitKey(1)
#else:
#print("图像输出格式不是BGR8,请先使用MVS软件设置相机默认输出图像格式为BGR8....")
else:
print ("no data[0x%x]" % ret)
if g_bExit == True:
break








def press_any_key_exit():
fd = sys.stdin.fileno()
old_ttyinfo = termios.tcgetattr(fd)
new_ttyinfo = old_ttyinfo[:]
new_ttyinfo[3] &= ~termios.ICANON
new_ttyinfo[3] &= ~termios.ECHO
#sys.stdout.write(msg)
#sys.stdout.flush()
termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo)
try:
os.read(fd, 7)
except:
pass
finally:
termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo)

if __name__ == "__main__":

SDKVersion = MvCamera.MV_CC_GetSDKVersion()
print ("SDKVersion[0x%x]" % SDKVersion)

deviceList = MV_CC_DEVICE_INFO_LIST()
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)

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))
elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
print ("\nu3v device: [%d]" % i)
strModeName = ""
for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
if per == 0:
break
strModeName = strModeName + chr(per)
print ("device model name: %s" % strModeName)

strSerialNumber = ""
for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:
if per == 0:
break
strSerialNumber = strSerialNumber + chr(per)
print ("user serial number: %s" % strSerialNumber)

if sys.version >= '3':
nConnectionNum = input("please input the number of the device to connect:")
else:
nConnectionNum = raw_input("please input the number of the device to connect:")

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)

# 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:Get payload size
stParam = MVCC_INTVALUE()
memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))

ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)
if ret != 0:
print ("get payload size fail! ret[0x%x]" % ret)
sys.exit()
nPayloadSize = stParam.nCurValue

# ch:开始取流 | en:Start grab image
ret = cam.MV_CC_StartGrabbing()
if ret != 0:
print ("start grabbing fail! ret[0x%x]" % ret)
sys.exit()
#将PayloadSize的uint数据转为可供numpy处理的数据,后面就可以用numpy将其转化为numpy数组格式。
data_buf = (c_ubyte * nPayloadSize)()

try:
#有些代码可能会在data_buf前面加上byteref,如果这样做的话,就会将数据转为浮点型,
# 而opencv需要的是整型,会报错,所以这里就不需要转化了
#hThreadHandle = threading.Thread(target=work_thread_rgb82bgr, args=(cam, byref(data_buf), nPayloadSize))
hThreadHandle = threading.Thread(target=work_thread_rgb82bgr, args=(cam, data_buf, nPayloadSize))
hThreadHandle.start()
hThreadHandle.start()
except:
print ("error: unable to start thread")

print ("press a key to stop grabbing.")
press_any_key_exit()

g_bExit = True
hThreadHandle.join()

# ch:停止取流 | en:Stop grab image
ret = cam.MV_CC_StopGrabbing()
if ret != 0:
print ("stop grabbing fail! ret[0x%x]" % ret)
del data_buf
sys.exit()

# ch:关闭设备 | Close device
ret = cam.MV_CC_CloseDevice()
if ret != 0:
print ("close deivce fail! ret[0x%x]" % ret)
del data_buf
sys.exit()

# ch:销毁句柄 | Destroy handle
ret = cam.MV_CC_DestroyHandle()
if ret != 0:
print ("destroy handle fail! ret[0x%x]" % ret)
del data_buf
sys.exit()

del data_buf


注意

0 修改代码中湘囧分辨率



img_w=1920
img_h=1080
img_c=3


1 导入SDK路径

因为需要用到SDK的接口函数,所以需要导入相应的库,官方的路径是这样的,这是因为这个包在程序的同一个文件夹下,所以前面的都可以省略,但我们使用的时候,最好把它的绝对路径给写上,我的路径是这样的,可以参考



sys.path.append("../MvImport") #导入相应SDK的库,实际安装位置绝对路径
#/opt/MVS/Samples/64/Python/MvImport


2 原始数据转化成numpy

data_buf = (c_ubyte * nPayloadSize)()这一句话将PayloadSize的uint数据转为可供numpy处理的数据,后面就可以用numpy将其转化为numpy数组格式。



# ch:开始取流 | en:Start grab image
ret = cam.MV_CC_StartGrabbing()
if ret != 0:
print ("start grabbing fail! ret[0x%x]" % ret)
sys.exit()
#将PayloadSize的uint数据转为可供numpy处理的数据,后面就可以用numpy将其转化为numpy数组格式。
data_buf = (c_ubyte * nPayloadSize)()


3 线程调用



try:
#有些代码可能会在data_buf前面加上byteref,如果这样做的话,就会将数据转为浮点型,
# 而opencv需要的是整型,会报错,所以这里就不需要转化了
#hThreadHandle = threading.Thread(target=work_thread_rgb82bgr, args=(cam, byref(data_buf), nPayloadSize))
hThreadHandle = threading.Thread(target=work_thread_rgb82bgr, args=(cam, data_buf, nPayloadSize))
hThreadHandle.start()