如何将提取的Mat轮廓转换为Opencvsharp中的位图?



在目标图像上应用阈值后我得到一个垫子作为参考然后调用函数FindContours()提取目标图像上所有存在的轮廓最后,我尝试将提取的轮廓一次一个地转换为位图,此时我得到了一个错误:

系统。ArgumentException: "通道数必须为1、3或4。Parametername: src"通过将Mat转换为位图

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog getImag = new OpenFileDialog();
getImag.Filter = "PNG,JPG|*.png;*.jpg";
DialogResult result = getImag.ShowDialog();
string Source_Logo_Link = string.Empty;
if (result == DialogResult.OK)
{
Source_Logo_Link = getImag.FileName;
System.Drawing.Image image = System.Drawing.Image.FromFile(Source_Logo_Link);
Mat src = new OpenCvSharp.Mat(Source_Logo_Link);
OpenCvSharp.Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY);
OpenCvSharp.Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu);
OpenCvSharp.Mat[] contoursQuery;
OutputArray hierarchyQ = InputOutputArray.Create(new List<Vec4i>());
binary.FindContours(out contoursQuery, hierarchyQ, RetrievalModes.CComp, ContourApproximationModes.ApproxTC89KCOS);
List<Bitmap> images = new List<Bitmap>();
for (int i = 0; i <= contoursQuery.Length; i++)
images.add(contoursQuery[i].toBitmap());
}    
}

抱歉来得有点晚,但我希望这仍然有帮助。除了一些其他问题(比如for循环的计数器),我猜您的主要问题是,您没有理解FindContours的结果。它只是给你一个所有轮廓点的列表,它在图像中找到的,不是完整的图像。看一下文档FindContours,它清楚地说明了轮廓参数:

每个轮廓被存储为点向量

这意味着如果你想让它们一次一个地变成位图你需要首先创建这些位图,然后在其中绘制轮廓。为了使绘图更容易(和更快),有DrawContours命令,您可以将其用于绘图部分。总的来说,最后,它应该看起来像这样:

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog getImag = new OpenFileDialog();
getImag.Filter = "PNG,JPG|*.png;*.jpg";
DialogResult result = getImag.ShowDialog();
string Source_Logo_Link = string.Empty;
if (result == DialogResult.OK)
{
Source_Logo_Link = getImag.FileName;
System.Drawing.Image image = System.Drawing.Image.FromFile(Source_Logo_Link);
Mat src = new OpenCvSharp.Mat(Source_Logo_Link);
OpenCvSharp.Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY);
OpenCvSharp.Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu);
// I'd really prefer to work with point lists and HierarchyIndex because 
// it's much more descriptive that way
OpenCvSharp.Point[][] contours;
OpenCvSharp.HierarchyIndex[] hierarchyQ;
binary.FindContours(out contours,out hierarchyQ, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS);
List<Bitmap> images = new List<Bitmap>();
for (int i = 0; i < contoursQuery.Length; i++){
var singleContour = new OpenCvSharp.Mat(src.Size(), MatType.CV_8U,0);
singleContour.DrawContours(contours,i,Scalar.White);
images.Add(singleContour.ToBitmap());
}
}    
}

我还将RetrievalMode更改为"列表",因为您似乎并不真正关心层次关系。

希望有帮助;-)

最新更新