【转】让OpenCV中的IplImage显示在C#的PictureBox上

上次写了一个让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了。

posted on 2009-07-05 19:50 碧云天 阅读(4098) 评论(0)  编辑 收藏 引用 所属分类: c#学习


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

Emgu CV ——c#版的opencv

Help

搜索

最新评论

阅读排行榜

评论排行榜