上文中驱动水星工业相机采集视频是采用官方例程修改,利用OpenCV显示函数实现的一个弹出的大窗口,无法控制。想着做一个播放界面,故采取QT实现了一个简单的界面播放器,使用多线程实现视频的采集。
采取QT中的多线程QThread类
直接放上代码 数据采集

// An highlighted block
#include "MERCamera.h"//using namespace cv;
using namespace std;QImage m_GlobalImage;
cv::Mat img;
//用户继承掉线事件处理类
class CSampleDeviceOfflineEventHandler : public IDeviceOfflineEventHandler
{public:void DoOnDeviceOfflineEvent(void* pUserParam){cout << "收到设备掉线事件!" << endl;}
};
//用户继承属性更新事件处理类
class CSampleFeatureEventHandler : public IFeatureEventHandler
{public:void DoOnFeatureEvent(const GxIAPICPP::gxstring&strFeatureName, void* pUserParam){cout << "收到曝光结束事件!" << endl;}
};//用户继承采集事件处理类  用户需要继承ICaptureEventHandler虚基类实现自己的回调处理类
class CSampleCaptureEventHandler : public ICaptureEventHandler
{public:void DoOnImageCaptured(CImageDataPointer&objImageDataPointer, void* pUserParam){cout << "收到一帧图像!" << endl;cout << "ImageInfo: " << objImageDataPointer->GetStatus() << endl;cout << "ImageInfo: " << objImageDataPointer->GetWidth() << endl;cout << "ImageInfo: " << objImageDataPointer->GetHeight() << endl;cout << "ImageInfo: " << objImageDataPointer->GetPayloadSize() << endl;img.create(objImageDataPointer->GetHeight(), objImageDataPointer->GetWidth(), CV_8UC3);void *pRGB24Buffer = NULL;//假设原始数据是BayerRG8图像pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);memcpy(img.data, pRGB24Buffer, (objImageDataPointer->GetHeight()) * (objImageDataPointer->GetWidth()) * 3);cv::flip(img, img, 0);//cv::imshow("sss", img);//cv::waitKey(1);m_GlobalImage = cvMat2QImage(img);cout << "帧数:" << objImageDataPointer->GetFrameID() << endl;}
};
int StoreBMP(int PictureNum){//声明事件回调对象指针IDeviceOfflineEventHandler* pDeviceOfflineEventHandler = NULL;///<掉线事件回调对象IFeatureEventHandler* pFeatureEventHandler = NULL;///<远端设备事件回调对象ICaptureEventHandler* pCaptureEventHandler = NULL;///<采集回调对象//初始化 使用其他接口之前,必须执行初始化IGXFactory::GetInstance().Init();try{do{//枚举设备gxdeviceinfo_vector vectorDeviceInfo;IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);if (0 == vectorDeviceInfo.size()){cout << "无可用设备!" << endl;break;}cout << vectorDeviceInfo[0].GetVendorName() << endl;cout << vectorDeviceInfo[0].GetSN() << endl;//打开第一台设备以及设备下面第一个流CGXDevicePointer ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[0].GetSN(),GX_ACCESS_EXCLUSIVE);CGXStreamPointer ObjStreamPtr = ObjDevicePtr->OpenStream(0);//注册设备掉线事件【目前只有千兆网系列相机支持此事件通知】GX_DEVICE_OFFLINE_CALLBACK_HANDLE hDeviceOffline = NULL;pDeviceOfflineEventHandler = new CSampleDeviceOfflineEventHandler();hDeviceOffline = ObjDevicePtr->RegisterDeviceOfflineCallback(pDeviceOfflineEventHandler, NULL);//获取远端设备属性控制器CGXFeatureControlPointer ObjFeatureControlPtr = ObjDevicePtr->GetRemoteFeatureControl();//设置曝光时间(示例中写死us,只是示例,并不代表真正可工作参数)//ObjFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(50);注册远端设备事件:曝光结束事件【目前只有千兆网系列相机支持曝光结束事件】选择事件源//ObjFeatureControlPtr->GetEnumFeature("EventSelector")->SetValue("ExposureEnd");使能事件//ObjFeatureControlPtr->GetEnumFeature("EventNotification")->SetValue("On");//GX_FEATURE_CALLBACK_HANDLE hFeatureEvent = NULL;//pFeatureEventHandler = new CSampleFeatureEventHandler();//hFeatureEvent = ObjFeatureControlPtr->RegisterFeatureCallback(//    "EventExposureEnd",// pFeatureEventHandler,// NULL);//注册回调采集pCaptureEventHandler = new CSampleCaptureEventHandler();ObjStreamPtr->RegisterCaptureCallback(pCaptureEventHandler, NULL);//发送开采命令ObjStreamPtr->StartGrab();ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();//此时开采成功,控制台打印信息,直到输入任意键继续getchar();//发送停采命令ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();ObjStreamPtr->StopGrab();//注销采集回调ObjStreamPtr->UnregisterCaptureCallback();注销远端设备事件//ObjFeatureControlPtr->UnregisterFeatureCallback(hFeatureEvent);注销设备掉线事件//ObjDevicePtr->UnregisterDeviceOfflineCallback(hDeviceOffline);//释放资源ObjStreamPtr->Close();ObjDevicePtr->Close();} while (0);}catch (CGalaxyException&e){cout << "错误码: " << e.GetErrorCode() << endl;cout << "错误描述信息: " << e.what() << endl;}catch (std::exception&e){cout << "错误描述信息: " << e.what() << endl;}//反初始化库 关闭设备之后,不能再调用其他任何库接口IGXFactory::GetInstance().Uninit();//销毁事件回调指针if (NULL != pCaptureEventHandler){delete pCaptureEventHandler;pCaptureEventHandler = NULL;}if (NULL != pDeviceOfflineEventHandler){delete pDeviceOfflineEventHandler;pDeviceOfflineEventHandler = NULL;}if (NULL != pFeatureEventHandler){delete pFeatureEventHandler;pFeatureEventHandler = NULL;}return 0;}
QImage cvMat2QImage(const cv::Mat& mat)
{// 8-bits unsigned, NO. OF CHANNELS = 1  if (mat.type() == CV_8UC1){QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);// Set the color table (used to translate colour indexes to qRgb values)  image.setColorCount(256);for (int i = 0; i < 256; i++){image.setColor(i, qRgb(i, i, i));}// Copy input Mat  uchar *pSrc = mat.data;for (int row = 0; row < mat.rows; row++){uchar *pDest = image.scanLine(row);memcpy(pDest, pSrc, mat.cols);pSrc += mat.step;}return image;}// 8-bits unsigned, NO. OF CHANNELS = 3  else if (mat.type() == CV_8UC3){// Copy input Mat  const uchar *pSrc = (const uchar*)mat.data;// Create QImage with same dimensions as input Mat  QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped();}else if (mat.type() == CV_8UC4){qDebug() << "CV_8UC4";// Copy input Mat  const uchar *pSrc = (const uchar*)mat.data;// Create QImage with same dimensions as input Mat  QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);return image.copy();}else{qDebug() << "ERROR: Mat could not be converted to QImage.";return QImage();}
}

采取的是回调采集方式,将帧采集函数放在线程中:

//线程入口函数
void SendTask::run()
{StoreBMP(1);
}

采用定时器刷新QLable上的帧:

//定时器处理函数
void QtCamera::timerEvent(QTimerEvent * event)
{//可以有多个定时器,每个定时器有不同的处理if (event->timerId() == m_timeId){ui.label->setPixmap(QPixmap::fromImage(m_GlobalImage));}
}

结果:

QLabel上播放时视频有点延时,同时还未改进视频的缩放问题,有同学提出:
经过实际测试Qlabel显示image的效率很差,可以使用QWidget,然后在paintEvent里面drawPixmap。
这样的效率提升相当大,16路视频播放时CPU才20%;
QPainter使用的是GPU,显卡不好的话图片与图片显示之间会有白画面,显卡不是很差的话非常流畅。
马上试试。

QT + 大恒水星工业相机 +vs2017 实现线程拍摄视频相关推荐

  1. 基于Qt大恒工业相机二次开发demo-C++

    目录 1.新建工程 2.文件及属性配置 2.1文件拷贝 2.2VS项目属性配置 2.2.1包含目录和库目录添加 2.2.2附加依赖项添加 3.添加基于官方mfc代码改写的CGXBitmap类 3.1添 ...

  2. 大恒水星相机开发记录

    大恒水星相机开发记录 前面的话: 最近搞了一个大恒的相机MER-500-14GC,本着这可是行业龙头的工业相机嘛,终归是在学校摸到了真正的工业级产品了.(٩(๑>◡<๑)۶) 想着用ope ...

  3. 大恒水星相机+opencv4.0.1保存视频

    最近项目上需要做一个保存相机视频的功能,手头上刚好有一个大恒130W分辨率的黑白水星相机.因此,就用该摄像机结合opencv实现了该功能. 准备工作: 1.OpenCV:版本4.0.1 2.大恒水星相 ...

  4. 配置网口相机(大恒水星相机)

    配置网口相机(大恒水星相机) 相机参数: 首先查看电脑是否为支持千兆网口. 从这里看的出来(GbE)是千兆的. 也可以用鲁大师,用鲁大师查看,确实是千兆网口. 命令行输入ipconfig/all,可以 ...

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

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

  6. QT 驱动大恒水星相机

    编程环境 vs2019+QT5.12.10 大恒官方相机驱动库 下载驱动->安装驱动 默认路径安装即可.参考编程mfc例子路径 搭建测试demo 首先相机初始化列表在构造过程中 在cam.cpp ...

  7. 双网口相机平台搭建C++(大恒水星)

    这次并不满足我的使用,后面我又改成C开发了,C++开发只做到这里,当然也有很多参考价值,C开发也差不多,这里是X86的,因为和下位机的通信是32位的,也要变成X86的. 主要工作模块与功能: 创建基于 ...

  8. 使用大恒水星相机利用OpenCV+ Zbar 解QR码在ROS下定位的实现

    使用大恒水星相机利用OpenCV+ Zbar 解QR码在ROS下定位的实现 本次的程序功能实现是在师兄原有程序的基础上,经我继续开发的.主要完成的功能是使用QR码定位,将位姿信息通过ROS中的tf变换 ...

  9. 大恒工业相机C#语言winform平台开发例程

    大恒工业相机winform快速开发 例程一.连续采集,返回bitmap格式图像 例程二.软触发采集,返回bitmap格式图像 例程三.硬触发采集,返回bitmap格式图像 例程四.作为TCP客户端接收 ...

最新文章

  1. 判断二叉树中两个节点的最低共同父节点
  2. 2009年网页设计10大趋势
  3. app = Flask(__name__)相关说明
  4. Js树形插件ztree
  5. 【Flink】Disconnect from JobManager responsible for
  6. Linux基础管理——磁盘管理及文件系统(全)
  7. 在Vim中将DOS行尾转换为Linux行尾
  8. 设计模式---外观模式(C++实现)
  9. JAVA中字符串函数subString的用法小结
  10. Mybatis foreach逗号分隔字符串遍历方式
  11. 时钟的同步与异步问题
  12. makefile 指定文件搜索路径和文件生成路径
  13. Why it occurs this error [The JSON value could not be converted to System.Nullable]
  14. Python程序写诗【训练1分钟】古诗生成
  15. 一篇讲给自己听的k8s网络模型
  16. 设计模式中的工厂类图
  17. 机器人抓取 三维重建机器人抓取 三维物体匹配
  18. oracle 在plsql中创建procedure并调用
  19. 医院管理信息系统解决方案
  20. 培训python排行榜

热门文章

  1. 初级软件开发人员进修必备的20本书(上)
  2. iOS 自带地图详解
  3. latex表格内部自定义换行
  4. 城市夜空三(续)公布聊天记录第一部分
  5. Ubuntu系统界面启动后启动开机自启动后锁屏
  6. 瞎子摸象---汇兑损益
  7. 基于javaweb+mysql的高校学生会社团管理系统(前台、后台)
  8. 请排列RJ45交叉双绞线水晶头的顺序?
  9. 基于机器学习的天气数据分析与预测系统
  10. python取整符号_Python中的取整函数