目录

  • 前言
  • 正文
    • 准备工作
    • 设备的初始化
    • 设备信息的获取
    • 实时采图
    • 将采集到的Buffer传上显示层
  • 总结

前言

本篇博客稍微记录一下我所写的插件。具体内容是有关于大恒相机的,关于这个相机,相信搜索到这个博客的应该都有所了解了,关于这个插件,我所完成的功能是:利用该相机提供的SDK完成主动采图,回调采图,以及显示出该相机的参数列表这三个主要的功能。下面就是正文,我只会贴属于这个插件的代码,其他部分就不贴出来了。所以,应该只能给你编写的代码一些启示,但就目前这些代码,却没办法运行起来这个代码的,你应该根据软件的功能去继承一些虚函数,就可以完成这个插件。

正文

准备工作

首先,开始写这个插件肯定是从下载这个相机的SDK开始的,下面就给出下载链接。
大恒相机SDK,我们需要从这个软件的安装目录中拿出我们所需要的东西,需要的东西我也打包成一个链接:
大恒相机必备材料。 如果没积分的话可私信。

设备的初始化

下面这个函数的主要功能就是完成设备的初始化工作,下面这个函数没有什么跟那个SDK挂上钩的地方,接下去的这个函数比较重要。

bool MDeviceDahengG3UC::InitDevice(QString index,QString identifier)
{m_cCameraID = index;m_cIdentifier = identifier;bool ret = false;
#ifdef WIN32_DAHENG_GEVif(DeviceLoading(m_cIdentifier)){m_pConfigureObj = new MConfigureDahengG3UC();m_pConfigureObj->InitConfigure(m_cCameraID,this);m_pConfigureObj->RegisterConfigureCallback(m_fXmlChange,m_pCallUser);//注册配置文件的回调函数QVariant wVal;QVariant hVal;QVariant pixelForamt;QVariant frameRate;this->GetParameter("Width",wVal);this->GetParameter("Height",hVal);this->GetParameter("PixelFormat",pixelForamt);if(IsExistParameter("ResultingFrameRate")){qDebug()<<"resultingFrameRate";this->GetParameter("ResultingFrameRate",frameRate);}else if(IsExistParameter("ResultingFrameRateAbs")){this->GetParameter("ResultingFrameRateAbs",frameRate);}m_iWidth = wVal.toInt();m_iHeight = hVal.toInt();m_cPixelFormat = pixelForamt.toString();m_fFrameRate = frameRate.toFloat();ret = true;}
#endifreturn ret;
}

下面这个函数就有比较多值得学习的地方,以下讲的地方都是从SDK中得出的。

首先,先给出整个具体的函数,然后再进行解析

bool MDeviceDahengG3UC::DeviceLoading(QString identifier)
{m_bLoaded = false;bool bIsDeviceOpen = false;              ///< 设备是否已打开标识bool bIsStreamOpen = false;              ///< 设备流是否已打开标识
#ifdef WIN32_DAHENG_GEVint nRet = -1;IGXFactory::GetInstance().Init();GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);//判断当前设备连接个数if (vectorDeviceInfo.size() <= 0){qDebug()<<"No Device!";return m_bLoaded;}else{for (uint n = 0; n < vectorDeviceInfo.size(); n++){//判断枚举到的设备是否为Gigebool accessStatus = vectorDeviceInfo[n].GetAccessStatus();if(accessStatus){GxIAPICPP::gxstring SerialNumber;QString SerialNumber2;GX_DEVICE_CLASS_LIST gClass2 = vectorDeviceInfo[n].GetDeviceClass();SerialNumber = vectorDeviceInfo[n].GetSN();SerialNumber2 = static_cast<QString>(SerialNumber);if(SerialNumber2.length()>=16)SerialNumber2 = SerialNumber2.left(16);if(identifier.contains(SerialNumber2)){m_cSerialNumber = SerialNumber2;m_cModelName = static_cast<QString>(vectorDeviceInfo[n].GetModelName());m_cCameraVendor = vectorDeviceInfo[n].GetVendorName();m_cUserDefine = vectorDeviceInfo[n].GetUserID();m_cDeviceVersion = vectorDeviceInfo[n].GetDisplayName();GxIAPICPP::gxstring strSN  = vectorDeviceInfo[n].GetSN();m_objDevicePtr  = IGXFactory::GetInstance().OpenDeviceBySN(strSN,GX_ACCESS_EXCLUSIVE);m_objStreamPtr = m_objDevicePtr->OpenStream(0);m_pCaptureEventHandler = new CSampleCaptureEventHandler();m_bLoaded = true;bIsDeviceOpen = true;break;}}}}return m_bLoaded;
#endif
}
  1. 首先,是相机设备的初始化
IGXFactory::GetInstance().Init();//这个是进行实例的初始化
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
//通过这个就可以获得相关的设备信息vectorDeviceInfo
  1. 接下来,就是获得当前设备的所有信息,这里就列举一些信息的获得就好了。这里可以稍微注意一下,强制类型转换在这里的应用。
GxIAPICPP::gxstring SerialNumber;
QString SerialNumber2;
GX_DEVICE_CLASS_LIST gClass2 = vectorDeviceInfo[n].GetDeviceClass();
SerialNumber = vectorDeviceInfo[n].GetSN();
SerialNumber2 = static_cast<QString>(SerialNumber);
  1. 接下来,根据设备序列号打开设备并获得实例
m_objDevicePtr  = IGXFactory::GetInstance().OpenDeviceBySN(strSN,GX_ACCESS_EXCLUSIVE);
  1. 打开流对象
 m_objStreamPtr = m_objDevicePtr->OpenStream(0);

上面这个就是对这个函数的一些解析了。如果有不懂的可以查下文档,肯定没有文档讲的细致,这里只是提出了一个解决问题的思路。

设备信息的获取

MDeviceDahengG3UCInfo.cpp
下面这个函数主要是获取根据SDK获取对象的相机信息,并且是相对上面那个函数会较全。

首先,这里先给出完整的这个函数,你可以大概先瞄一眼大概。

bool MDeviceDahengG3UCInfo::SearchDeviceInfos(QStringList &lInfo)
{bool ret = false;
#ifdef WIN32_DAHENG_GEVint nRet = -1;IGXFactory::GetInstance().Init();GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);if(vectorDeviceInfo.size()>0){for (uint32_t i = 0; i < vectorDeviceInfo.size(); i++){if(vectorDeviceInfo[i].GetDeviceClass() == GX_DEVICE_CLASS_GEV||vectorDeviceInfo[i].GetDeviceClass()==GX_DEVICE_CLASS_U3V){GxIAPICPP::gxstring ModelName = vectorDeviceInfo[i].GetModelName();QString ModelName2 = static_cast<QString>(ModelName);GxIAPICPP::gxstring CameraVendor = vectorDeviceInfo[i].GetVendorName();QString CameraVendor2 = static_cast<QString>(CameraVendor);GxIAPICPP::gxstring UserID = vectorDeviceInfo[i].GetUserID();QString UserID2 = static_cast<QString>(UserID);GxIAPICPP::gxstring DeviceID = vectorDeviceInfo[i].GetDeviceID();QString DeviceID2 = static_cast<QString>(DeviceID);GxIAPICPP::gxstring DeviceIP = vectorDeviceInfo[i].GetIP();QString DeviceIP2 = static_cast<QString>(DeviceIP);GxIAPICPP::gxstring DeviceSN = vectorDeviceInfo[i].GetSN();QString DeviceSN2 = static_cast<QString>(DeviceSN);GxIAPICPP::gxstring DeviceDisplayName = vectorDeviceInfo[i].GetDisplayName();QString DeviceDisplayName2 = static_cast<QString>(DeviceDisplayName);bool DeviceStatus = vectorDeviceInfo[i].GetAccessStatus();QString devInfo;devInfo += QString("%1:%2;").arg(XML_TLAYER_TYPE)      //传输协议.arg(XML_TLAYER_U3V);devInfo += QString("%1:%2;").arg(XML_DRIVER_TYPE)      //驱动类型.arg(m_cCameraType);devInfo += QString("%1:%2;").arg(XML_DEVICE_MODEL_NAME)//设备型号.arg(ModelName2);devInfo += QString("%1:%2;").arg(XML_DEVICE_USER_DEFINE)//自定义名称.arg(UserID2);devInfo += QString("%1:%2;").arg(XML_DEVICE_ID)         //序列号.arg(DeviceSN2);devInfo += QString("%1:%2;").arg(XML_DEVICE_VENDOR)     //生产厂家.arg(CameraVendor2);devInfo += QString("%1:%2;").arg(XML_DEVICE_VERSION)    //设备版本.arg(DeviceDisplayName2);devInfo += QString("%1:%2;").arg(XML_DEVICE_STATUS)     //设备状态.arg(DeviceStatus);qDebug()<<"=>GetDeviceDaHengU3V:"<<devInfo;lInfo << devInfo;}}}#endifreturn ret;
}
  1. 首先也是要进行初始化,并获得设备信息对象。
IGXFactory::GetInstance().Init();
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
  1. 然后就是获取设备信息的那部分了。注意一些强制类型转换。这部分难度不大,应该可以完成。

实时采图

下面这个函数是主动采图的开启与停止函数,所谓主动采图,就是通过按钮,用户主动去控制采图的过程,控制定时器定时器的开关,从而得到在一定的时间内可以连续采图,得到较好的连续的图像。

首先上开启采图的完整代码:

qint32  MDeviceDahengG3UC::AcquisitionStart()
{qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEVif(m_bLoaded){if(m_bStopWork){m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();m_objImageProcessPtr = m_objDevicePtr->CreateImageProcessConfig();bool m_bIsColorFilter = m_objFeatureControlPtr->IsImplemented("PixelColorFilter");//开启流通道采集if(!m_objStreamPtr.IsNull()){qDebug()<<"MDeviceDahengG3UC::AcquisitionStart m_objStreamPtr";//objStreamPtr->SetAcqusitionBufferNumber(10);//必须在调用StartGrab开启流通道的采集之前,设置采集buffer个数,否则设置无效。m_objStreamPtr->StartGrab();}//给设备发送开采命令if(!m_objFeatureControlPtr.IsNull()){m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();ret = RETURN_OK;}if(m_pConfigureObj->UpdateConfigureFromDevice())m_pConfigureObj->SlotConfigChanged();if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())m_pConfigureObj->SlotSimplyConfigChanged();m_bStopWork =false;}}
#endifreturn ret;
}
qint32  MDeviceDahengG3UC::AcquisitionStop()
{qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEVif(m_bLoaded){if(!m_bStopWork){//停采if((!m_objFeatureControlPtr.IsNull())&&(!m_objStreamPtr.IsNull())){m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();m_objStreamPtr->StopGrab();//关闭流通道m_objStreamPtr->Close();}if(m_pConfigureObj->UpdateConfigureFromDevice())m_pConfigureObj->SlotConfigChanged();if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())m_pConfigureObj->SlotSimplyConfigChanged();ret = RETURN_OK;m_bStopWork = true;}}
#endifreturn ret;
}
  1. 首先,开启流通道采集
if(!m_objStreamPtr.IsNull())
{qDebug()<<"MDeviceDahengG3UC::AcquisitionStart m_objStreamPtr";//objStreamPtr->SetAcqusitionBufferNumber(10);//必须在调用StartGrab开启流通道的采集之前,设置采集buffer个数,否则设置无效。m_objStreamPtr->StartGrab();
}
  1. 给设备发送开始开采命令
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();if(!m_objFeatureControlPtr.IsNull())
{m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();ret = RETURN_OK;
}
  1. 在这里调用相机参数配置的函数,
if(m_pConfigureObj->UpdateConfigureFromDevice())m_pConfigureObj->SlotConfigChanged();
if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())m_pConfigureObj->SlotSimplyConfigChanged();
  1. 给设备发送关闭开采的命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();m_objStreamPtr->StopGrab();//关闭流通道m_objStreamPtr->Close();

将采集到的Buffer传上显示层

先上完整的代码:
CaptureImageEx

qint32 MDeviceDahengG3UC::CaptureImageEx(QImage *img, MFrameInfo *info)
{qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEVif(m_bLoaded){QImage::Format format = QImage::Format_Indexed8;if(m_cPixelFormat.compare("RGB888")==0)format = QImage::Format_RGB888;if((img->width() !=m_iWidth) ||(img->height() !=m_iHeight) ||(img->format() !=format) ){qDebug()<<"--> HiDahengG3V:CaptureImageEx reset image memory! ";*img = QImage(m_iWidth,m_iHeight,format);if(format == QImage::Format_Indexed8)img->setColorTable(m_vColorTabel);}CImageDataPointer objImageDataPtr;if(!m_objStreamPtr.IsNull()){objImageDataPtr = m_objStreamPtr->GetImage(500);//500ms趨}if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS){//void *pbit = objImageDataPtr->GetBuffer();int size = qMin((int)objImageDataPtr->GetPayloadSize(),img->byteCount());//memcpy(img->bits(),pbit,size);info->nWidth  = (qint32)objImageDataPtr->GetWidth();info->nHeight = (qint32)objImageDataPtr->GetHeight();info->nFramerLen = (qint32)objImageDataPtr->GetPayloadSize();//QMetaEnum metaEnum = QMetaEnum::fromType<GXIAPICPP_API::GX_PIXEL_FORMAT_ENTRY>();//info->cFormat = metaEnum.valueToKey(objImageDataPtr->GetPixelFormat();quint64 nformat = objImageDataPtr->GetPixelFormat();info->cFormat = GetPixelFormat(nformat);info->fFrameRate = m_fFrameRate;ret = RETURN_OK;}}
#endifreturn ret;
}
  1. 下面我开始解析,首先,你可以注意到这个操作;
 *img = QImage(m_iWidth,m_iHeight,format);

这个操作的目的是啥呢?目的是让这个img指向的QImage的宽高处于合理的状态,不然,即使你把buffer进行填充,你有可能发现你的框里面出现了三个重复的这个图像,但这肯定不是你想要的,所以,做一个判断,做一个赋值,这样是正确的操作。

  1. 我们可以看到,我上面是不是又做了一个采图的操作。也就是:
objImageDataPtr = m_objStreamPtr->GetImage(500);//500ms趨

这个操作,其实我们在Acqusisition上面就已经实现过,其实已经没有实现的必要了,但加上也可以。我这里这样使用的原因是,我并没有把这个指针objImageDataPtr声明为全局变量。所以,我这里就得再采一次了,但确实在之前的Acquisition那里采集更好。

  1. 然后就是把信息赋值给Info了,这个操作应该不难,并且,把得到的buffer的地址传递给img的这个地址,让其从底层人民传递到皇帝那里,从而把信息传递出去。具体的操作是这个:
void *pbit = objImageDataPtr->GetBuffer();
int size = qMin((int)objImageDataPtr->GetPayloadSize(),img->byteCount());//
memcpy(img->bits(),pbit,size);
info->nWidth  = (qint32)objImageDataPtr->GetWidth();
info->nHeight = (qint32)objImageDataPtr->GetHeight();
info->nFramerLen = (qint32)objImageDataPtr->GetPayloadSize();
//QMetaEnum metaEnum = QMetaEnum::fromType<GXIAPICPP_API::GX_PIXEL_FORMAT_ENTRY>();
//info->cFormat = metaEnum.valueToKey(objImageDataPtr->GetPixelFormat();
quint64 nformat = objImageDataPtr->GetPixelFormat();
info->cFormat = GetPixelFormat(nformat);
info->fFrameRate = m_fFrameRate;

总结

这个实时采图说难也不难,根所以,加油,重点应该是在最后的那个CaptureImageEx,你需要对你的程序有一个较好的设计,让这个函数接口不断的从最上层往下传,从而传递到插件这。
这个部分还有另外两篇,这里给出地址,有需要的可以去看看:

大恒相机开发实践(2)——触发采图
大恒相机开发实践(3)——参数设置

若有错误,欢迎指出,感谢~

大恒相机开发实践(1)——实时采图相关推荐

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

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

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

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

  3. Basler Blaze-101开发实践(1)——实时采图

    目录 前言 效果图 环境安装 SDK下载 正文 相机的初始化 实时采图 开始抓图 抓图函数 停止抓图 总结 前言 关于Basler的相机还是很常见的,网上也有很多代码可以参考,但这个相机的版本是Bla ...

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

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

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

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

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

    注:代码仅供参考,相互学习. 本意:帮助大家快速入手大恒相机,也留个记录后续优化. 配置环境:VS2019.OpenCV454.Qt5.14.2.大恒水星系列相机(gige) 优化: 2022/4/2 ...

  7. 基于大恒相机的VS工程配置

    1.开发主机上需安装大恒的开发工具软件(如图所示,版本号可能有不同),安装完成后桌面上会显示如下图标. 2.新建工程,选择Visual C++下的"Win32控制台应用程序",工程 ...

  8. VS调用大恒相机sdk实时显示图像并进行图像处理+OPENCV

    前言: 近期企业需要用大恒相机的sdk开发项目,我采用VS2017+QT5.10.1+MSVC. 一.环境配置 VS2017和qt的安装不多介绍,主要介绍大恒sdk的配置. 1.https://www ...

  9. MIL开发实践(2)——MIL实时采图

    前言 前言 效果图 正文 初始化 实时采图 总结 前言 网上找到的关于MIL实时采图的代码基本上都是只有很老的代码,但其实MIL是有自带的关于采图方面的QT的demo的.这里给出地址,应该比一些普通的 ...

最新文章

  1. Linux kernel 编译问题记录【转】
  2. [转移]安装 BugZilla 时 Perl 模块的安装
  3. Selenium IDE安装和检查获取的控件路径技巧
  4. 南通工学院计算机97级,2021年南通理工学院录取结果查询网址入口及录取结果公布时间...
  5. cbow word2vec 损失_word2vec个人总结-理论篇
  6. 替换html标签内容正则表达式,正则表达式,替换所有HTML标签的简单实例
  7. 前端学习(2781):底部tabber配置
  8. 如何理解Spring对缓存的支持
  9. 详解没有dSYM文件 如何解析iOS崩溃日志
  10. docker php amqp 扩展,docker搭建rabbitmq,配合php-amqplib+supervisor使用(下)
  11. 关于空间分析的一点小思考
  12. 如何破解“仅三天可见”的朋友圈?
  13. 计算机网络原理之网络层(解疑答惑)
  14. 移动机器人小众期刊Foundations and Trends in Roboics
  15. Optimized Cost per Click in Taobao Display Advertising - 淘宝 OCPC 阅读笔记
  16. 淘宝评论数据抓取简记
  17. 流年暗换,是什么偷走了我们的爱情
  18. 分享一个很好的卸载绿色软件:Geek Uninstaller(个人用户免费)
  19. 20190917练习题总结——选择题
  20. 深克隆和浅克隆的区别

热门文章

  1. 残疾人求职阿里巴巴等了八年!好辛苦!
  2. 全自动浅层过滤器的后期维护
  3. C语言 阿拉伯数字转换为汉语大写数字金额程序分析及源码
  4. 迭代学习控制方式Simulink建模与仿真
  5. 针对华为产品,如何在小红书宣传中发布有关图文笔记并达到最佳效果?
  6. python eel 多线程_Python的一个轻量级桌面GUI开发第三方库:Eel
  7. python中一般使用几个空格表示缩进_为什么Python pep-8强烈建议使用标签上的空格来缩进?...
  8. 安利这几款软件给需要的你
  9. 电脑连上了WiFi,却发现没有网(昨天还好好的)
  10. 从C/C++到Python(之二)(By Robinvane Suen)