C++下OPENCV驱动调用海康GigE工业相机

这篇具有很好参考价值的文章主要介绍了C++下OPENCV驱动调用海康GigE工业相机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

第一章 Ubuntu22下OpenCV4.6.0+contrib模块编译安装
第二章 ubuntu22下C++ kdevelop环境搭建:OpenCV示例
第三章 C++下OPENCV驱动调用海康GigE工业相机



前言

在前两章内笔者详细叙述了如何编译以及加载opencv库,本文将从opencv出发,在linux系统下利用海康工业摄像机的SDK完成基于海康工业相机的opencv开发算法。
包含:
1.海康工业相机的驱动;
2.工业相机的帧格式转换;

本文代码库:https://gitee.com/C-Qiyao/gig-e_camera


一、海康工业相机

一切缘起笔者在实验室翻箱倒柜喜提一个师兄购买的海康工业 相机,遂对其进行详细了解,发现功能性相比普通摄像头强不少。
产品页面

C++下OPENCV驱动调用海康GigE工业相机

笔者使用的海康工业相机的型号为MV-CE013-50GC,采用rj45的网线接口来输出视频数据,并不会在系统设备上挂载video设备,所以需要调用海康的驱动来完成视频帧的获取。

二、MVS软件安装 摄像头连接

MVS软件是为支持海康机器视觉相机产品而开发的软件应用程序,适用于所有海康机器视觉面阵以及线阵相机产品。MVS内我们主要配置摄像头以及利用他的SDK进行开发。

1.安装MVS

前往HIKROBOT网站下载对应系统的MVS安装包

在此笔者使用的是linux系统所以选择linux系统的安装包进行下载
C++下OPENCV驱动调用海康GigE工业相机

打开下载得到的压缩包,内容如下:

C++下OPENCV驱动调用海康GigE工业相机我们使用的计算机为64位的X86架构,所以在此我们将后缀为x86_64的安装包解压出来,笔者使用的是Debian系的ubuntu操作系统,所以在此解压对应deb安装包。

使用终端或者软件安装器安装该deb包

安装完成之后,读者可能会发现并没有在菜单内找到MVS软件的图标,但是我们可以在/opt路径下找到MVS的文件夹

qiyao@qiyao-Legion-Y9000X-IAH7:/opt$ ls
apps      durapps  ffmpeg-4.3.tar.gz  nvidia   zTools
clion  deepin-wine6-stable  ffmpeg   MVS                qqmusic

进入MVS文件夹,启动MVS软件

$ cd /opt/MVS/bin
$ ./MVS

成功打开MVS界面
C++下OPENCV驱动调用海康GigE工业相机

2.连接配置摄像头

笔者使用的海康摄像头采用rj45接口,查阅手册得知需要使用千兆以太网标准进行连接

C++下OPENCV驱动调用海康GigE工业相机

设置网卡IP 修改有线网卡ipv4参数为以下内容:

IP:	192.168.16.68
网关:	192.168.16.1
DNS:	202.96.128.166
MTU:	9000

重启MVS软件,在设备列表里选中我们的网络摄像机,右键修改IP(在ip段内随意设置)

C++下OPENCV驱动调用海康GigE工业相机

双击选中我们的相机,开启相机采集

C++下OPENCV驱动调用海康GigE工业相机
至此,相机和计算机之间的连接以及完成,接下来就需要进行SDK的开发了,同时我们在画面下部的带宽部分也可以发现,该相机的数据流巨大,确实需要依赖千兆网络的支撑。

三、基于SDK的摄像头C++开发

1.拷贝SDK

笔者比较习惯kdevelop的开发,当然也建议读者选择自己钟意的IDE进行软件的开发,毕竟代码才是核心,工具次之,对于狠人用文本编辑器也未尝不可。

拷贝/opt/MVS目录下的 include和lib文件夹到我们的项目文件夹内,与main.cpp同级

2.编辑cmakelist

本次项目我们需要使用到海康摄像头SDK以及opencv库,笔者在此提供自己的cmakelist

# cmake needs this line
cmake_minimum_required(VERSION 3.1)
set(PROJECT_NAME1 "camera_class_project")
# Define project name
#set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_BUILD_TYPE "Release")
set(PROJ_DIR "/home/qiyao/codes/camera_class")
#s设置自己的项目文件夹目录,用以定位文件夹下的include'和lib

project(${PROJECT_NAME1})
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
message(STATUS "OpenCV library status:")
message(STATUS "    config: ${OpenCV_DIR}")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

link_directories("${PROJ_DIR}/lib/64")
include_directories("${PROJ_DIR}/include" "/usr/include/X11" "/usr/include")
link_libraries("${PROJ_DIR}/lib/64/libMvCameraControl.so")
add_compile_options(-std=c++11)
add_executable(${PROJECT_NAME1} main.cpp)
add_library(camera_class SHARED camera_class.cpp)
#target_link_libraries(${PROJECT_NAME1} PUBLIC )

# Link your application with OpenCV libraries
target_link_libraries(${PROJECT_NAME1} ${OpenCV_LIBS} )
target_link_libraries(${PROJECT_NAME1}  -lX11)
target_link_libraries(${PROJECT_NAME1} libMvCameraControl.so)
target_link_libraries(${PROJECT_NAME1} camera_class)

3.编辑相机class

笔者将自己对相机的操作编写成了一个class类,方便自己的调用,读者可以进行参考

camera_class.h

#ifndef CAMERA_CLASS_H_INCLUDED
#define CAMERA_CLASS_H_INCLUDED
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "MvCameraControl.h"
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/video/video.hpp>
using namespace std;
using namespace cv;

class camera{
private:
    void* handle;
    bool g_bExit;
    int nRet;
    unsigned int g_nPayloadSize;
    unsigned char *pDataForRGB;
    MV_CC_DEVICE_INFO* pDeviceInfo;
    MV_CC_DEVICE_INFO_LIST stDeviceList;
    MVCC_INTVALUE stParam;
    MV_FRAME_OUT stOutFrame;
    MV_CC_PIXEL_CONVERT_PARAM CvtParam;
public:
    camera();
    void PrintDeviceInfo();
    void close_cam();
    void start_cam();
    void get_pic(Mat * srcimg);
    void re_iso();
};
#endif // CAMERA_CLASS_H_INCLUDED

camera_class.cpp

#include "camera_class.h"
camera::camera()
{
    nRet = MV_OK;
    handle = NULL;
    g_bExit = false;
    g_nPayloadSize = 0;
    pDataForRGB  = (unsigned char*)malloc(1280 *960 * 4 + 2048);
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    CvtParam={0};
    stOutFrame = {0};
    memset(&stOutFrame, 0, sizeof(MV_FRAME_OUT));
}
void camera::start_cam()
{

    memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
    nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);
    if (stDeviceList.nDeviceNum > 0)
    {
        for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
        {
            pDeviceInfo = stDeviceList.pDeviceInfo[i];
            if (NULL == pDeviceInfo)
            {
                break;
            }
            PrintDeviceInfo();
        }
    }else{
        cout<<"Find no Device"<<endl;
    }
    unsigned int nIndex = 0;
    MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);
    MV_CC_OpenDevice(handle);
    if (stDeviceList.pDeviceInfo[nIndex]->nTLayerType == MV_GIGE_DEVICE)
    {
        int nPacketSize = MV_CC_GetOptimalPacketSize(handle);
        if (nPacketSize > 0)
        {
            MV_CC_SetIntValue(handle,"GevSCPSPacketSize",nPacketSize);
        }else{
            cout<<"Warning: Get Packet Size fail"<<endl;
        }
    }
    MVCC_ENUMVALUE  p={0};
    MVCC_STRINGVALUE st;
    MV_CC_GetStringValue(handle,"DeviceModelName",&st);
    cout<<"DeviceModelName: "<<st.chCurValue<<endl;
    MV_CC_GetStringValue(handle,"DeviceVersion",&st);
    cout<<"DeviceVersion:\t"<<st.chCurValue<<endl;
    MV_CC_GetEnumValue(handle,"DeviceScanType",&p);
    if(p.nCurValue==0)
    {
        cout<<"DeviceScanType:\t"<<"Areascan"<<endl;

    }else{
        cout<<"DeviceScanType:\t"<<"Linescan"<<endl;
    }
    MV_CC_SetEnumValue(handle, "TriggerMode", 0);
    MV_CC_SetEnumValue(handle, "PixelFormat", 0x0210001F);
    MV_CC_SetEnumValue(handle, "GainAuto", 1);
    MV_CC_SetFloatValue(handle, "Gamma", 0.8);
    MV_CC_SetBoolValue(handle, "GammaEnable", 1);
    MV_CC_SetEnumValue(handle, "BalanceWhiteAuto", 2);
    MV_CC_SetEnumValue(handle, "ExposureAuto", 1);
    MV_CC_GetIntValue(handle, "PayloadSize", &stParam);
    g_nPayloadSize = stParam.nCurValue;
    nRet = MV_CC_StartGrabbing(handle);
    if (MV_OK == nRet)
        cout<<"Start Grabbing !"<<endl;
    cout<<"\nPress ESC to exit.\n";
}
void camera::PrintDeviceInfo()
{
    if (NULL == pDeviceInfo)
    {
        cout<<"null point"<<endl;
    }
    if (pDeviceInfo->nTLayerType == MV_GIGE_DEVICE)
    {
        int nIp1 = ((pDeviceInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);
        int nIp2 = ((pDeviceInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);
        int nIp3 = ((pDeviceInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);
        int nIp4 = (pDeviceInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
        cout<<"IP:"<<nIp1<<"."<<nIp2<<"."<<nIp3<<"."<<nIp4<<endl;
    }
}
void camera::close_cam()
{
    int nRet = MV_CC_StopGrabbing(handle);
    if (MV_OK == nRet)
        cout<<"Stopped Grabbing !"<<endl;
}
void camera::get_pic(cv::Mat* srcimg)
{
    MV_CC_GetImageBuffer(handle, &stOutFrame, 400);
    CvtParam.enSrcPixelType=stOutFrame.stFrameInfo.enPixelType;
    CvtParam.enDstPixelType=PixelType_Gvsp_RGB8_Packed;
    CvtParam.nHeight=stOutFrame.stFrameInfo.nHeight;
    CvtParam.nWidth=stOutFrame.stFrameInfo.nWidth;
    CvtParam.nDstBufferSize=stOutFrame.stFrameInfo.nWidth * stOutFrame.stFrameInfo.nHeight *  4 + 2048;
    CvtParam.pSrcData=stOutFrame.pBufAddr;
    CvtParam.pDstBuffer=pDataForRGB;
    CvtParam.nSrcDataLen=stOutFrame.stFrameInfo.nFrameLen;
    MV_CC_ConvertPixelType(handle,&CvtParam);
    *srcimg=Mat(stOutFrame.stFrameInfo.nHeight,stOutFrame.stFrameInfo.nWidth,CV_8UC3,pDataForRGB);
    cvtColor(*srcimg,*srcimg,COLOR_RGB2BGR);
    if(NULL != stOutFrame.pBufAddr)
    {
        MV_CC_FreeImageBuffer(handle, &stOutFrame);
    }
}
void camera::re_iso()
{
    MV_CC_SetEnumValue(handle, "BalanceWhiteAuto", 2);
    MV_CC_SetEnumValue(handle, "ExposureAuto", 1);
}


4.主函数调用

main.cpp

#include <stdio.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/video/video.hpp>
#include <opencv2/opencv.hpp>
#include "camera_class.h"

int main()
{
    Mat img;
    int key;
    camera cam;
    cam.start_cam();
    while(1)
    {
        cam.get_pic(&img);
        imshow("test",img);
        key=waitKey(1);
        if(key==27)
        {
            cam.close_cam();
            break;
        }

    }
}

可谓非常的简洁优雅

四、测试验证

构建编译测试工程
达到预期目标,成功驱动摄像机

C++下OPENCV驱动调用海康GigE工业相机


总结

以上就是今天要讲的内容,本文介绍了linux下海康GigE相机在opencv下的使用,同时在代码类里包括了相机参数调整和帧格式的转换操作,笔者有空再进行详细地阐述。文章来源地址https://www.toymoban.com/news/detail-455746.html

到了这里,关于C++下OPENCV驱动调用海康GigE工业相机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • C# 开源SDK 工业相机库 调用海康相机 大恒相机

    C# 开源SDK 工业相机库 调用海康相机 大恒相机

    c# 相机库,含海康、大恒品牌2D相机的常用功能。 底层采用回调+信号量模式封装 ,最大程度减小线程资源,提高采图效率。 开源地址 :https://gitee.com/laomaogu/mgcamctrl 现只兼容了大恒和海康,都是常用的 其他相机,看我老板啥时候换品牌吧,或者换老板? 当然如果小伙伴感兴

    2024年04月26日
    浏览(59)
  • Python 调用海康机器人工业相机

    Python 调用海康机器人工业相机

    一、前期准备 1、python环境搭建 2、安装MVS软件 3、网上博客参考 1)RTSP(Runtime Stream Protocol)协议方向 (很遗憾,此路不通!!!) 因为我们用的 海康机器人工业相机 MV-CU060-10GM 这款相机,不支持 RTSP 协议。 如下博客适用于 海康威视摄像头,并不适用于 海康工业相机,如

    2024年02月16日
    浏览(7)
  • opencv——连接/控制工业相机(海康)

    1.自动抓取图像 通过接受前步传输的指令而实现相机的自动抓取图像 2.定时抓取图像 通过自定义设置延时时间而实现相机的定时抓取图像 3.特定按键控制抓取图像 通过自定义特定按键而实现相机的人为控制抓取图像 以上就是三种实现Python/opencv工业相机控制的方法啦!

    2024年02月12日
    浏览(14)
  • Qt+opencv+Linux+海康工业相机连接

    Qt+opencv+Linux+海康工业相机连接

           本人需要在树莓派上部署深度学习推理模型 ,由于本实验室只有海康工业相机,因此通过借鉴博客和自主调试,完成了模型的部署。本文主要讲述如何在基于linux的Qt中成功连接海康工业相机,第一次尝试写博客,练练手感。       1、安装海康工业相机自带的MVS  

    2024年02月01日
    浏览(11)
  • 海康工业相机SDK + OpenCV实例(4):相机参数设置详解

    前文海康工业相机SDK + OpenCV实例(3):相机初始化Bug调试讲述了相机初始化可能遇到的问题。本文讲解海康工业相机设置参数的相关接口,其中,会重点讲解 自动曝光时间调整亮度 , 图像对比度调整 。 海康SDK提供一系列参数设置的接口,本节主要讲解几个万能接口的使用,

    2024年02月11日
    浏览(235)
  • opencv调用海康威视工业摄像头

    opencv调用海康威视工业摄像头

    opencv调用海康威视工业摄像头需要用到官方接口VideoCapture() 接口:cv2.VideoCapture() 作用:获取本地目录下的视频文件或者使用本电脑的摄像头获取实时数据;  “0” ,调用的是本地电脑摄像头 “1” ,调用的是外接摄像头 打开MVS  正常设置使画面正常  然后找到宽度和长度

    2024年02月13日
    浏览(14)
  • Matlab 打开 Gige 工业相机连续采集数据 & Bug解决

    Matlab 打开 Gige 工业相机连续采集数据 & Bug解决

    电脑配置:Windows 10;Matlab 2021b 相机型号:DMK 33GP1300 官网链接:https://www.theimagingsource.com/zh-hans-cn/product/industrial/33g/dmk33gp1300/ 按照默认路径安装,安装好后界面: 测试相机,仍在官网找到图中软件,安装好后测试: 打开 Matlab,从附加功能进入: 打开后,搜索并安装 GigE Vis

    2024年02月12日
    浏览(11)
  • 【项目实践】海康威视工业相机SDK开发小白版入门教程(VS2015+OpenCV4.5.1)

    【项目实践】海康威视工业相机SDK开发小白版入门教程(VS2015+OpenCV4.5.1)

      由于学校要求暑期实习,于是找了一位学长开的公司,接了一个项目,是 对海康威视工业相机(MV_CE200_10GM)进行二次开发,读取其图像并做分析处理。 于是花了一点时间查找的相关资料并记录一些 入门要点 。   想先说说一些 “尝试授人与渔” 的话,也是自己的一

    2024年02月04日
    浏览(13)
  • Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C++)

    Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C++)

    ​ Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度

    2024年01月20日
    浏览(11)
  • Baumer工业相机堡盟工业相机如何使用BGAPISDK和OpenCV设置图像进行比例显示(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩

    2024年02月10日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包