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调用的时候,内存释放就是多么的悲剧。这里的启示:有时候换一种方式处理问题更好。
下面我分别演示 彩色图像 和 灰度图像的读取。
需要添加的头文件等:
彩色图像C++代码:
C#调用代码:
其中,opencv.dll 为自己制作的C++的dll,pictureBox1 为C#中的控件。
灰度图像C++代码:
可以看到代码和彩色图像C++代码并没有太大区别,但是C#中会有区别,代码如下:
这个CvToolbox的结构体如下:
总结:图像用IplImage 读取很重要,否则会报错。
这样大家就可以顺利读取cv::Mat 的中的数据啦!!!
有什么不明白的可以留言!!!!
之前有将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 的中的数据啦!!!
有什么不明白的可以留言!!!!
相关文章推荐
- C#高级知识点&(ABP框架理论学习高级篇)——白金版
- C#基础(四)
- C#字符串操作--获取字符或字符串的位置、数量
- 关于基础信息的结构设计
- C#中类及类型成员访问权限修饰符
- 【C#进阶系列】21 托管堆和垃圾回收
- 【C#进阶系列】21 托管堆和垃圾回收
- C# List深拷贝和浅拷贝的简单案例说明
- [C#]大小端字节序(Big Endian和Little Endian)
- C# 解决 调用线程非安全的控件xx不是在本线程上创建 异常
- c#使用wpd读取便携式设备信息二
- C#编程基础 实验(6) (1-3)
- C#—结构与枚举
- c#---读文件
- C#单例模式使用
- C#实现优先队列 基于二叉堆 附使用案例
- C# 使用Tuple传递多个参数
- C# Interlocked 笔记
- C# Timer类详解
- C# get