将 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);
}
我的代码分为三个部分:第 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);
}