opencv筆記8----從大恆工業攝像頭讀取影象
阿新 • • 發佈:2019-01-05
採用大恆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); }