OpenCV中的IplImage显示在C#的PictureBox上

借助于EmguCV来写一个让OpenCV的IplImage显示在C#的PictureBox上的函数,当然了,其中有一个值得注意的地方,那就是将EmguCV中IntPtr类型转化为EmguCV中的结构图MIplImage类型。因为MIplImage类型是和OpenCV中的IplImage类型一样的,只要进行转换之后,我们才能使用MIplImage结构体中的imageData,height,width,widthStep等数据。当然在C#中要添加EmguCV的几个引用的Dll文件,更多配置内容看OpenCV与C#开发环境的搭建。

下面是整个窗体的程序:(红色字体部分为主要程序)

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了。

原文出处:http://peng-jun.blog.163.com/blog/static/21562814200932641749179/

你可能感兴趣的:(OpenCV中的IplImage显示在C#的PictureBox上)