目錄
第一步:安裝Gaalxy_view軟件:Galaxy_V18.06.25.01_X86_Win_cn.exe
第二步:測試相機:MER-1070-10GC相機,應用軟件打開該相機體驗。
第三步:利用SDK-API進行編程,主要功能(開啓、採集、錄像、停止、關閉)
第一步:安裝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 <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <GxIAPI.h>
#include <DxImageProc.h>
using namespace std;
using namespace cv;
GX_DEV_HANDLE m_hDevice; ///< 設備句柄
BYTE *m_pBufferRaw; ///< 原始圖像數據
BYTE *m_pBufferRGB; ///< RGB圖像數據,用於顯示和保存bmp圖像
int64_t m_nImageHeight; ///< 原始圖像高
int64_t m_nImageWidth; ///< 原始圖像寬
int64_t m_nPayLoadSize;
int64_t m_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 <m_nImageHeight; i++) {
memcpy(m_pImageBuffer + i*m_nImageWidth, m_pBufferRaw + (m_nImageHeight - i - 1)*m_nImageWidth, (size_t)m_nImageWidth);
}
IplImage* src;
src = cvCreateImage(cvSize(m_nImageWidth, m_nImageHeight), 8, 1);
src->imageData = (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 = (char*)m_pBufferRGB;
// cvSaveImage("./test.bmp", cv_Image);
//test.data = 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_t nDeviceNum = 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);
bool bColorFliter = 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 |
條件:C++SDK配置、Opencv SDK配置
利用回調函數進行顯示
# 實時顯示——使用Mat Opencv
#include"stdafx.h"
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\opencv.hpp>
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<iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\opencv.hpp>
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的問題
問題三【運行一次正常,如果手動中斷程序,則不能再次訪問相機】:
只能重啓相機電源,因爲該相機沒有自動清除網絡佔有