上次写了一个让OpenCV的IplImage显示在VC的窗体上的函数,这次借助于EmguCV来写一个让OpenCV的IplImage显示在C#的PictureBox上的函数,当然了,其中有一个值得注意的地方,那就是将EmguCV中IntPtr类型转化为EmguCV中的结构图MIplImage类型。因为MIplImage类型是和OpenCV中的IplImage类型一样的,只要进行转换之后,我们才能使用MIplImage结构体中的imageData,height,width,widthStep等数据。当然在C#中要添加EmguCV的几个引用的Dll文件,更多配置内容看我博客其他相关文章。
下面是整个窗体的程序:(红色字体部分为主要程序)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Emgu.Util;
using Emgu.CV;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace ShowIplImage
{
public partial class Form1 : Form
{
IntPtr eof = new IntPtr();
IntPtr src=new IntPtr();
public Form1()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "BMP files(*.bmp)|*.bmp|JPG files(*.jpg)|*.jpg|All files(*.*)|*.*";
if(ofd.ShowDialog()!=DialogResult.OK)
{
return;
}
src = CvInvoke.cvLoadImage(ofd.FileName, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR);
if(src==eof)
{
return;
}
ShowIplImageInWindow(src);
}
private void ShowIplImageInWindow(IntPtr src)
{
MIplImage img = (MIplImage)Marshal.PtrToStructure(src, typeof(MIplImage));
Bitmap disp = new Bitmap(img.width, img.height,PixelFormat.Format24bppRgb);
BitmapData bmp = disp.LockBits(new Rectangle(0,0,img.width, img.height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
long linebytes = (img.width * 24 + 31) / 32 * 4;
unsafe
{
byte* pixel = (byte*)bmp.Scan0.ToPointer();
if(img.nChannels==3)
{
for (int i = 0; i < img.height; i++)
{
for (int j = 0,n=0; j < img.width * 3; j++,n++)
{
byte b = ((byte*)img.imageData + img.widthStep * i)[3*j];
byte g = ((byte*)img.imageData + img.widthStep * i)[3 * j + 1];
byte r = ((byte*)img.imageData + img.widthStep * i)[3 * j + 2];
*(pixel + linebytes * (i) + n) = b;
n++;
*(pixel + linebytes * (i) + n) = g;
n++;
*(pixel + linebytes * ( i) + n) = r;
}
}
}
else if(img.nChannels==1)
{
for(int i=0;i<img.height;i++)
{
for(int j=0,n=0;j<img.width;j++,n++)
{
byte g = ((byte*)img.imageData + img.widthStep * i)[j];
*(pixel + linebytes * (i) + n) = g;
n++;
*(pixel + linebytes * (i) + n) = g;
n++;
*(pixel + linebytes * (i) + n) = g;
}
}
}
else
{
return;
}
}
disp.UnlockBits(bmp);
pictureBox1.Image = (Image)disp;
}
}
}
如果需要在C#窗体上显示OpenCV中的IplImage指向的图像,只需要将pictureBox1.Image = (Image)disp;
改为:
Graphics gg=this.CreateGraphics();
gg.DrawImage((Image)disp,0,0);
然后就OK了。