opencv與Labview的結合(Dll調用)


為什么會有把二者結合這個想法,主要是在接觸過這兩種工具后,發現它們對圖像處理有自己獨特的優勢,但也有自己的缺點,借助C++,opencv可以實現許多自己想實現的功能,但是在界面設計上得花另一番功夫,Labview的長處就在於它的界面設計簡單,控件拖拽所見即所得,與QT有點類似,當然QT的跨平台性是labview比不了的,可是labview在功能實現上的快速性和簡潔性也是較大的優勢,對labview稍微熟悉一點即可實現許多強大的功能。(當然,用什么都只是工具,主要是掌握方法與思想)

話不多說,進入正題:軟件版本Labview2015 64位英文版(要安裝VISION Acquisition Software組件) 和 Visual Studio 2015,注意生成的DLL要與Labview版本一致,都是64位才可以,否則會有其他的調用問題

一、從Labview傳遞圖像數據到opencv中,經過圖像處理后又將處理結果返回到Labview顯示。(源圖片來源於Labview這端)

我這里有兩種圖像數據來源,一種是直接調用本地圖片,另一種是通過labview調用攝像頭傳輸視頻,可以做到實時的圖像傳輸和圖像處理。二者的區別只在Labview的設計上有稍許差別,Dll的內容是一致的。

既然DLL的內容一致,那就先介紹DLL的設計,前面幾篇中有講到VS如何創建DLL,可以翻看前面的內容,這里是調用軟件發生改變,不再是由VS自己調用,而是通過Labview來調用,步驟差別不大。

dll.h頭文件的定義如下:

#pragma once
#include<iostream>
#ifdef DLL_IMPLEMENT
#define DLL_API _declspec(dllimport)
#else
#define DLL_API _declspec(dllexport)
#endif
extern "C" DLL_API   void add2(int rows, int cols, unsigned __int8 *data);
extern "C" DLL_API  int ImgdatatoLabview(unsigned __int8 *imgdata);
extern "C" DLL_API  int getimagesize(int* rows, int* cols);

void add2(int rows, int cols, unsigned __int8 *data)是接收從labview傳來的數據進行圖像處理,注意參數類型,unsigned __int8 *data是指針類形,由於opencv中的圖片數據類型是Mat型,而Labview里面沒有Mat類型,所以要通過指針/數組來實現數據的傳遞。

下面是對圖像處理函數主體,完成的是一個調用opencv里的Canny邊緣提取函數。可以看到將image_src與關聯到指針的首地址,經過圖像處理后,最后的結果又返回到了image_src上,所以即便該函數沒有返回值,也是能實現圖像經過處理后傳回到Labview。

_declspec(dllexport) extern void add2(int rows, int cols, unsigned __int8 *data)//接收labview傳過來的圖像數據進行處理,圖片來源於labview的采集

{

    Mat image_src(rows, cols, CV_8U, &data[0]);

    /* Insert code here */

    Mat temp;

    boxFilter(image_src, temp, -1, Size(5, 5));
    Canny(temp, image_src, 150, 100, 3);

}

Labview的設計

1、源圖像來源於本地圖片文件,Labview前面板可看到一下效果,在運行前先選擇文件目錄即可。

 

 后面板邏輯:調用動態鏈接庫控件的位置在Connectivity->Libraries & Executables->Call Library Function Node

 

 

 調用DLL參數設置,尤其注意指針data的數據類型為Array,Dimention為2

  

 

 

2、源圖像來源於usb攝像頭,這種方式需要安裝NI VISION Acquisition組件,也就是下圖所示的控件

前面板如下所示,圖一是攝像頭原圖,圖二是灰度圖,圖三是從opencv經過Canny邊緣檢測后返回的結果圖

 

 后面板邏輯如下:這里包括了兩個沒講的DLL,可以先跳過這看完另外兩個DLL的解釋

 

 

 二、從opencv傳遞圖像到Labview,即源圖像來源於opencv(本地文件或者調用攝像頭都可以)

其實前面的功能也已經實現了將處理好的圖像返回到labview顯示,這里只是再更直觀的體現一下圖片來源於opencv

這里就涉及到另外兩個DLL的使用一個是getimagesize獲取圖像文件大小的(獲取行列數才可以在labview里初始化數組的大小),另一個是 ImgdatatoLabview實現圖像的處理和傳遞(其實和第一個DLL功能類似,只是圖像大小需要通過另一個DLL獲得)

getimagesize功能代碼實現:可以看到獲得的圖像來源opencv調用本地文件

_declspec(dllexport) extern int getimagesize(int* rows, int* cols)
{
    Mat ImgSrc = imread("E:\\study\\VS2015\\practice\\shumaguang\\shumaguang\\30.jpg");//read the image;
    *rows = ImgSrc.rows;
    *cols = ImgSrc.cols;
    return 0;
}

代碼其實很簡單,只是需要注意從opencv獲取的行列信息要以指針的形式傳出,所以看到函數的參數都是指針。

所以在labview調用該DLL的參數設置上也要注意數據類型,如下圖所示

 

 

 

 

ImgdatatoLabview功能代碼實現:將原圖由RGB轉換為GRAY類型傳遞到Labview

_declspec(dllexport) extern int ImgdatatoLabview(int rows,int cols,unsigned __int8 *imgdata)

{

    Mat ImgSrc = imread("E:\\study\\VS2015\\practice\\shumaguang\\shumaguang\\30.jpg");//read the image;
    Mat img(rows, cols, CV_8U, &imgdata[0]);
    cvtColor(ImgSrc, img, CV_BGR2GRAY);
    return 0;
}

代碼也比較簡單:

參數rows和cols就是接收來自getimagesize函數的返回值,而*imgdata指針關聯到圖片,和第一個DLL功能基本一致

同樣注意該指針參數在Labview的設置     二維數組

 

 

 Labview最后的功能實現,第四張圖片就是得到的灰度圖片,前面板如下所示,后面板和第一部分里的一樣,就不再貼圖了。

 

 有心人可以發現這里不管是從Labview傳輸圖片到opencv還是從opencv傳輸到Labview,這里的圖片傳輸的都是灰度圖像,這是為什么,直接改變數組指針的類型可以實現彩色圖像的傳輸嗎?這個我也沒測試過,下一篇介紹如何實現彩色圖像的傳輸。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM