这里写自定义目录标题

  • QT+opencv调用海康工业相机
    • 开发环境
    • 引用海康开发文件
    • 直接上代码

QT+opencv调用海康工业相机

最近在使用Opencv调用海康工业相机的程序,从网上查了好多资料,也走了不少弯路,在这里分享下,希望大家少走弯路!

开发环境

QT5.14.2 +MSVC2017 64bit + opencv4.5

引用海康开发文件

这里就不多少了 网上有好多,可以参考 记得工程文件添加引用路径
opencv


```cpp
INCLUDEPATH += D:/Environment/opencv/build/include\D:/Environment/opencv/build/include/opencv2
LIBS += D:/Environment/opencv/build/x64/vc15/lib/opencv_world451d.lib

海康

INCLUDEPATH += $$PWD/includes
LIBS += $$PWD/libs/MvCameraControl.lib\

直接上代码

界面

头文件

#include <QMainWindow>
#include <MvCameraControl.h>
#include <opencv2/opencv.hpp>
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();public://公共函数void EnumDevice();//设备枚举void ConnectDevice();//连接设备void SetTriggerMode();//设置触发模式void GrabImage();//开始取流//RGB转BGRint RGB2BGR( unsigned char* pRgbData, unsigned int nWidth, unsigned int nHeight );//图片格式转Mat类型并返回Matcv::Mat Convert2Mat(MV_FRAME_OUT_INFO_EX* pstImageInfo, unsigned char * pData);private slots://按键槽函数void on_pushButton_seachDevice_clicked();void on_pushButton_grabImage_clicked();void on_pushButton_stopGrab_clicked();private slots:// 自定义槽函数void GetImage();//获取图像private://全局对象MV_CC_DEVICE_INFO_LIST stDeviceList;//实例化设备列表int nRet;//定义返回接收值void* handle;//实例化设备句柄unsigned char * pData;//图像信息unsigned int g_nPayloadSize;//图像尺寸mat_to_img MatToImage;//Mat转ImageQTimer * timer;//创建定时器MV_FRAME_OUT_INFO_EX stImageInfo;private:Ui::MainWindow *ui;
};

CPP文件

#include "Mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <Windows.h>#ifdef WIN32
#pragma execution_character_set("utf-8")//解决QT VC中文乱码
#endifMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);/*初始化对象↓*/nRet = MV_OK;handle = NULL;g_nPayloadSize = 0;stImageInfo = {0};/*↑初始化对象*/}MainWindow::~MainWindow()
{timer->stop();delete ui;delete timer;}void MainWindow::EnumDevice()//枚举设备
{memset(&stDeviceList,0,sizeof(MV_CC_DEVICE_INFO_LIST));//开辟空间nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE,&stDeviceList);//枚举设备并返回信息进行判断if(nRet != MV_OK){QString text = QString("枚举设备失败!nRet [0x%1]").arg(nRet);QMessageBox::warning(this,"警告",text);return;}if(stDeviceList.nDeviceNum > 0){for (unsigned int i = 0;i < stDeviceList.nDeviceNum;i++){MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];if(pDeviceInfo == NULL){continue;}wchar_t* pUserName = NULL;if(pDeviceInfo->nTLayerType == MV_GIGE_DEVICE){int nIp1 = ((stDeviceList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);int nIp2 = ((stDeviceList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);int nIp3 = ((stDeviceList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);int nIp4 = (stDeviceList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);if(std::strcmp("",(LPCSTR)(pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName)) != 0){DWORD dwLenUserName = MultiByteToWideChar(CP_ACP,0,(LPCSTR)(pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName),-1,NULL,0);pUserName = new wchar_t[dwLenUserName];MultiByteToWideChar(CP_ACP,0,(LPCSTR)(pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName),-1,pUserName,dwLenUserName);}else{DWORD dwLenUserName = MultiByteToWideChar(CP_ACP,0,(LPCSTR)(pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName),-1,NULL,0);pUserName = new wchar_t[dwLenUserName];MultiByteToWideChar(CP_ACP,0,(LPCSTR)(pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName),-1,pUserName,dwLenUserName);}QString text = QString("[%1]Gige:%2(%3.%4.%5.%6)").arg(i).arg(pUserName).arg(nIp1).arg(nIp2).arg(nIp3).arg(nIp4);ui->comboBox_DeviceList->addItem(text);}else{QMessageBox::warning(this,"警告","未知设备");QString text = QString("未知设备[%1]").arg(i);ui->comboBox_DeviceList->addItem(text);}if(pUserName){delete [] pUserName;pUserName = NULL;}}}if(stDeviceList.nDeviceNum == 0){QMessageBox::warning(this,"警告","未发现设备");return;}
}void MainWindow::ConnectDevice()//连接设备并打开
{//创建设备句柄unsigned int nIndex = ui->comboBox_DeviceList->currentIndex();nRet = MV_CC_CreateHandle(&handle,stDeviceList.pDeviceInfo[nIndex]);if(nRet != MV_OK){QString text = QString("创建设备失败!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);return;}//打开设备nRet = MV_CC_OpenDevice(handle);if(nRet != MV_OK){QString text = QString("打开设备失败!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);return;}// 检测网络最近封装尺寸(仅支持 GigE camera)if (stDeviceList.pDeviceInfo[nIndex]->nTLayerType == MV_GIGE_DEVICE){int nPacketSize = MV_CC_GetOptimalPacketSize(handle);if (nPacketSize > 0){nRet = MV_CC_SetIntValue(handle,"GevSCPSPacketSize",nPacketSize);if(nRet != MV_OK){QString text = QString("设置封装尺寸失败!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);}}else{QString text = QString("获取封装尺寸失败!nRet [%1]").arg(nPacketSize);QMessageBox::warning(this,"警告",text);}}}void MainWindow::SetTriggerMode()//设置触发模式
{nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 0);if (MV_OK != nRet){printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);QString text = QString("设置触发模式失败!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);return;}
}void MainWindow::GrabImage()//开始取流
{//获取playload尺寸MVCC_INTVALUE stParam;memset(&stParam, 0, sizeof(MVCC_INTVALUE));nRet = MV_CC_GetIntValue(handle, "PayloadSize", &stParam);if (MV_OK != nRet){QString text = QString("获取playlord失败!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);return;}g_nPayloadSize = stParam.nCurValue;//开始取流nRet = MV_CC_StartGrabbing(handle);if(nRet != MV_OK){printf("Start Grabbing fail! nRet [0x%x]\n", nRet);
//        QString text = QString("取流失败!nRet [0x%1]").arg(nRet);
//        QMessageBox::warning(this,"警告",text);return;}
//    MV_FRAME_OUT_INFO_EX stImageInfo = {0};memset(&stImageInfo,0,sizeof (MV_FRAME_OUT_INFO_EX));pData = (unsigned char*)malloc(sizeof (unsigned char)* (g_nPayloadSize));if (pData == NULL){QMessageBox::warning(this,"警告","分配内容失败!");return;}// 获取一张图片get one frame from camera with timeout=1000msnRet = MV_CC_GetOneFrameTimeout(handle, pData, g_nPayloadSize, &stImageInfo, 1000);if (nRet == MV_OK){printf("Get One Frame: Width[%d], Height[%d], nFrameNum[%d]\n",stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);}else{QString text = QString("无图像数据!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);free(pData);pData = NULL;return;}
}int MainWindow::RGB2BGR(unsigned char *pRgbData, unsigned int nWidth, unsigned int nHeight)//RGB转BGR
{if ( NULL == pRgbData ){return MV_E_PARAMETER;}for (unsigned int j = 0; j < nHeight; j++){for (unsigned int i = 0; i < nWidth; i++){unsigned char red = pRgbData[j * (nWidth * 3) + i * 3];pRgbData[j * (nWidth * 3) + i * 3]     = pRgbData[j * (nWidth * 3) + i * 3 + 2];pRgbData[j * (nWidth * 3) + i * 3 + 2] = red;}}return MV_OK;
}cv::Mat MainWindow::Convert2Mat(MV_FRAME_OUT_INFO_EX *pstImageInfo, unsigned char *pData)//转Mat格式
{cv::Mat srcImage;if ( pstImageInfo->enPixelType == PixelType_Gvsp_Mono8 ){srcImage = cv::Mat(pstImageInfo->nHeight, pstImageInfo->nWidth, CV_8UC1, pData);return srcImage;}else if ( pstImageInfo->enPixelType == PixelType_Gvsp_RGB8_Packed ){RGB2BGR(pData, pstImageInfo->nWidth, pstImageInfo->nHeight);srcImage = cv::Mat(pstImageInfo->nHeight, pstImageInfo->nWidth, CV_8UC3, pData);return srcImage;}else{QMessageBox::warning(this,"警告","不支持此类型转换");return srcImage;}if ( NULL == srcImage.data ){QMessageBox::warning(this,"警告","转换图像为空");return srcImage;}
}void MainWindow::on_pushButton_seachDevice_clicked()//按下查询设备按钮
{EnumDevice();//调用枚举设备函数
}void MainWindow::on_pushButton_grabImage_clicked()//按下采样按钮
{ConnectDevice();SetTriggerMode();GrabImage();//GetImage();timer = new QTimer;timer->start(300);connect(timer,&QTimer::timeout,this,&MainWindow::GetImage);//通过定时器循环调用显示图像
}void MainWindow::GetImage()//采集一张图片
{nRet = MV_CC_GetOneFrameTimeout(handle, pData, g_nPayloadSize, &stImageInfo, 1000);if (nRet == MV_OK){cv::Mat dstImga;dstImga = Convert2Mat(&stImageInfo, pData);//cv::imshow("image",dstImga);cv::cvtColor(dstImga,dstImga,cv::COLOR_BGR2RGB);QImage Qtemp = QImage((const unsigned char*)(dstImga.data), dstImga.cols, dstImga.rows, dstImga.step, QImage::Format_RGB888);ui->label_show->setScaledContents(true);ui->label_show->setPixmap(QPixmap::fromImage(Qtemp));}else{QString text = QString("无图像数据!nRet [%1]").arg(nRet);QMessageBox::warning(this,"警告",text);free(pData);pData = NULL;return;}}void MainWindow::on_pushButton_stopGrab_clicked()//按下停止采集按钮
{timer->stop();// 关闭取流nRet = MV_CC_StopGrabbing(handle);if (MV_OK != nRet){printf("Stop Grabbing fail! nRet [0x%x]\n", nRet);return;}//关闭设备nRet = MV_CC_CloseDevice(handle);if (MV_OK != nRet){printf("ClosDevice fail! nRet [0x%x]\n", nRet);return;}// Destroy handlenRet = MV_CC_DestroyHandle(handle);if (MV_OK != nRet){printf("Destroy Handle fail! nRet [0x%x]\n", nRet);return;}
}

就到这里,本人也是小白,刚接触编程没多久,班门弄斧大神轻喷!

QT+opencv调用海康工业相机相关推荐

  1. (一)Qt+OpenCV调用海康工业相机SDK示例开发

    系列文章目录 提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 文章目录 系列文章目录 ...

  2. (二)Qt多线程实现海康工业相机图像实时采集

    系列文章目录 提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 文章目录 系列文章目录 ...

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

    python语言调用海康机器人(hikrobotics)工业相机 系列文章目录 第一章 python调用海康工业相机并用opencv显示(整体实现) 第二章 python 调用海康工业相机图像获取方式 ...

  4. 调用海康工业相机图像获取方式之主动取流(getimagebuffer )

    本文仅作记录!原文链接!:https://blog.csdn.net/qq_39570716/article/details/114304110 目录 一.使用前提 二.主动取流(官方例程说明) 1. ...

  5. qt调用海康工业相机踩坑全纪录

    方法一,使用qt中的QCameraInfo::availableCameras()调用海康摄像头 结论,失败 想的太天真 #include "mainwindow.h" #incl ...

  6. WIN10 C++调用海康工业相机

    1.安装海康工业相机套件MVS,需要下载的MVS如下图所示.链接为https://www.hikrobotics.com/cn/machinevision/service/download?modul ...

  7. Python调用海康工业相机:包含相机参数修改、彩色原图显示(不失真)

    [引言] 海康相机作为目前工业检测.视觉定位等领域应用较为广泛的国产品牌相机,其搭配有一套专用视觉软件VM,而在完成具有复杂场景.复杂任务的科研项目时依靠其VM算法平台提供的视觉算法往往无法满足项目要 ...

  8. python 调用海康工业相机调试后出现被占用问题

    问题描述: 在使用海康工业网口相机开发过程中,调试阶段异常结束程序调试时,经常出现相机被占用的异常情况,无论是使用海康的客户端界面连接相机还是使用调试代码连接相机,都没有权限再次打开相机,需要相机断电 ...

  9. 2022-05-16 Python OpenCV 海康工业相机

    背景 Python OpenCV连接海康工业相机做图像处理 环境 Python:3.9.9 OpenCV:4.5.5 numpy:1.19.3 2022-05-16_112138.png 相机 海康: ...

最新文章

  1. ASP.NET中Response.Redirect()方法深度剖析
  2. Flutter瀑布流及通用列表解决方案
  3. 面试题:如何编写一个杯子测试用例
  4. stdafx.h 的作用
  5. html自适应_web前端入门到实战:HTML 文档流,设置元素浮动,导致父元素高度无法自适应的解决方法...
  6. linux mutex 数量上限,互斥量mutex
  7. java list 内存分页_Java List内存分页
  8. MySQL索引(如何设计索引)
  9. [ SHELL编程 ] 远程服务器传输文件
  10. matlab练习程序(方框模糊)
  11. 优麒麟 mysql_优麒麟18.10新特性预览—生物识别
  12. 百度输入法黑莓版更新至1.0.1.7
  13. DDOS防御流量清洗的解决方案,流量清洗服务有什么功能?
  14. 两个经纬度偏角_转载:经纬度和方位角之间的关系
  15. Http的三次握手与四次挥手的流程:SYN包--同步包 ACK包--应答包 FIN包--终止包
  16. 2020-09-07关皓
  17. 根据出生年月日计算出生了多少年,多少月,多少天
  18. IR-CUT选择须知
  19. 青龙-今日头条极速版更新
  20. linux网卡驱动rtl8188cu,linux下编译基于rtl8188cu控制芯片的USB无线网卡驱动 -电脑资料...

热门文章

  1. 教务管理系统java源代码,教务管理系统 - WEB源码|JSP源码/Java|源代码 - 源码中国...
  2. 微耕控制器实现远程开门与普通刷卡的反潜回
  3. 基于MVC的在线影票售卖系统/基于ASP.NET的电影院售票系统
  4. 书迷软件_书迷们应该抵制好书吗
  5. 注音符号与汉语拼音对照表
  6. DDos工具tfn2k的编译
  7. 【Prompt】7 个向 chatGPT 高效提问的方法
  8. 计算机专业的就业方向有哪些呢?
  9. 一起回答这36个问题,你们会相爱
  10. 如何通过以太坊智能合约来进行众筹(ICO)