1. 程式人生 > >opencv筆記8----從大恆工業攝像頭讀取影象

opencv筆記8----從大恆工業攝像頭讀取影象

採用大恆MER系列工業攝像機,不能用opencv自帶函式開啟攝像頭,需要用廠商提供的API

工業攝像頭採集的圖片格式為BYTE,opencv需要從記憶體中讀取BYTE,轉化成IplImage *(in C) 或者Mat( in c++)

#include "stdafx.h"
#include "camera.h"
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;


GX_DEV_HANDLE hDevice = NULL; 
 static int keycode;

MERCamera::MERCamera()
{
	GX_STATUS status = GX_STATUS_SUCCESS;
	int64_t nValue  = 0;
	
	GXInitLib();
	status = GXOpenDeviceByIndex(1, &hDevice);
	if(status != GX_STATUS_SUCCESS)
	{
			std::cout<<"open error"<<std::endl;
			return;
	}
}

MERCamera::~MERCamera()
{
	GX_STATUS emStatus = GX_STATUS_SUCCESS;
	if(m_bIsSnaping)
	{
		EndContinuesMode();
	}

	emStatus = GXCloseDevice(hDevice);
	if(emStatus != GX_STATUS_SUCCESS)
	{ 
		std::cout<<"close error"<<std::endl;
	} 
	
	//關閉裝置庫
	emStatus = GXCloseLib();
	if(emStatus != GX_STATUS_SUCCESS)
	{ 
		std::cout<<"close lib error"<<std::endl;
	} 
}

void MERCamera::InitCamera()
{
	GX_STATUS status = GX_STATUS_SUCCESS;
	int64_t nValue  = 0;

	m_bIsSnaping = false;
	status = GXGetEnum(hDevice, GX_ENUM_PIXEL_FORMAT, &m_nPixelFomat);
	//獲取寬度(需在停止採集狀態下設定)
	status = GXGetInt(hDevice, GX_INT_WIDTH, &nValue);
	m_nImageWidth = (int)nValue;
 
	//獲取高度(需在停止採集狀態下設定)
	status = GXGetInt(hDevice, GX_INT_HEIGHT, &nValue);
	m_nImageHeight = (int)nValue;
 
	//獲取圖象資料大小
	status = GXGetInt(hDevice, GX_INT_PAYLOAD_SIZE, &nValue);
	m_nPayLoadSize = (int)nValue;	
	//設定採集模式。一般相機的預設採集模式為連續模式。
	int64_t nAcqMode = GX_ACQ_MODE_CONTINUOUS;
    status = GXSetEnum(hDevice, GX_ENUM_ACQUISITION_MODE, nAcqMode);
 
	 
	do 
	{
		m_pBufferRaw8 = new BYTE[m_nImageWidth * m_nImageHeight];
		if (m_pBufferRaw8 == NULL)
		{
			status = GX_STATUS_ERROR;
			break;
		}
		
		//為儲存RGB影象資料開闢空間
		m_pBufferRGB = new BYTE[m_nImageWidth * m_nImageHeight * 3];
		if (m_pBufferRGB == NULL)
		{
			status = GX_STATUS_ERROR;
			break;
		}
		
		//為儲存原始影象資料開闢空間
		m_pBufferRaw = new BYTE[m_nPayLoadSize];
		if (m_pBufferRaw == NULL)
		{
			status = GX_STATUS_ERROR;
			break;
		}
		
	} while (0);
	if (status != GX_STATUS_SUCCESS)
	{
		if (m_pBufferRaw8 != NULL)
		{
			delete[]m_pBufferRaw8;
			m_pBufferRaw8 = NULL;
		}
		if (m_pBufferRaw != NULL)
		{
			delete[]m_pBufferRaw;
			m_pBufferRaw = NULL;
		}
		if (m_pBufferRGB != NULL)
		{
			delete[]m_pBufferRGB;
			m_pBufferRGB = NULL;
		}
	}
 
}

void MERCamera::StartContinuesMode()
{
	GX_STATUS status = GX_STATUS_SUCCESS;
	InitCamera();
	//註冊影象處理回撥函式
	 status = GXRegisterCaptureCallback(hDevice, NULL,OnFrameCallbackFun); 
	if(!m_bIsSnaping)
	{	
		//傳送開採命令
		status = GXSendCommand(hDevice, GX_COMMAND_ACQUISITION_START);   
		m_bIsSnaping = true;
	}
	while(1)
	{
		if(keycode == 'q') EndContinuesMode();
	}
}

void MERCamera::EndContinuesMode()
{  
	GX_STATUS status = GX_STATUS_SUCCESS;
	if(m_bIsSnaping)
	{
		//傳送停採命令
		status = GXSendCommand(hDevice, GX_COMMAND_ACQUISITION_STOP);
		//登出採集回撥
		status = GXUnregisterCaptureCallback(hDevice);
		m_bIsSnaping = false;
	}
}
//fuction:ProcessImage(BYTE* pImageBuf)
//功能:raw格式影象轉換為RGB圖
void MERCamera::ProcessImage(BYTE *pImageBuf)
{
	//m_objDrawImg.Enter();
	memcpy(m_pBufferRaw, pImageBuf, m_nPayLoadSize);
		
	switch(m_nPixelFomat)
	{
	//當資料格式為12位時,位數轉換為4-11
	case GX_PIXEL_FORMAT_MONO12:
		//將12位格式的影象轉換為8位格式
		DxRaw16toRaw8(m_pBufferRaw, m_pBufferRaw8, m_nImageWidth, m_nImageHeight, DX_BIT_4_11);

		//將轉換完成後的8點陣圖轉換為RGB圖,以供顯示
		DxRaw8toRGB24(m_pBufferRaw8, m_pBufferRGB, m_nImageWidth, m_nImageHeight, RAW2RGB_NEIGHBOUR, (DX_PIXEL_COLOR_FILTER)NONE, TRUE);
		break;
		
	//當資料格式為12位時,位數轉換為2-9
	case GX_PIXEL_FORMAT_MONO10:
		//將12位格式的影象轉換為8位格式
		DxRaw16toRaw8(m_pBufferRaw, m_pBufferRaw8, m_nImageWidth, m_nImageHeight, DX_BIT_2_9);

		//將轉換完成後的8點陣圖轉換為RGB圖,以供顯示
		DxRaw8toRGB24(m_pBufferRaw8, m_pBufferRGB, m_nImageWidth, m_nImageHeight, RAW2RGB_NEIGHBOUR, (DX_PIXEL_COLOR_FILTER)NONE, TRUE);
		break;

	//當資料格式為8位時,將8點陣圖轉換為RGB圖,以供顯示
	case GX_PIXEL_FORMAT_MONO8:
		DxRaw8toRGB24(m_pBufferRaw, m_pBufferRGB, m_nImageWidth, m_nImageHeight, RAW2RGB_NEIGHBOUR, (DX_PIXEL_COLOR_FILTER)NONE, TRUE);	
		break;
		
	default:
		//m_objDrawImg.Leave();
		return;
	}

	m_objDrawImg.Leave();
}

//影象回撥處理函式
void __stdcall MERCamera::OnFrameCallbackFun(GX_FRAME_CALLBACK_PARAM* pFrame)
{
	MERCamera *pDlg = (MERCamera*)(pFrame->pUserParam);
   if (pFrame->status == 0)
   {
        //影象獲取成功
		//對影象進行處理...
	   // cout<<"successful"<<endl;
	   pDlg->DrawImage((BYTE*)pFrame->pImgBuf, pFrame->nImgSize);
   }   
   return;    
}
 
 void MERCamera::DrawImage(BYTE *pImageBuf, int nImageSize)
{ 
 
	cv::namedWindow("window",0);
	cv::Mat img(Size(2592,1944),CV_8U,pImageBuf );
	flip(img,img,-1);
	cv::imshow("window",img);
	cv::waitKey(30);
	 
}