VS2015+OpenCV+大恆MER-Gx系列工業相機
阿新 • • 發佈:2019-01-06
VS2015+OpenCV+大恆MER-Gx系列工業相機
本人C++和OpenCV基礎比較薄弱,VS2015龐雜的處理介面又讓人應接不暇。之前偶爾使用網路攝像頭,勉強能夠完成基礎操作;偶爾進行離線處理,也還應付的過來。這次專案需求,購買了大恆MER-Gx系列工業相機(GigE網路介面),離我的專業知識跨度很大,因此查了很多資料,在此分享一下。
1.實驗所需
1)VS2015
2)OpenCV,解壓並完成環境變數配置
3)大恆MER-Gx系列工業相機
2.建立C++專案
1)新建Win32控制檯專案,切記,選擇空專案!否則會遇到我也難以解釋的問題…
2)右鍵專案——屬性——VC++目錄——包含目錄,先新增OpenCV的三個目錄(…\include以及其兩個子目錄…\include\opencv,…\include\opencv2),然後新增大恆SDK的\VC SDK 和 \C++ SDK兩個inc目錄。(一共5個目錄)
3)同樣在VC++目錄下,點選庫目錄,先新增OpenCV的庫目錄,再新增大恆SDK的\VC SDK 和 \C++ SDK兩個lib目錄。(一共3個目錄)
4)回到專案——屬性,我們選擇連結器——輸入 下的“附加依賴項”,手動輸入需要新增的庫檔案。首先是opencv庫目錄下的*d.lib檔案,然後是大恆SDK目錄下的三個.lib檔案。
3. 新增原始檔
右鍵原始檔,新增,自己命名吧。
然後複製、執行下列程式碼:
記得執行之前將解決方案改成debug和x64(當然還是根據自己的來)。
#include "GxIAPI.h" #include "DxImageProc.h" #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> 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; }
對了,執行程式碼時會提示DxImageProc.h檔案裡有一行執行不了,具體是打不開“stdafx.h”,我遮蔽了就好了。應該是沒有適配VS2015的問題。
4.感言
現在終於可以聯合使用OpevCV與大恆SDK,成功打開了大恆相機!接下來,讀懂程式碼,在合適的地方做修改就好了!