OK,上一篇講完了opencv與Labview實現了黑白圖像的傳輸,結尾有提到彩色圖像的傳輸問題,我也自己試了一下,直接改變unsigned int8 char *data指針為unsigned int32 char *data,最后Labview並沒有成功接收到彩色圖像,經過網上的查找,有提到說這兩者要是實現彩色圖像傳輸,要借助圖像的分離與融合,簡單說就是把RGB圖像的R、G、B三個通道拆分開來,然后逐個通道進行傳輸,有了上一篇的基礎,已經知道了如何傳輸8bit的圖片,實質就是單通道的功能,那么在實現彩色圖像傳輸上也就有了更大的方便性。
原理比較簡單,實現起來應該也不難,結果本人在嘗試過程中卻遇到了許多小問題,在這個過程中我會把要特別注意的細節問題用不同顏色注釋:
首先是實現從opencv傳輸和一幅圖像到Labview
關於DLL的創建也不再復述,不知道的可以查看往期的文章,這里主要講DLL里面的實現代碼
定義圖像輸出的函數名為outImage,函數主體如下:
_declspec(dllexport) extern void outImage(int rows, int cols, unsigned __int8 *imageR, unsigned __int8 *imageG, unsigned __int8 *imageB) { Mat ImgSrc = imread("E:\\study\\VS2015\\practice\\shumaguang\\shumaguang\\30.jpg");//read the image; vector<Mat>sbgr(ImgSrc.channels()); split(ImgSrc, sbgr); Mat temp1(rows, cols, CV_8U, &imageR[0]); Mat temp2(rows, cols, CV_8U, &imageG[0]); Mat temp3(rows, cols, CV_8U, &imageB[0]); //cvtColor(ImgSrc, temp1, CV_BGR2GRAY); sbgr[2].copyTo(temp1); sbgr[1].copyTo(temp2); sbgr[0].copyTo(temp3); }
可以看到,函數參數里面定義了三個unsigned __int8 *的指針,這三個指針分別會關聯到RGB三個通道圖像,函數實現的是讀取一張本地文件圖片,將這張圖片三個通道拆分后存到一個vector中,然后將三個通道分別復制到指針所指向的圖像上。
這里要注意兩點:
1、圖像復制要采用深拷貝,而不能使用淺拷貝,也就是不能直接使用temp1=sbgr[0],而要用sbgr[0].copyTo(temp3);最開始我就因為這個原因卡了許久。關於深拷貝、淺拷貝的差別可自行百度
2、opencv里面Mat圖像的RGB三個通道順序是BGR,所以在進行拷貝時要注意順序,sbgr[0]對應的是B通道,要對應到參數里的imagB指針,最后在labview里接收到的RGB按本來的順序即可,否則合並后的圖像與原圖不符。
反過來是實現從Labview傳輸圖片到opencv中
在DLL中定義接收函數名為getimage,函數主體如下:
_declspec(dllexport) extern void getImage(int rows, int cols, unsigned __int8 *imageR, unsigned __int8 *imageG, unsigned __int8 *imageB) { Mat Image; Mat srcImageR(rows, cols, CV_8U, &imageR[0]); Mat srcImageG(rows, cols, CV_8U, &imageG[0]); Mat srcImageB(rows, cols, CV_8U, &imageB[0]); Mat merger_array_src[] = { srcImageB,srcImageG,srcImageR }; merge(merger_array_src,3,Image); }
也是三個指針參數,分別接收三個通道的圖像數據,最后將得到的三通道進行融合
接着就是Labview的代碼主體了:
首先給大家看后面板要注意的事項,后面板邏輯如下:
圖片中上半部分是實現從Labview傳輸到opencv中,可以看到將攝像頭采集到的RGB圖像通過IMAQ ExtractSingleColorPlane函數拆分得到R、G、B三個通道圖像,特別注意IMAQ ExtractSingleColorPlane這個函數一定要給Image Dst接線端一個圖片緩存區,否則一定會出問題,后續則是將圖像轉化為數組,連接到DLL getimage函數的參數接口上。
下圖是調用getimage函數的參數設置
后面板下半部分就是實現從opencv傳輸一幅圖片到Labview上進行顯示
可以看到首先調用的還是getimagesize函數,該函數在上一篇有介紹到,接着就是初始化三通道的數據為0,注意三個通道一定要初始化大小和數值,最后調用IMAQ ReplaceColorPlane 函數實現三通道的合並,最后說一點要注意的,所有IMAQ Creat創建的圖像要注意圖片的類型,這里涉及到32位和8位圖的互相轉換,確保所有圖片格式正確保證程序的准確性。
最后就是前面板的程序運行結果圖片了
可以看到上半部分就是攝像頭的捕捉畫面,拆分為R、G、B三個通道進行顯示了
下半部分就是接收到的來自opencv發送來的三個通道的圖片,以及最后組合融合的彩色圖片。效果完美!