C#调用 opencv cv::Mat 图像

C# 用于界面的制作要比MFC高效许多,但是有时候为了效率需要用C++程序,这样就涉及到了把C++核心算法程序做成dll,在C#中进行调用。


之前有将IplImage*  这类结构用于C#调用,  整体结构较为复杂,现在我将更方便有效的方法介绍给大家,如果有更好的方法可以分享给我。


将C++ IplImage 图像用C#读取,     将C++ IplImage 图像用C#读取(二)



实现机制:

当然这里需要注意一个问题,就是转换的本质都是采用IplImage*    但是之前处理可以采用cv::Mat  进行各种处理

后面需要用到  IplImage* dst = &IplImage(src); (浅拷贝)   需要通过深拷贝 得到dst1  (代码如下 :  cvCopy(dst,dst1);)  再通过后面文中的方式就可以轻松传递数据啦。

Mat  在C++中很好用,不用处理释放的问题,但是再制作dll调用的时候,内存释放就是多么的悲剧。这里的启示:有时候换一种方式处理问题更好。


下面我分别演示 彩色图像  和 灰度图像的读取。


需要添加的头文件等:

[cpp] view plain copy print ?
  1. #include "stdafx.h"  
  2.   
  3.   
  4. #define DLL_API extern "C" _declspec(dllexport)       
  5.    
  6. #include     

彩色图像C++代码:


[cpp] view plain copy print ?
  1. DLL_API uchar * _stdcall run1(char* filename, int & width, int & height, int & step )    
  2. {    
  3.     
  4.         IplImage* uu = cvLoadImage(filename);    
  5.     IplImage* dst1 = cvCreateImage(cvSize(uu->width,uu->height),8,1);  
  6.     cvCvtColor(uu,dst1,CV_RGB2GRAY);  
  7.     Mat ss(uu);  
  8.     uchar * data = new uchar[uu->width*uu->height*3];  
  9.   
  10.     data= ss.data;  
  11.     width = ss.size().width;  
  12.     height = ss.size().height;  
  13.     step = ss.step;  
  14.   
  15.     return data;  
  16. }  

C#调用代码:

[csharp] view plain copy print ?
  1. [DllImport("opencv.dll")]  
  2.     public static extern IntPtr run1(string a , out int width, out int height, out int step);   
  3.     private void button1_Click(object sender, EventArgs e)  
  4.     {  
  5.         string filename;  
  6.         OpenFileDialog op = new OpenFileDialog();  
  7.         if (op.ShowDialog() == DialogResult.OK)  
  8.         {  
  9.             filename = op.FileName;  
  10.             int width, height, step;  
  11.             IntPtr dst =  run1(filename,out width,out height, out step);  
  12.            Bitmap img = new Bitmap(width, height, step, System.Drawing.Imaging.PixelFormat.Format24bppRgb, dst);  
  13.            pictureBox1.Image = img;  
  14.   
  15.         }  
  16.     }  

其中,opencv.dll 为自己制作的C++的dll,pictureBox1 为C#中的控件。



灰度图像C++代码:

[cpp] view plain copy print ?
  1. DLL_API uchar * _stdcall run1(char* filename, int & width, int & height, int & step )    
  2. {    
  3.     
  4.     IplImage* uu = cvLoadImage(filename);    
  5.     IplImage* dst1 = cvCreateImage(cvSize(uu->width,uu->height),8,1);  
  6.     cvCvtColor(uu,dst1,CV_RGB2GRAY);  
  7.     Mat ss(dst1);  
  8.     uchar * data = new uchar[uu->width*uu->height*3];  
  9.   
  10.     data= ss.data;  
  11.     width = ss.size().width;  
  12.     height = ss.size().height;  
  13.     step = ss.step;  
  14.     return data;  
  15.   
  16. }  

可以看到代码和彩色图像C++代码并没有太大区别, 但是C#中会有区别,代码如下

[csharp] view plain copy print ?
  1. [DllImport("raildetection.dll")]  
  2. public static extern IntPtr run1(string a , out int width, out int height, out int step);   
  3. private void button1_Click(object sender, EventArgs e)  
  4. {  
  5.     string filename;  
  6.     OpenFileDialog op = new OpenFileDialog();  
  7.     if (op.ShowDialog() == DialogResult.OK)  
  8.     {  
  9.         filename = op.FileName;  
  10.         int width, height, step;  
  11.         IntPtr dst =  run1(filename,out width,out height, out step);  
  12.        Bitmap img = new Bitmap(width, height, step, System.Drawing.Imaging.PixelFormat.Format8bppIndexed,dst);                 
  13.        img.Palette = CvToolbox.GrayscalePalette;   
  14.        pictureBox1.Image = img;  
  15.   
  16.     }  
  17. }  
注:颜色加粗部分为区别部分

这个CvToolbox的结构体如下:

[csharp] view plain copy print ?
  1. public static class CvToolbox  
  2.     {  
  3.   
  4.        // #region Color Pallette  
  5.         ///   
  6.         /// The ColorPalette of Grayscale for Bitmap Format8bppIndexed  
  7.         ///   
  8.         public static readonly ColorPalette GrayscalePalette = GenerateGrayscalePalette();  
  9.   
  10.         private static ColorPalette GenerateGrayscalePalette()  
  11.         {  
  12.             using (Bitmap image = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))  
  13.             {  
  14.                 ColorPalette palette = image.Palette;  
  15.                 for (int i = 0; i < 256; i++)  
  16.                 {  
  17.                     palette.Entries[i] = Color.FromArgb(i, i, i);  
  18.                 }  
  19.                 return palette;  
  20.             }  
  21.         }  
  22.     }  


总结:图像用IplImage 读取很重要,否则会报错。

这样大家就可以顺利读取cv::Mat 的中的数据啦!!!




原文地址:http://blog.csdn.net/yeyang911/article/details/51158621

你可能感兴趣的:(C#调用 opencv cv::Mat 图像)