opencv与Labview的结合(Dll调用)

为何会有把两者结合这个想法,主要是在接触过这两种工具后,发现它们对图像处理有本身独特的优点,但也有本身的缺点,借助C++,opencv能够实现许多本身想实现的功能,可是在界面设计上得花另外一番功夫,Labview的长处就在于它的界面设计简单,控件拖拽所见即所得,与QT有点相似,固然QT的跨平台性是labview比不了的,但是labview在功能实现上的快速性和简洁性也是较大的优点,对labview稍微熟悉一点便可实现许多强大的功能。(固然,用什么都只是工具,主要是掌握方法与思想)ios

话很少说,进入正题:软件版本Labview2015 64位英文版(要安装VISION Acquisition Software组件) 和 Visual Studio 2015,注意生成的DLL要与Labview版本一致,都是64位才能够,不然会有其余的调用问题数组

1、从Labview传递图像数据到opencv中,通过图像处理后又将处理结果返回到Labview显示。(源图片来源于Labview这端)函数

我这里有两种图像数据来源,一种是直接调用本地图片,另外一种是经过labview调用摄像头传输视频,能够作到实时的图像传输和图像处理。两者的区别只在Labview的设计上有稍许差异,Dll的内容是一致的。工具

既然DLL的内容一致,那就先介绍DLL的设计,前面几篇中有讲到VS如何建立DLL,能够翻看前面的内容,这里是调用软件发生改变,再也不是由VS本身调用,而是经过Labview来调用,步骤差异不大。测试

dll.h头文件的定义以下:ui

#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类型,因此要经过指针/数组来实现数据的传递。spa

下面是对图像处理函数主体,完成的是一个调用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的设计3d

一、源图像来源于本地图片文件,Labview前面板可看到一下效果,在运行前先选择文件目录便可。指针

 

 后面板逻辑:调用动态连接库控件的位置在Connectivity->Libraries & Executables->Call Library Function Node

 

 

 调用DLL参数设置,尤为注意指针data的数据类型为Array,Dimention为2

  

 

 

二、源图像来源于usb摄像头,这种方式须要安装NI VISION Acquisition组件,也就是下图所示的控件

前面板以下所示,图一是摄像头原图,图二是灰度图,图三是从opencv通过Canny边缘检测后返回的结果图

 

 后面板逻辑以下:这里包括了两个没讲的DLL,能够先跳过这看完另外两个DLL的解释

 

 

 2、从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,这里的图片传输的都是灰度图像,这是为何,直接改变数组指针的类型能够实现彩色图像的传输吗?这个我也没测试过,下一篇介绍如何实现彩色图像的传输。

相关文章
相关标签/搜索