您的位置:首页 > 编程语言 > C#

C#调用 opencv cv::Mat 图像, 采用折中方法

2016-04-15 08:56 537 查看
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调用的时候,内存释放就是多么的悲剧。这里的启示:有时候换一种方式处理问题更好。

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

需要添加的头文件等:

#include "stdafx.h"

#define DLL_API extern "C" _declspec(dllexport)

#include <opencv2\opencv.hpp>


彩色图像C++代码:

DLL_API uchar * _stdcall run1(char* filename, int & width, int & height, int & step )
{

IplImage* uu = cvLoadImage(filename);
IplImage* dst1 = cvCreateImage(cvSize(uu->width,uu->height),8,1);
cvCvtColor(uu,dst1,CV_RGB2GRAY);
Mat ss(uu);
uchar * data = new uchar[uu->width*uu->height*3];

data= ss.data;
width = ss.size().width;
height = ss.size().height;
step = ss.step;

return data;
}


C#调用代码:

[DllImport("opencv.dll")]
public static extern IntPtr run1(string a , out int width, out int height, out int step);
private void button1_Click(object sender, EventArgs e)
{
string filename;
OpenFileDialog op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
filename = op.FileName;
int width, height, step;
IntPtr dst =  run1(filename,out width,out height, out step);
Bitmap img = new Bitmap(width, height, step, System.Drawing.Imaging.PixelFormat.Format24bppRgb, dst);
pictureBox1.Image = img;

}
}


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

灰度图像C++代码:

DLL_API uchar * _stdcall run1(char* filename, int & width, int & height, int & step )
{

IplImage* uu = cvLoadImage(filename);
IplImage* dst1 = cvCreateImage(cvSize(uu->width,uu->height),8,1);
cvCvtColor(uu,dst1,CV_RGB2GRAY);
Mat ss(dst1);
uchar * data = new uchar[uu->width*uu->height*3];

data= ss.data;
width = ss.size().width;
height = ss.size().height;
step = ss.step;
return data;

}


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

[DllImport("raildetection.dll")]
public static extern IntPtr run1(string a , out int width, out int height, out int step);
private void button1_Click(object sender, EventArgs e)
{
string filename;
OpenFileDialog op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
filename = op.FileName;
int width, height, step;
IntPtr dst =  run1(filename,out width,out height, out step);
Bitmap img = new Bitmap(width, height, step, <strong>System.Drawing.Imaging.PixelFormat.Format8bppIndexed</strong>,dst);
<strong>img.Palette = CvToolbox.GrayscalePalette;</strong>
pictureBox1.Image = img;

}
}
注:颜色加粗部分为区别部分

这个CvToolbox的结构体如下:

public static class CvToolbox
{

// #region Color Pallette
/// <summary>
/// The ColorPalette of Grayscale for Bitmap Format8bppIndexed
/// </summary>
public static readonly ColorPalette GrayscalePalette = GenerateGrayscalePalette();

private static ColorPalette GenerateGrayscalePalette()
{
using (Bitmap image = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
ColorPalette palette = image.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
return palette;
}
}
}


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

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


有什么不明白的可以留言!!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: