将System.Drawing.Bitmap读入OpenCV / Emgu以查找轮廓

时间:2015-07-31 11:48:12

标签: c# opencv drawing paint emgucv

我的代码分为三个部分:第1部分:在位图中绘制,第2部分)将位图保存为jpg图像,第3部分)读取jpg文件并使用Emgu查找轮廓。

这三个部分分开工作,但我不能让它们一起工作。特别是,我的问题是如何将第1部分的System.Drawing.Bitmap输入到第3部分,输入是Image<Bgr, Byte>。 到目前为止,我已经尝试阅读Bitmap&#34; target&#34;在第1部分直接进入第3部分,Image<Bgr, Byte> imageFrame = new Image<Bgr, Byte>(target)没有成功(它没有识别任何轮廓) 我还试图创建一个中间的.jpg文件(第2部分),他们可以共享但没有成功(它也不能识别任何轮廓)。

我能做到这一点的唯一方法是:

i)运行第1部分和第2部分

ii)使用Paint打开结果jpg图像,点击&#34; Save&#34;并关闭油漆。我手动完成了这个。

iii)运行第3部分。

执行此操作可识别轮廓。然而,这不是有效的解决方案,因为步骤ii)不是自动化的。然而,这可能有助于说明问题所在。

有人可以帮忙吗?

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;

namespace Contouring
{

class Program
{
    static void Main(string[] args)
    {

        //--------------------------------------PART 1 : DRAWING STUFF IN A BITMAP------------------------------------------------------------------------------------
        Pen blackPen = new Pen(Color.FromArgb(255, 0, 0, 0), 1);
        Bitmap bmp = new Bitmap(1000, 1000);
        Graphics g = Graphics.FromImage(bmp);

            //This is just an example using three rectangles for illustration purposes. 
            //In reality I have a set of arbitrary lines defining complex polygons.
            g.DrawRectangle(blackPen, new Rectangle(10, 10, 200, 100)); //rectangle 1
            g.DrawRectangle(blackPen, new Rectangle(20, 20, 50, 30)); //rectangle 2
            g.DrawRectangle(blackPen, new Rectangle(200, 10, 25, 25)); //rectangle 3

        Rectangle r = new Rectangle(10, 10, 250, 250); //bounding box of the 3 rectangles
        Rectangle rcrop = new Rectangle(r.X, r.Y, r.Width + 10, r.Height + 10);//This is the cropping rectangle (bonding box adding 10 extra units width and height)

        //Crop the model from the bmp
        Bitmap src = bmp;
        Bitmap target = new Bitmap(r.Width, r.Height);
        using (Graphics gs = Graphics.FromImage(target))
        {
            gs.DrawImage(src, new Rectangle(5, 5, 250, 250), rcrop, GraphicsUnit.Pixel);
            gs.Dispose();
        }


        //--------------------------------------PART 2 : SAVING THE BMP AS JPG------------------------------------------------------------------------------------
        target.Save("test.jpg");


        //--------------------------------------PART 3 : USING THE SAVED PICTURE AND FIND CONTOURS ----------------------------------------------------------------
        Image<Bgr, Byte> imageFrame = new Image<Bgr, Byte>("test.jpg");
            //Image<Bgr, Byte> imageFrame = new Image<Bgr, Byte>(target);

        //Find contours
        Image<Gray, byte> grayFrame = imageFrame.Convert<Gray, byte>();
        List<Contour<Point>> result = new List<Contour<Point>>();
        using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation
        for (Contour<Point> contours = grayFrame.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
        {
            //here i do stuff with the contours and add them to the list result
            result.Add(contours);
        }

        //Write to console
        Console.WriteLine(result.Count + " NO. contours have been identified");

    }//endmain

}//endprogram

}//endNamespace

1 个答案:

答案 0 :(得分:0)

嗯,我认为麻烦是透明的。 EmguCV无法理解透明图像。我更新了你的代码,所以现在它可以不保存。它有帮助还是需要透明图像?

        //--------------------------------------PART 1 : DRAWING STUFF IN A BITMAP------------------------------------------------------------------------------------
        var blackPen = new Pen(Color.FromArgb(255, 0, 0, 0), 1);
        var bmp = new Bitmap(1000, 1000, PixelFormat.Format32bppArgb);

        using (var g = Graphics.FromImage(bmp))
        {
            g.Clear(Color.White);
            //This is just an example using three rectangles for illustration purposes. 
            //In reality I have a set of arbitrary lines defining complex polygons.
            g.DrawRectangle(blackPen, new Rectangle(10, 10, 200, 100)); //rectangle 1
            g.DrawRectangle(blackPen, new Rectangle(20, 20, 50, 30)); //rectangle 2
            g.DrawRectangle(blackPen, new Rectangle(200, 10, 25, 25)); //rectangle 3

        }

        var r = new Rectangle(10, 10, 250, 250); //bounding box of the 3 rectangles
        var rcrop = new Rectangle(r.X, r.Y, r.Width + 10, r.Height + 10);//This is the cropping rectangle (bonding box adding 10 extra units width and height)

        //Crop the model from the bmp
        var src = bmp;
        var target = new Bitmap(r.Width, r.Height);
        using (var gs = Graphics.FromImage(target))
        {
            gs.DrawImage(src, new Rectangle(5, 5, 250, 250), rcrop, GraphicsUnit.Pixel);
            gs.Dispose();
        }

        //--------------------------------------PART 3 : USING THE SAVED PICTURE AND FIND CONTOURS ----------------------------------------------------------------

        var imageFrame = new Image<Bgr, Byte>(target);
        //Find contours
        var grayFrame = imageFrame.Convert<Gray, byte>();
        var result = new List<Contour<Point>>();
        using (var storage = new MemStorage()) //allocate storage for contour approximation
            for (var contours = grayFrame.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
            {
                //here i do stuff with the contours and add them to the list result
                result.Add(contours);
            }