当前位置: 首页 > news >正文

海康相机---采集图像

理论知识

一、环境准备

1. 系统要求

Linux,Windows,Mac都可,由于linux的工业应用普遍性,在此用Linux为例讲解。

2. 硬件连接
  • USB相机:通过USB3.0线缆连接相机,确保供电充足(建议使用有源USB hub)。
  • GigE相机
    • 配置相机IP:使用海康官方工具(如MVS Linux版)或ifconfig设置电脑IP与相机同网段(默认相机IP为192.168.1.60)。
    • 安装libpcap库:用于网络通信,执行sudo apt-get install libpcap-dev(Ubuntu)或sudo yum install libpcap-devel(CentOS)。
3. 依赖库安装
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y libusb-1.0-0-dev libudev-dev libopencv-dev# CentOS/RHEL
sudo yum install -y libusb-devel libudev-devel opencv-devel

二、SDK下载与安装

1. 获取SDK
  • 访问海康威视机器视觉官网,下载对应版本的Linux MVSDK(区分32位/64位,工业相机SDK包名通常为Hikvision_MV_SDK_Linux_x86_64_Vx.x.x.tar.gz)。
2. 解压与配置
tar -zxvf Hikvision_MV_SDK_Linux_x86_64_Vx.x.x.tar.gz -C /usr/local/hikvision_mvsdk
cd /usr/local/hikvision_mvsdk
  • 目录结构
    • include/:头文件(MvCameraControl.h为核心接口)。
    • lib/:动态链接库(libMvCameraControl.so为核心库)。
    • samples/:示例代码(C++/Python)。
3. 添加库路径
# 临时生效(当前终端)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/hikvision_mvsdk/lib# 永久生效(全局)
sudo sh -c 'echo "/usr/local/hikvision_mvsdk/lib" >> /etc/ld.so.conf.d/hikvision.conf'
sudo ldconfig

三、权限配置

1. USB相机权限
# 创建udev规则
sudo tee /etc/udev/rules.d/51-hikvision-camera.rules <<EOF
SUBSYSTEM=="usb", ATTRS{idVendor}=="0408", MODE="0666", GROUP="plugdev"
EOF
sudo udevadm control --reload-rules && sudo udevadm trigger
# 将当前用户加入plugdev组
sudo usermod -aG plugdev $USER
newgrp plugdev  # 重新登录后生效
2. GigE相机权限
# 允许非root用户访问网络设备(需谨慎)
sudo setcap cap_net_raw,cap_net_admin+eip $(which your_program)

四、核心API流程与代码示例

1. 关键API调用流程

在这里插入图片描述

2. C++示例代码(同步采集单张图像)
#include <iostream>
#include "MvCameraControl.h"using namespace std;int main() {// 1. 初始化SDKMV_CC_InitSDK();// 2. 枚举设备MV_CC_DEVICE_INFO_LIST stDeviceList;int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (nRet != MV_OK) {cerr << "枚举设备失败, 错误码: " << nRet << endl;return -1;}if (stDeviceList.nDeviceNum == 0) {cerr << "未发现设备" << endl;return -1;}// 3. 创建句柄并打开设备(以第一个设备为例)MV_CC_HANDLE hDevice;nRet = MV_CC_CreateHandle(&hDevice, stDeviceList.pDeviceInfo[0]);if (nRet != MV_OK) {cerr << "创建设备句柄失败, 错误码: " << nRet << endl;return -1;}nRet = MV_CC_OpenDevice(hDevice);if (nRet != MV_OK) {cerr << "打开设备失败, 错误码: " << nRet << endl;MV_CC_DestroyHandle(hDevice);return -1;}// 4. 配置参数(示例:设置自动曝光)MV_EXPOSURE_MODE_TYPE eExpMode = MV_EXPOSURE_MODE_AUTO;nRet = MV_CC_SetEnumValue(hDevice, "ExposureMode", eExpMode);if (nRet != MV_OK) {cerr << "设置曝光模式失败, 错误码: " << nRet << endl;}// 5. 开始抓图nRet = MV_CC_StartGrabbing(hDevice);if (nRet != MV_OK) {cerr << "开始抓图失败, 错误码: " << nRet << endl;MV_CC_CloseDevice(hDevice);MV_CC_DestroyHandle(hDevice);return -1;}// 6. 同步获取图像(超时时间1000ms)MV_FRAME_OUT_INFO_EX stFrameInfo = {0};unsigned char* pData = nullptr;nRet = MV_CC_GetImageBuffer(hDevice, &pData, &stFrameInfo, 1000);if (nRet == MV_OK && stFrameInfo.nFrameStatus == MV_FRAME_STATUS_SUCCESS) {cout << "获取图像成功, 宽度: " << stFrameInfo.nWidth << ", 高度: " << stFrameInfo.nHeight << ", 像素格式: " << stFrameInfo.enPixelType << endl;// 7. 示例:转换为BGR格式(需OpenCV支持)if (stFrameInfo.enPixelType == PixelType_Gvsp_Mono8) {cv::Mat img(stFrameInfo.nHeight, stFrameInfo.nWidth, CV_8UC1, pData);cv::imwrite("capture.jpg", img);cout << "图像已保存为capture.jpg" << endl;}} else {cerr << "获取图像失败, 错误码: " << nRet << endl;}// 8. 停止抓图并释放资源MV_CC_StopGrabbing(hDevice);MV_CC_CloseDevice(hDevice);MV_CC_DestroyHandle(hDevice);MV_CC_UnInitSDK();return 0;
}
3. 编译命令(使用GCC)
g++ -o capture capture.cpp -I/usr/local/hikvision_mvsdk/include \
-L/usr/local/hikvision_mvsdk/lib -lMvCameraControl -lpthread -ldl -lopencv_core -lopencv_highgui

五、参数配置与高级功能

1. 常用参数设置
参数名称接口函数示例代码
分辨率MV_CC_SetEnumValueMV_CC_SetEnumValue(hDevice, "Width", 1920);
帧率限制MV_CC_SetFloatValueMV_CC_SetFloatValue(hDevice, "AcquisitionFrameRate", 30.0);
手动曝光时间MV_CC_SetFloatValueMV_CC_SetFloatValue(hDevice, "ExposureTime", 10000.0);(单位:μs)
增益MV_CC_SetIntValueMV_CC_SetIntValue(hDevice, "Gain", 10);
ROI区域MV_CC_SetStructValueMV_Roi roi = {x, y, width, height}; MV_CC_SetStructValue(hDevice, "Roi", &roi);
触发模式(软触发)MV_CC_SetEnumValue + MV_CC_SoftTriggerMV_CC_SetEnumValue(hDevice, "TriggerMode", MV_TRIGGER_MODE_ON);
MV_CC_SoftTrigger(hDevice);
2. 图像格式转换
// 将RAW格式转换为BGR(以Mono8转BGR为例)
MV_PIXEL_CONVERT_PARAM stConvertParam = {0};
stConvertParam.nWidth = stFrameInfo.nWidth;
stConvertParam.nHeight = stFrameInfo.nHeight;
stConvertParam.pSrcData = pData;
stConvertParam.nSrcDataLen = stFrameInfo.nFrameLen;
stConvertParam.enSrcPixelType = stFrameInfo.enPixelType;
stConvertParam.enDstPixelType = PixelType_BGR8;
unsigned char* pConvertData = new unsigned char[stFrameInfo.nWidth * stFrameInfo.nHeight * 3];
stConvertParam.pDstData = pConvertData;
nRet = MV_CC_ConvertPixelType(hDevice, &stConvertParam);
if (nRet == MV_OK) {// 使用pConvertData创建OpenCV图像cv::Mat bgrImg(stFrameInfo.nHeight, stFrameInfo.nWidth, CV_8UC3, pConvertData);
}
delete[] pConvertData;

六、多相机并发采集

1. 线程安全方案
  • 为每个相机创建独立线程,避免句柄竞争。
  • 使用互斥锁保护全局资源(如日志输出)。
#include <thread>
#include <mutex>std::mutex mtx;void CaptureThread(MV_CC_HANDLE hDevice) {mtx.lock();MV_CC_StartGrabbing(hDevice);mtx.unlock();// 线程内采集逻辑...mtx.lock();MV_CC_StopGrabbing(hDevice);mtx.unlock();
}int main() {// 枚举所有设备并创建设备句柄...std::vector<MV_CC_HANDLE> handles = {hDevice1, hDevice2};std::vector<std::thread> threads;for (auto& h : handles) {threads.emplace_back(CaptureThread, h);}for (auto& t : threads) {t.join();}return 0;
}

七、常见问题与解决方案

1. 设备枚举失败
  • 原因:USB权限不足或GigE相机IP未配置。
  • 解决
    • 重新加载udev规则并重启电脑。
    • 使用ifconfig确认电脑IP与相机同网段(GigE相机)。
    • 检查相机电源与线缆连接。
2. 图像采集异常(花屏/丢帧)
  • 原因:传输带宽不足或缓冲区设置过小。
  • 解决
    • USB相机:确保使用USB3.0接口,调整TransferBufferNumber参数(默认8,可增大至16)。
    • GigE相机:启用PacketSize自动协商,执行sudo ethtool -K eth0 gso off关闭GSO功能。
3. 动态库找不到
  • 原因LD_LIBRARY_PATH未正确配置。
  • 解决
    • 执行echo $LD_LIBRARY_PATH确认路径包含SDK的lib目录。
    • 重新运行sudo ldconfig更新系统库缓存。
4. 触发模式不生效
  • 原因:触发参数未正确配置或触发源错误。
  • 解决
    • 确保触发模式设置为MV_TRIGGER_MODE_ON,触发源设置为MV_TRIGGER_SOURCE_SOFTWARE(软触发)或硬件触发源。
    • 调用MV_CC_SoftTrigger触发采集(软触发场景)。

八、性能优化建议

  1. 缓冲区管理

    • 增大GrabBufferNumber(默认3,可设为5-10)以减少丢帧。
    • 使用异步采集接口MV_CC_RegisterImageCallBackEx提升吞吐量。
  2. 网络优化(GigE相机)

    • 设置相机GevSCPSPacketSize为最大值(通常9000,需交换机支持Jumbo Frame)。
    • 禁用相机GevTimestampEnable以降低CPU占用。
  3. 预处理优化

    • MV_FRAME_OUT_INFO_EX中判断nFrameStatus,跳过无效帧(如MV_FRAME_STATUS_TIMEOUT)。
    • 直接使用原始像素数据(如Mono8),避免不必要的格式转换。

九、官方资源与支持

  • 开发文档/usr/local/hikvision_mvsdk/doc/MV_SDK_Programming_Guide.pdf
  • 示例代码samples/C++/MvSampleGrabImage(同步采集)、samples/C++/MvSampleGrabImageAsync(异步采集)
  • 技术支持:海康威视机器视觉技术支持邮箱(mv_support@hikvision.com)或官网工单系统。

通过以上步骤,可全面掌握Linux下使用海康MVSDK进行图像采集的核心流程与高级功能,覆盖设备控制、参数调优、多线程开发及问题排查等关键知识点。实际开发中建议结合官方文档与调试工具(如strace跟踪系统调用)进行深度优化。

示例

完整的用Cmake架构,调用Hik相机的代码示例:

//main.cpp
#include "MvCameraControl.h"#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 创建设备列表MV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));// 枚举设备int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (nRet != MV_OK || stDeviceList.nDeviceNum == 0) {std::cout << "No devices found!" << std::endl;return -1;}// 创建句柄并打开设备void* handle = nullptr;nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[0]);if (nRet != MV_OK) {std::cout << "Create handle failed!" << std::endl;return -1;}nRet = MV_CC_OpenDevice(handle);if (nRet != MV_OK) {std::cout << "Open device failed!" << std::endl;return -1;}// 开始采集nRet = MV_CC_StartGrabbing(handle);if (nRet != MV_OK) {std::cout << "Start grabbing failed!" << std::endl;return -1;}// 获取图像MV_FRAME_OUT_INFO_EX stImageInfo = {0};unsigned char* pData = (unsigned char*)malloc(1920 * 1080 * 3); // 假设最大分辨率为 1920x1080while (true) {nRet = MV_CC_GetOneFrameTimeout(handle, pData, 1920 * 1080 * 3, &stImageInfo, 1000);if (nRet == MV_OK) {// 转换为 OpenCV 格式cv::Mat img(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3, pData);cv::imshow("Image", img);if (cv::waitKey(1) == 27) break; // 按 ESC 退出}}// 停止采集并释放资源MV_CC_StopGrabbing(handle);MV_CC_CloseDevice(handle);MV_CC_DestroyHandle(handle);free(pData);return 0;
}
cmake_minimum_required(VERSION 3.15)
project(HikTest)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)# 查找 OpenCV 库
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})# 包含海康相机 SDK 的头文件目录
include_directories(/opt/MVS/include)  # 请替换为实际的海康 SDK 头文件目录
link_directories(/opt/MVS/lib/64)# 添加可执行文件
add_executable(hik_test hik_test.cpp)# 链接 OpenCV 库
target_link_libraries(hik_test ${OpenCV_LIBS})target_link_libraries(hik_test MvCameraControl)
http://www.xdnf.cn/news/588997.html

相关文章:

  • 如何解决鸿蒙应用闪退问题
  • Flutter 3.32 新特性
  • 鸿蒙Flutter实战:21-混合开发详解-1-概述
  • flutter getx路由管理、状态管理、路由守卫中间件、永久储存get_storage
  • 汇川EasyPLC MODBUS-RTU通信配置和编程实现
  • S7-1500PLC通过工艺对象实现V90总线伺服定位控制(105报文)
  • 英伟达有意入股 PsiQuantum,释放战略转向量子计算的重要信号
  • JVM常量池(class文件常量池,运行时常量池,字符串常量池)
  • Mysql数据库之索引与事务
  • 【内部教程】ISOLAR-AB配置以太网栈|超详细实战版
  • Kotlin与Flutter:跨平台开发的互补之道与实战指南
  • Armadillo C++ 线性代数库介绍与使用
  • Kotlin 极简小抄 P10(类与对象、主构造函数、带有默认参数值的主构造函数、次要构造函数)
  • 【机器学习】集成学习算法及实现过程
  • Ubuntu20.04的安装(VMware)
  • 详解受约束的强化学习(四、数学符号说明)
  • PL/Python数据库: PostgreSQL Python扩展
  • Argo CD 详解:从 GitOps 到持续交付的完整实践
  • 关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别
  • 相机标定与图像处理涉及的核心坐标系
  • 2. PyQGIS Windows下开发环境搭建
  • Java——集合类
  • 【Android】屏幕适配小合集
  • 基于python,html,echart,php,mysql,在线实时监控入侵检测系统
  • 六一儿童节礼物清单|雷克赛恩 CyberPro1 打造亲子光影盛宴
  • OptiStruct结构分析与工程应用:结构激励
  • 线程安全问题
  • 100个Linux运维知识
  • Cursor远程连接+工具使用
  • VSCode查询