添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

C++ 大恒水星相机的单帧采集及回调采集 利用OpenCV转成 Mat格式
最近购买一大恒水星MER-310-12UC型彩色相机,其SDK在2019年进行了更新,与之前SDK有很大不同,故现在网上资料较少,将一些简单的采集转换操作过程进行总结,后一篇将介绍与QT结合在软件界面中进行视频播放等操作。 环境是Win10,VS2017, OpenCV3.4

1. 使用手册阅读

  1. 首先我们要在其官网下载大恒相机的SDK,官网地址:http://www.daheng-imaging.com/,点击下载中心中的软件下载选择合适版本进行下载。然后安装
    在这里插入图片描述
  2. 安装好了软件以后,在安装目录下找到说明书,路径一般为安装目录下:\Daheng Imaging\GalaxySDK\Doc 按照说明书搭建编译环境
    在这里插入图片描述
    在这里插入图片描述
    认真阅读里面的一些函数及环境搭建 方法,但是其给出的示例不能调试成功,后面进行更改可以正确运行程序。

我们在工程需要把图存成Opencv的Mat形式。大恒C++ SDK采集的图像数据不能直接把图像的数据存进Mat,需要将原始数据(我这里是BayerRG8)经过格式转换之后转变成RGB24的格式,直接调用SDK的ConvertToRGB24函数。然后再向Mat写入数据。

2. 相机回调采集

// An highlighted block
#include <iostream>
#include <opencv2/opencv.hpp>
//using namespace cv;
using namespace std;
#include <GalaxyIncludes.h>
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;
//用户继承采集事件处理类
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);
		cout << "帧数:" << objImageDataPointer->GetFrameID() << endl;		
int main(int argc, char* argv[])
	//声明事件回调对象指针
	IDeviceOfflineEventHandler* pDeviceOfflineEventHandler = NULL;///<掉线事件回调对象
	IFeatureEventHandler* pFeatureEventHandler = NULL;///<远端设备事件回调对象
	ICaptureEventHandler* pCaptureEventHandler = NULL;///<采集回调对象
	//初始化
	IGXFactory::GetInstance().Init();
			//枚举设备
			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;

运行会报CGalaxyEeception 找不到标识符的错误,我们可以在gxsmartptr.h的文件中,在上面添一句#include “GalaxyException.h” 就好了!

使用的是回调采集方式,其运行结果:
在这里插入图片描述
图中是以视频帧的方式显示。

3.单帧采集

// An highlighted block
#include <iostream>
#include <opencv2/opencv.hpp>
//using namespace cv;
using namespace std;
#include <GalaxyIncludes.h>
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;
int main(int argc, char* argv[])
	//声明事件回调对象指针
	IDeviceOfflineEventHandler* pDeviceOfflineEventHandler = NULL;///<掉线事件回调对象
	IFeatureEventHandler* pFeatureEventHandler = NULL;///<远端设备事件回调对象
	ICaptureEventHandler* pCaptureEventHandler = NULL;///<采集回调对象
	//初始化 使用其他接口之前,必须执行初始化
	IGXFactory::GetInstance().Init();
			//枚举设备
			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();
			//采单帧
			CImageDataPointer objImageDataPtr;
			objImageDataPtr = ObjStreamPtr->GetImage(500);//超时时间使用500ms,用户可以自行设定
			if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)				//采图成功而且是完整帧,可以进行图像处理...
				cout << "收到一帧图像!" << endl;
				cout << "ImageInfo: " << objImageDataPtr->GetStatus() << endl;
				cout << "ImageInfo: " << objImageDataPtr->GetWidth() << endl;
				cout << "ImageInfo: " << objImageDataPtr->GetHeight() << endl;
				cout << "ImageInfo: " << objImageDataPtr->GetPayloadSize() << endl;
				img.create(objImageDataPtr->GetHeight(), objImageDataPtr->GetWidth(), CV_8UC3);
				void *pRGB24Buffer = NULL;
				//假设原始数据是BayerRG8图像
				pRGB24Buffer = objImageDataPtr->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);
				memcpy(img.data, pRGB24Buffer, (objImageDataPtr->GetHeight()) * (objImageDataPtr->GetWidth()) * 3);
				cv::flip(img, img, 0);
				cv::imshow("sss", img);
				cv::waitKey(1);
				cv::imwrite("01.bmp", img);
				cout << "帧数:" << objImageDataPtr->GetFrameID() << endl;
			//此时开采成功,控制台打印信息,直到输入任意键继续
			//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;

并将其采集图像保存在01.bmp中,结果:
在这里插入图片描述

大恒相机sdk开发+opencv开发笔记二 一.理清相机工作流程 首先我的相机是支持usb3.0的所以传输速率是很快的、 从传输速率上进行比较:理论值上讲USB 3.0的传输速度是4.8Gbps,是USB 2.0的10倍。我的项目需要快速的处理所以,需要3.0的其他的同学可以根据自己的需求选取各自所需要的相机。 回到主题。我们要使用相机,就像很多单片机的RST一样我们开始是需要初始话,这个函数是其自己写好的初始化库 (GXInitLib)可以在头文件中找到。之后我们初始完之后得去找到相机,它在其中定义了一个 大恒相机sdk开发+opencv开发笔记七 工业相机转换成Mat 类型 一 .Mat类型 Mat基本上是一个具有两个数据部分的类:矩阵头(包含矩阵的大小,用于存储的方法,存储在哪个地址的信息等等)和指向包含像素值(取决于所选存储方法的任何维度)。矩阵头大小是恒定的,然而矩阵本身的大小可以随着图像的不同而变化,通常会大一个数量级。 OpenCV是一个图像处理库。它包含大量的图像处理功能。为了解决计算挑战,大多数时候你最终会使用库的多个功能。因此,将图像传递给功能是常见的做法。我们不应该忘记,我们正在谈论的图像 #include"Daheng\CGVidEx.h" #pragma comment(lib, "CGVideo.lib") #pragma comment(lib, "CGVidEx.lib") class D... 使用海康工业相机sdk开发。语言C++,环境Qt,Ubuntu16.04 1.海康相机官网标称帧率为22fps,实际应用时发现只有4fps左右。后来确定为图像位深造成。 官方sdk,8位图像只支持mono 和bayer bg8 格式输出。所以,要修改官方图像转换 的Demo. 2.实验证明,并不用自己写bayer图像转换的函数。opencv就可以完成转换。但一定注意Bayer 作者所用相机大恒MER-132-43U3C彩色相机 2018年12月的时候调试成功过大恒水星相机,当时是用的vs2013,后来换了编译系统成了vs2015,之前的程序都不能用了。2019年3月26日晚上又搞了三个多小时,才在网上一些大牛成功的基础上,重新调试成果了相机的驱动程序。具体步骤如下: 搭建编译环境,从本网址下载最新的大恒相机SDK:http://www.daheng-imag... 目录前言正文 实验室正好有一个大恒型号为MER-1070-10GC的面阵相机,于是便用该相机学习工业相机的开发,写下本篇博客作为开发记录,也当作学习之路的一次小小实践。 通过OpenCV打开指定型号的大恒相机,通过回调和直接采集两种方式获取图像,并将图像转换成OpenCV格式打开相机采集图像格式转换图像处理 打开相机 采集图像 格式转换 图像处理 通常在网上能找到打开大恒相机的例子都是先枚举设备列表,然后通过索引序号打开相机,这种方法对于一台电脑上连接一台相机的情况还算适用,但如果同一台电脑上连接多台相机,通过枚举设备列表打开相机的话就有可能会出现问题(出现打开相机混乱,原来的1号相机有可能下次变为2号)。 下面来介绍一下在VS2017环境下,通过OpenCV大恒提供的S public void updateuiimg(IGXStream cameraStream, IGXFeatureControl cameraFeature,int i) 在将bayer图像转换成为rgb的时候遇到的问题 Mat bayer = imread("/home/pan/Desktop/data/Testaufbau_Ecoflac153.tif",-1); Mat bayer2rgb; bayer2rgb.create(bayer.rows,bayer.cols,CV_8UC3); cvtColor(bayer,bayer2rg typedef struct _tagFRAME_DATA //图像帧数据 unsigned int Width; //图像宽度 unsigned int Height; //图像高度 unsigned char Img[MAX_FRAME_LENGTH]; //图像数据 }FRAME_D.