機器視覺_相機開發(二)——大恆相機

目錄

第一步:安裝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 <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

必備:https://blog.csdn.net/joe9280/article/details/46952947

條件: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的問題

問題三【運行一次正常,如果手動中斷程序,則不能再次訪問相機】:

只能重啓相機電源,因爲該相機沒有自動清除網絡佔有

第四步:MFC聯合SDK進行項目開發之一(MFC相機界面)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章