注:代码仅供参考,相互学习。
本意:帮助大家快速入手大恒相机,也留个记录后续优化。

配置环境:VS2019、OpenCV454、Qt5.14.2、大恒水星系列相机(gige)

优化:
2022/4/22
1、把.h文件中类成员的初始化写到构造函数中
2、重新整理相机类和主窗口类关系
2022/7/21(完)
1、基本上重写了一版,这次逻辑更加清晰,考虑更全面。
这次更新是为了这篇博客有始有终,优化到目前这个阶段对于初学者应该是够用了。

一、qt界面

二、ui框架

三、代码部分

(1)DH_MER.h

#pragma once#include <QtWidgets/QMainWindow>
#include "ui_DH_MER.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include "GalaxyIncludes.h"using namespace cv;
using namespace std;class DH_MER : public QMainWindow, public IDeviceOfflineEventHandler, public ICaptureEventHandler
{Q_OBJECTpublic:DH_MER(QWidget* parent = Q_NULLPTR);public:void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam);void DoOnDeviceOfflineEvent(void* pUserParam); //掉线事件回调函数
public:CGXDevicePointer m_objDevicePtr; //设备指针,指向打开的相机CGXFeatureControlPointer m_objRemoteFeatureControlPtr; //(远端)设备属性控制器指针CGXFeatureControlPointer m_objFeatureControlPtr; //本地和流属性控制器CGXStreamPointer m_objStreamPtr; //流指针,指向相机打开的流GX_DEVICE_OFFLINE_CALLBACK_HANDLE m_hDeviceOffline; //掉线事件GX_DEVICE_CLASS_LIST objDeviceClass;//设备类型CGXDeviceInfo m_deviceInfo;//设备信息QString m_firmName;//厂商名称QString m_modelName;//设备型号QString m_serialNumName;//序列号QString m_ipName;//ip地址QString m_maskName;//掩码QString m_macName;//MAC地址int64_t m_width;int64_t m_height;QString m_bitDepth;cv::Mat capturedImg; //相机采集的图片//相机状态判断bool isOpenCam; //相机是否打开bool isOpenStream; //相机流是否打开bool isOffline; //设备是否掉线bool isTrigger; //相机是否触发int exposeTime; //曝光时间QString m_triggerMode;QString m_triggerSource;private:Ui::DH_MERClass ui;public slots:void on_openDevice_clicked();void on_closeDevice_clicked();void on_startCapture_clicked();void on_stopCapture_clicked();void on_TriggerSoftware_clicked();void getExposeTime();
public:void showMatInLabel(Mat matImg);void updateUI();
};

(2)DH_MER.cpp

#pragma once#include "DH_MER.h"
#include<QWidget>DH_MER::DH_MER(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);isOpenCam = false;isOpenStream = false;isOffline = false;isTrigger = false;exposeTime = 30000;m_hDeviceOffline = NULL;m_firmName = "";m_modelName = "";m_serialNumName = "";m_ipName = "";m_maskName = "";m_macName = "";m_width = 0;m_height = 0;m_bitDepth = "";m_triggerMode = "";m_triggerSource = "";//曝光时间connect(ui.exposeTime,&QLineEdit::editingFinished, this, &DH_MER::getExposeTime);//初始化库try{IGXFactory::GetInstance().Init();//GxIAPICPPEx库在使用之前必须执行初始化}catch (CGalaxyException& e){cout << "错误码: " << e.GetErrorCode() << endl;cout << "错误描述信息: " << e.what() << endl;}ui.TriggerMode->setEnabled(false);ui.TriggerSource->setEnabled(false);ui.TriggerSoftware->setEnabled(false);ui.comboBox_3->setEnabled(false);
}
void DH_MER::on_openDevice_clicked()
{try{if (!isOpenCam){//初始化IGXFactory::GetInstance().Init();//枚举设备gxdeviceinfo_vector vectorDeviceInfo;IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);if (0 == vectorDeviceInfo.size()){cout << "无可用设备!" << endl;return;}cout << vectorDeviceInfo.size() << endl;//打开第一台设备m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[0].GetSN(), GX_ACCESS_EXCLUSIVE);isOpenCam = true;m_objRemoteFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();m_objFeatureControlPtr = m_objDevicePtr->GetFeatureControl();/*设备信息获取*/m_deviceInfo = m_objDevicePtr->GetDeviceInfo();m_firmName = m_deviceInfo.GetVendorName();m_modelName = m_deviceInfo.GetModelName();m_serialNumName = m_deviceInfo.GetSN();m_ipName = m_deviceInfo.GetIP();m_maskName = m_deviceInfo.GetSubnetMask();m_macName = m_deviceInfo.GetMAC();m_width = m_objRemoteFeatureControlPtr->GetIntFeature("Width")->GetValue();m_height = m_objRemoteFeatureControlPtr->GetIntFeature("Height")->GetValue();m_bitDepth = m_objRemoteFeatureControlPtr->GetEnumFeature("PixelSize")->GetValue();
#ifdef _DEBUG//设置心跳超时时间 6sm_objRemoteFeatureControlPtr->GetIntFeature("GevHeartbeatTimeout")->SetValue(6000);
#endif/*设备初始设置*///千兆网系列相机设置objDeviceClass = m_objDevicePtr->GetDeviceInfo().GetDeviceClass();if (objDeviceClass == GX_DEVICE_CLASS_GEV){//提高网络相机的采集性if (true == m_objFeatureControlPtr->IsImplemented("GevSCPSPacketSize"))        //判断设备是否支持流通道数据包功能{//获取当前网络环境的最优包长值int nPacketSize = m_objStreamPtr->GetOptimalPacketSize();//将最优包长值设置为当前设备的流通道包长值m_objRemoteFeatureControlPtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize);}//注册掉线事件m_hDeviceOffline = m_objDevicePtr->RegisterDeviceOfflineCallback(this, NULL);}//曝光时间if (exposeTime > 0 && exposeTime < 200000)m_objRemoteFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(exposeTime);elseexposeTime = 30000;//采集模式m_objRemoteFeatureControlPtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous");//触发模式m_objRemoteFeatureControlPtr->GetEnumFeature("TriggerSelector")->SetValue("FrameStart");m_objRemoteFeatureControlPtr->GetEnumFeature("TriggerMode")->SetValue("Off");//自动曝光m_objRemoteFeatureControlPtr->GetEnumFeature("ExposureAuto")->SetValue("Off");ui.TriggerMode->setEnabled(true);ui.TriggerSource->setEnabled(true);ui.TriggerSoftware->setEnabled(true);ui.comboBox_3->setEnabled(true);}}catch (CGalaxyException& e){cout << "错误码: " << e.GetErrorCode() << endl;cout << "错误描述信息: " << e.what() << endl;}catch (std::exception& e){cout << "错误描述信息: " << e.what() << endl;}
}
void DH_MER::on_closeDevice_clicked()
{if (isOpenCam){if (isOpenStream){//发送停采命令m_objRemoteFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();m_objStreamPtr->StopGrab();ui.TriggerMode->setEnabled(true);ui.TriggerSource->setEnabled(true);ui.TriggerSoftware->setEnabled(true);ui.comboBox_3->setEnabled(true);m_objStreamPtr->UnregisterCaptureCallback();//注销采集回调m_objStreamPtr->Close(); //关闭相机流isOpenStream = false;}if (objDeviceClass == GX_DEVICE_CLASS_GEV){//注销掉线回调事件m_objDevicePtr->UnregisterDeviceOfflineCallback(m_hDeviceOffline);}m_objDevicePtr->Close(); //关闭相机,释放相机资源IGXFactory::GetInstance().Uninit(); //释放GxIAPICPPEx申请的所有资源isOpenCam = false;}
}
void DH_MER::on_startCapture_clicked()
{if (isOpenCam){uint32_t nStreamNum = m_objDevicePtr->GetStreamCount();if ((nStreamNum > 0) && (!isOpenStream)){m_objStreamPtr = m_objDevicePtr->OpenStream(0);isOpenStream = true;}m_objStreamPtr->RegisterCaptureCallback(this, NULL);m_objStreamPtr->StartGrab();m_objRemoteFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();}ui.TriggerMode->setEnabled(false);ui.TriggerSource->setEnabled(false);ui.TriggerSoftware->setEnabled(false);ui.comboBox_3->setEnabled(false);
}
void DH_MER::on_stopCapture_clicked()
{if (isOpenStream){//发送停采命令m_objRemoteFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();m_objStreamPtr->StopGrab();isOpenStream = false;}ui.TriggerMode->setEnabled(true);ui.TriggerSource->setEnabled(true);ui.TriggerSoftware->setEnabled(true);ui.comboBox_3->setEnabled(true);
}
void DH_MER::on_TriggerSoftware_clicked()
{try{do{m_triggerMode = ui.TriggerMode->currentText();m_triggerSource = ui.TriggerSource->currentText();if ((m_triggerMode =="on") && (m_triggerSource == "Software")){uint32_t nStreamNum = m_objDevicePtr->GetStreamCount();if ((nStreamNum > 0) && (!isOpenStream)){m_objStreamPtr = m_objDevicePtr->OpenStream(0);isOpenStream = true;}//发送开采命令m_objStreamPtr->StartGrab();m_objRemoteFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();CImageDataPointer objImageDataPtr = m_objStreamPtr->GetImage(500);//超时时间使用500ms,用户可以自行设定if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS){cout << "采集成功" << endl;void* pRGB24Buffer = NULL;//原始数据是 Mono8 图像if (objImageDataPointer->GetPixelFormat()==GX_PIXEL_FORMAT_MONO8){pRGB24Buffer = objImageDataPointer->ConvertToRaw8(GX_BIT_0_7);capturedImg = cv::Mat::zeros(cv::Size(m_width, m_height), CV_8UC1);memcpy(capturedImg.data, pRGB24Buffer, m_width * m_height);}if (objImageDataPointer->GetPixelFormat() == GX_PIXEL_FORMAT_MONO10){pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_2_9, GX_RAW2RGB_NEIGHBOUR, true);capturedImg = cv::Mat::zeros(cv::Size(m_width, m_height), CV_8UC3);memcpy(capturedImg.data, pRGB24Buffer, m_width * m_height * 3);}//resize(img, img, Size(), 0.1, 0.1, CV_INTER_AREA);showMatInLabel(capturedImg);}m_objRemoteFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();m_objStreamPtr->StopGrab();}} while (0);}catch (CGalaxyException& e){cout << "错误码: " << e.GetErrorCode() << endl;cout << "错误描述信息: " << e.what() << endl;}
}
void DH_MER::showMatInLabel(Mat matImg)
{Mat src = matImg.clone();QImage imgForDisplay;if (matImg.channels() == 3)//RGB Img{cv::cvtColor(src, src, cv::COLOR_BGR2RGB);//颜色空间转换imgForDisplay = QImage((const uchar*)(src.data), src.cols, src.rows, src.cols * src.channels(), QImage::Format_RGB888);}else//Gray Img{imgForDisplay = QImage((const uchar*)(src.data), src.cols, src.rows, src.cols * src.channels(), QImage::Format_Indexed8);}ui.label_Img->setPixmap(QPixmap::fromImage(imgForDisplay));
}
void DH_MER::getExposeTime()
{try{exposeTime = ui.exposeTime->text().toInt();if (exposeTime >= 31){m_objRemoteFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(exposeTime);}}catch (CGalaxyException& e){cout << "错误码: " << e.GetErrorCode() << endl;cout << "错误描述信息: " << e.what() << endl;}catch (std::exception& e){cout << "错误描述信息: " << e.what() << endl;}
}
void DH_MER::updateUI()
{ui.width->setText(QString::number(m_width));ui.height->setText(QString::number(m_height));ui.factoryName->setText(m_firmName);ui.basicModel->setText(m_modelName);
}
void DH_MER::DoOnDeviceOfflineEvent(void* pUserParam)
{isOffline = true;IGXFactory::GetInstance().Uninit(); //释放GxIAPICPPEx申请的所有资源cout << "设备掉线,请检查并重新连接。" << endl;
}
void DH_MER::DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
{//判断图像是否为完整帧if (GX_FRAME_STATUS_SUCCESS == objImageDataPointer->GetStatus()){//图像获取为完整帧,可以读取图像宽、高、数据格式等uint64_t m_width = objImageDataPointer->GetWidth();uint64_t m_height = objImageDataPointer->GetHeight();//GX_PIXEL_FORMAT_ENTRY emPixelFormat =objImageDataPointer->GetPixelFormat();void* pRGB24Buffer = NULL;//原始数据是 Mono8 图像if (objImageDataPointer->GetPixelFormat()==GX_PIXEL_FORMAT_MONO8){pRGB24Buffer = objImageDataPointer->ConvertToRaw8(GX_BIT_0_7);capturedImg = cv::Mat::zeros(cv::Size(m_width, m_height), CV_8UC1);memcpy(capturedImg.data, pRGB24Buffer, m_width * m_height);}if (objImageDataPointer->GetPixelFormat() == GX_PIXEL_FORMAT_MONO10){pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_2_9, GX_RAW2RGB_NEIGHBOUR, true);capturedImg = cv::Mat::zeros(cv::Size(m_width, m_height), CV_8UC3);memcpy(capturedImg.data, pRGB24Buffer, m_width * m_height * 3);}if (!capturedImg.empty()){double d = m_objRemoteFeatureControlPtr->GetFloatFeature("ExposureTime")->GetValue();exposeTime = int(d);emit sendCapturedMat(capturedImg,n);}showMatInLabel(capturedImg);updateUI();}
}

(3)main.cpp

#include "DH_MER.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);qRegisterMetaType<cv::Mat>("cv::Mat");DH_MER w;w.show();return a.exec();
}

四、其他资源

大恒软件以及开发文档传送
完整项目链接(有兴趣可以自己重新配置一下环境):
https://pan.baidu.com/s/10AJiTQC9rrZNe2HTPyO8kg
提取码:vh0i

注:相机开发存在错误和不完善的地方,仅供参考。无私分享,如有帮助,不妨收藏点赞

vs+Qt+opencv+大恒相机开发(基础功能,适合初学者学习)相关推荐

  1. 大恒相机开发(大恒SDK+opencv开发)笔记1

    大恒相机开发(大恒SDK+opencv开发 一.项目简介 在大三上学期做过人脸识别的开发,刚好下学期老师手中有相机的项目,然后项目就到了我手上,下面是我开发这个项目的一些经历,进程还在调试中.笔记会按 ...

  2. 大恒相机开发实践(1)——实时采图

    目录 前言 正文 准备工作 设备的初始化 设备信息的获取 实时采图 将采集到的Buffer传上显示层 总结 前言 本篇博客稍微记录一下我所写的插件.具体内容是有关于大恒相机的,关于这个相机,相信搜索到 ...

  3. 大恒相机开发实践(3)——参数设置

    目录 前言 正文 初始化配置信息 创建Xml节点 创建节点下面的Attribute 总结 前言 这一部分的内容放在如何生成大恒相机的参数,但其实难点并不在我接下去写的部分.难点在于你获得了这个节点的N ...

  4. 大恒相机开发实践(2)——触发采图

    目录 前言 正文 开启采图模式 开启实时采图功能 点击触发按钮 总结 前言 这部分完成的功能是触发采图,所谓触发采图,基本的过程是在先开启连续采图,然后,在某个触发信号到来的时候,读取其中的某一帧的信 ...

  5. 大恒相机开发问题(错误码: -8)无法打开相机

    前言: 记录一下大恒相机开发中的问题,如果能给和我一样正在摸索的小白一些帮助就更好了. 一.问题: 错误码: -8 错误描述信息: {Accessdenied:{1005}{GenICam::Clie ...

  6. QT调用大恒相机的开发教程

    Qt(5.12.10) 调用大恒相机,实时显示图像,并保存bmp文件 文章导读:相机为大恒相机,接口是USB3.0,水星系列产品.本项目采用Qt5.12.10版本编码,编译器为MSVC2017,ope ...

  7. Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)

    第一部分 bash简介     -- 对bash进行简要介绍 第二部分 bash示例和书写流程     -- 以一个简单的bash为例,说明书写.执行bash的流程 第三部分 bash基础语法     ...

  8. 微信小程序期末大作业 记单词小程序 适合初学者学习使用

    微信小程序期末大作业 记单词小程序 小程序如下图所示:(下载链接在文末) 点我下载资源 https://download.csdn.net/download/weixin_43474701/59677 ...

  9. Qt+大恒相机+OpenCV+MinGW界面开发

    Qt+大恒相机+OpenCV+MinGW界面开发 遇到的坑有哪些? 大恒相机接口的问题(C与C++选谁,傻傻分不清) OpenCV版本与MinGW编译平台适应性问题(编译通过,但是一运行就异常退出) ...

最新文章

  1. 利用七牛云实现简单的图床
  2. python(numpy,pandas4)——numpy中array合并和分割
  3. swiper用loop不出图片_swiper实现双向控制
  4. 数据科学学习心得_学习数据科学
  5. 【云速建站】后台配置邮费
  6. 滴滴又出事!33项问题被查,程维再次致歉
  7. PIE SDK导出图片
  8. [转]将H264与AAC打包Ipad可播放的TS流的总结
  9. Excel自定义格式日期计算问题
  10. 怎么知道银行卡号对应的银行
  11. NIO网络编程中重复触发读(写)事件
  12. python 实现人脸采集 训练 与人脸识别
  13. Tetris(初学Java第六篇)
  14. 用微分和差分方程描述的因果LIT系统
  15. 海量文本中挖掘人物关联关系核心技术介绍-桂洪冠
  16. 计算机d盘给c盘,怎么把D盘变成系统盘?
  17. npm安装报错(npm ERR! code EPERM npm ERR! syscall mkdir npm ERR! path C:\Program Files\nodejs\node_ca...)
  18. 直击GITC2018 尚德机构苏万松:从消费互联网到产业互联网
  19. 阿里大佬2019年回顾:有他60%的努力,何愁进不了大公司
  20. Windows应急响应篇

热门文章

  1. 股票预测 - ARIMA
  2. 软件嵌入式研发行业源代码安全管理方案概要
  3. 中南大学计算机组成原理,中南大学计算机组成原理作业答案
  4. XPS测试原理及样品要求
  5. zookeeper安装步骤
  6. centos8 配置 dns_centos 8 集群Linux环境搭建 - 凭栏莫听雨落
  7. oracle 速度最快 驱动,c# – Oracle ODP.NET托管驱动程序在64位运行速度比在32位运行速度慢50-100%...
  8. 【加餐】如何在SteamVR 2 中替换手部模型
  9. 点菜java_java点菜系统代码
  10. 2023年美赛A题思路解析/2023年美国大学生数学建模竞赛A题思路