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

Reading System.Drawing.Bitmap into OpenCV / Emgu to find contours

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

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

我能完成这项工作的唯一方法是:

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

ii) 使用画图打开生成的 jpg 图像,点击 "Save" 并关闭画图。我已经手动完成了。

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

好吧,我认为麻烦在于透明。 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);
            }