目录
第一步:安装Gaalxy_view软件:Galaxy_V18.06.25.01_X86_Win_cn.exe
第二步:测试相机:MER-1070-10GC相机,应用软件打开该相机体验。
第三步:利用SDK-API进行编程,主要功能(开启、采集、录像、停止、关闭)
C接口
利用回调函数进行显示
C++ 接口
利用回调函数进行显示
利用获取帧进行显示
第四步:MFC联合SDK进行项目开发(当前项目瓷砖检测)。
第一步:安装Gaalxy_view软件:Galaxy_V18.06.25.01_X86_Win_cn.exe 软件从官网-技术支持-下载中心-选择需求软件(可单独使用SDK包、本文使用SDK+客户端软件一体)
链接:https://pan.baidu.com/s/1Il2qr_LD8Zz8gpb0QNQBaw 提取码:kh2w
文章图片
文章图片
第二步:测试相机:MER-1070-10GC相机,应用软件打开该相机体验。 MER-1070-10GC相机为以太网通信的相机,之前开发的项目都是走FlyCapture的sdk,不能开启该相机,所有先测试体验下。
文章图片
第三步:利用SDK-API进行编程,主要功能(开启、采集、录像、停止、关闭) 重中之重,如何开发所需功能,鄙人使用联合Opencv图像库联合开发。
使用C接口和C++ 接口两个程序分别实现:
总体思路:
初始化接口库——》枚举设备——》打开设备打开流
——》注册设备掉线事件【目前只有千兆网系列相机支持此事件通知】
——》获取远端设备属性控制器
————》注册远端设备事件【属性控制器】
——》注册回调采集(显示)
————》发送开采命令【属性控制器】
————》发送停采命令【属性控制器】
——》注销采集回调
——》注销远端设备事件
——》注销设备掉线事件
——》释放资源
C接口 (参考网上代码,C++的是看接口说明文档进行的)
配置:VC SDK的inc和lib、Opencv SDK配置
利用回调函数进行显示
#include
#include
#include
#include
#include
#include using namespace std;
using namespace cv;
GX_DEV_HANDLEm_hDevice;
///< 设备句柄
BYTE*m_pBufferRaw;
///< 原始图像数据
BYTE*m_pBufferRGB;
///< RGB图像数据,用于显示和保存bmp图像
int64_tm_nImageHeight;
///< 原始图像高
int64_tm_nImageWidth;
///< 原始图像宽
int64_tm_nPayLoadSize;
int64_tm_nPixelColorFilter;
///< Bayer格式
Mat test;
//图像回调处理函数
static void GX_STDC OnFrameCallbackFun(GX_FRAME_CALLBACK_PARAM* pFrame)
{
//PrepareForShowImg();
if (pFrame->status == 0)
{
//对图像进行某些操作
/*memcpy(m_pBufferRaw, pFrame->pImgBuf, pFrame->nImgSize);
// 黑白相机需要翻转数据后显示
for (int i = 0;
i imageData = https://www.it610.com/article/(char*)m_pImageBuffer;
cvSaveImage("src.jpg", src);
*/
memcpy(m_pBufferRaw, pFrame->pImgBuf, pFrame->nImgSize);
// RGB转换
DxRaw8toRGB24(m_pBufferRaw
, m_pBufferRGB
, (VxUint32)(m_nImageWidth)
, (VxUint32)(m_nImageHeight)
, RAW2RGB_NEIGHBOUR
, DX_PIXEL_COLOR_FILTER(m_nPixelColorFilter)
, false);
//cv_Image->imageData = https://www.it610.com/article/(char*)m_pBufferRGB;
//cvSaveImage("./test.bmp", cv_Image);
//test.data = https://www.it610.com/article/m_pBufferRaw;
memcpy(test.data, m_pBufferRGB, m_nImageWidth*m_nImageHeight * 3);
imwrite("./test1.bmp", test);
namedWindow("test");
imshow("test", test);
waitKey(15);
}
return;
}int main(int argc, char* argv[])
{
GX_STATUS emStatus = GX_STATUS_SUCCESS;
GX_OPEN_PARAM openParam;
uint32_tnDeviceNum = 0;
openParam.accessMode = GX_ACCESS_EXCLUSIVE;
openParam.openMode = GX_OPEN_INDEX;
openParam.pszContent = "1";
// 初始化库
emStatus = GXInitLib();
if (emStatus != GX_STATUS_SUCCESS)
{
return 0;
}
// 枚举设备列表
emStatus = GXUpdateDeviceList(&nDeviceNum, 1000);
if ((emStatus != GX_STATUS_SUCCESS) || (nDeviceNum <= 0))
{
return 0;
}
//打开设备
emStatus = GXOpenDevice(&openParam, &m_hDevice);
//设置采集模式连续采集
emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_MODE, GX_ACQ_MODE_CONTINUOUS);
emStatus = GXSetInt(m_hDevice, GX_INT_ACQUISITION_SPEED_LEVEL, 1);
emStatus = GXSetEnum(m_hDevice, GX_ENUM_BALANCE_WHITE_AUTO, GX_BALANCE_WHITE_AUTO_CONTINUOUS);
boolbColorFliter = false;
// 获取图像大小
emStatus = GXGetInt(m_hDevice, GX_INT_PAYLOAD_SIZE, &m_nPayLoadSize);
// 获取宽度
emStatus = GXGetInt(m_hDevice, GX_INT_WIDTH, &m_nImageWidth);
// 获取高度
emStatus = GXGetInt(m_hDevice, GX_INT_HEIGHT, &m_nImageHeight);
test.create(m_nImageHeight, m_nImageWidth, CV_8UC3);
//判断相机是否支持bayer格式
bool m_bColorFilter;
emStatus = GXIsImplemented(m_hDevice, GX_ENUM_PIXEL_COLOR_FILTER, &m_bColorFilter);
if (m_bColorFilter)
{
emStatus = GXGetEnum(m_hDevice, GX_ENUM_PIXEL_COLOR_FILTER, &m_nPixelColorFilter);
}
m_pBufferRGB = new BYTE[(size_t)(m_nImageWidth * m_nImageHeight * 3)];
if (m_pBufferRGB == NULL)
{
return false;
}
//为存储原始图像数据申请空间
m_pBufferRaw = new BYTE[(size_t)m_nPayLoadSize];
if (m_pBufferRaw == NULL)
{
delete[]m_pBufferRGB;
m_pBufferRGB = NULL;
return false;
}
//注册图像处理回调函数
emStatus = GXRegisterCaptureCallback(m_hDevice, NULL, OnFrameCallbackFun);
//发送开采命令
emStatus = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_START);
//---------------------
//
//在这个区间图像会通过OnFrameCallbackFun接口返给用户
Sleep(100000);
//
//---------------------
//发送停采命令
emStatus = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_STOP);
//注销采集回调
emStatus = GXUnregisterCaptureCallback(m_hDevice);
if (m_pBufferRGB != NULL)
{
delete[]m_pBufferRGB;
m_pBufferRGB = NULL;
}
if (m_pBufferRaw != NULL)
{
delete[]m_pBufferRaw;
m_pBufferRaw = NULL;
}
emStatus = GXCloseDevice(m_hDevice);
emStatus = GXCloseLib();
return 0;
}
C++ 接口
CCD采集的像素,该相机的图形格式GX_PIXEL_FORMAT_BAYER_GR8:Bayer Green-Red 8-bit 必备:https://blog.csdn.net/joe9280/article/details/46952947 |
利用回调函数进行显示
# 实时显示——使用Mat Opencv
#include"stdafx.h"
#include
#include
#include
#include
using namespace cv;
using namespace std;
//请用户提前配置好工程头文件目录,需要包含GalaxyIncludes.h
#include"GalaxyIncludes.h"//用户继承掉线事件处理类
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;
cout << objImageDataPointer->GetPixelFormat() << endl;
cout << GX_PIXEL_FORMAT_BAYER_GR8 << endl;
void* pRGB24Buffer = NULL;
//假设原始数据是BayerRG8图像
pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);
Mat test;
test.create(objImageDataPointer->GetHeight(), objImageDataPointer->GetWidth(), CV_8UC3);
memcpy(test.data, pRGB24Buffer, objImageDataPointer->GetPayloadSize() * 3);
namedWindow("测试", 0);
imshow("测试", test);
waitKey(10);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//声明事件回调对象指针
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;
}//打开第一台设备以及设备下面第一个流
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(500);
//注册远端设备事件:曝光结束事件【目前只有千兆网系列相机支持曝光结束事件】
//选择事件源
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;
}
文章图片
利用获取帧进行显示
条件:C++SDK配置、Opencv SDK配置
#include"stdafx.h"
#include
#include
#include
#include
using namespace cv;
using namespace std;
//请用户提前配置好工程头文件目录,需要包含GalaxyIncludes.h
#include"GalaxyIncludes.h"Mat src;
int _tmain(int argc, _TCHAR* argv[])
{
//初始化
IGXFactory::GetInstance().Init();
try
{
do
{
//枚举设备
gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
if (0 == vectorDeviceInfo.size())
{
cout << "无可用设备!" << endl;
break;
}//打开第一台设备以及设备下面第一个流
CGXDevicePointer ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(
vectorDeviceInfo[0].GetSN(),
GX_ACCESS_EXCLUSIVE);
CGXStreamPointer ObjStreamPtr = ObjDevicePtr->OpenStream(0);
//获取远端设备属性控制器
CGXFeatureControlPointer ObjFeatureControlPtr = ObjDevicePtr->GetRemoteFeatureControl();
//发送开采命令
ObjStreamPtr->StartGrab();
ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
//主程序
//采单帧
int a = 1;
while (a)
{
CImageDataPointer objImageDataPtr;
objImageDataPtr = ObjStreamPtr->GetImage(500);
//超时时间使用500ms,用户可以自行设定
if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)
{
//getchar();
//采图成功而且是完整帧,可以进行图像处理...
cout << "收到一帧图像!" << endl;
cout << "ImageInfo: " << objImageDataPtr->GetStatus() << endl;
cout << "ImageInfo: " << objImageDataPtr->GetWidth() << endl;
cout << "ImageInfo: " << objImageDataPtr->GetHeight() << endl;
cout << "ImageInfo: " << objImageDataPtr->GetPayloadSize() << endl;
cout << objImageDataPtr->GetPixelFormat() << endl;
cout << GX_PIXEL_FORMAT_BAYER_GR8 << endl;
//假设原始数据是BayerRG8图像,则 GX_BIT_0_7
void* pRGB24Buffer = NULL;
pRGB24Buffer = objImageDataPtr->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);
Mat test;
test.create(objImageDataPtr->GetHeight(), objImageDataPtr->GetWidth(), CV_8UC3);
memcpy(test.data, pRGB24Buffer, objImageDataPtr->GetPayloadSize() * 3);
namedWindow("测试", 0);
imshow("测试", test);
//waitKey(10);
test.copyTo(src);
//system("pause");
if (waitKey(20)==27)
{
a = 0;
break;
}
}
}//发送停采命令
ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
ObjStreamPtr->StopGrab();
//释放资源
ObjStreamPtr->Close();
ObjDevicePtr->Close();
} while (false);
}
catch (CGalaxyException&e)
{
cout << "错误码: " << e.GetErrorCode() << endl;
cout << "错误描述信息: " << e.what() << endl;
}
catch (std::exception&e)
{
cout << "错误描述信息: " << e.what() << endl;
} //反初始化库
IGXFactory::GetInstance().Uninit();
return 0;
}
文章图片
问题解决:
问题一【图示】:该问题为库的配置没有连接好,解决方案:查看配置(ilb、inc、dll)的文件缺省,检测完成,重启电脑。
文章图片
问题二【图示】:图片流转Mat的问题
文章图片
问题三【运行一次正常,如果手动中断程序,则不能再次访问相机】:
【#|机器视觉_相机开发(二)——大恒相机】只能重启相机电源,因为该相机没有自动清除网络占有
第四步:MFC联合SDK进行项目开发之一(MFC相机界面)
推荐阅读
- 数据结构和算法|LeetCode 的正确使用方式
- #|7.分布式事务管理
- #|算法设计与分析(Java实现)——贪心算法(集合覆盖案例)
- #|算法设计与分析(Java实现)—— 动态规划 (0-1 背包问题)
- #|阿尔法点亮LED灯(一)汇编语言
- #|Multimedia
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- 基础课|使用深度优先搜索(DFS)、广度优先搜索(BFS)、A* 搜索算法求解 (n^2 -1) 数码难题,耗时与内存占用(时空复杂度)对比(附((n^2 - 1) 数码问题控
- #|学习笔记 | Ch05 Pandas数据清洗 —— 缺失值、重复值、异常值
- win10|搏一搏 单车变摩托,是时候捣鼓一下家中的小米电视机啦。