简体   繁体   English

EmguCV C#:FindContours() 检测不同形状

[英]EmguCV C# : FindContours() to detect different shapes

I have this image:我有这张图片:

在此处输入图像描述

What I try to do is detecting the contours of it.我试图做的是检测它的轮廓。 So with looking to the documentation and some code on the web I made this:因此,通过查看 web 上的文档和一些代码,我做了这个:

Image<Gray, byte> image = receivedImage.Convert<Gray, byte>().ThresholdBinary(new Gray(80), new Gray(255));
        Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
        Mat hier = new Mat();

        CvInvoke.FindContours(image, contours, hier, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

        CvInvoke.DrawContours(receivedImage, contours, 0, new MCvScalar(255, 0, 0), 2);

Then it detects this contour in blue:然后它以蓝色检测此轮廓:

在此处输入图像描述

Now I would like to detect both rectangles in differents contours.现在我想检测不同轮廓中的两个矩形。 So the result would be this:所以结果是这样的:

在此处输入图像描述

(made with paint) So now I would like to detect the two rectangles separetely, (the blue and red rectangles would be two different contours). (用油漆制成)所以现在我想分别检测两个矩形(蓝色和红色矩形将是两个不同的轮廓)。 But I have no idea about how to do that !但我不知道该怎么做!

Thanks in advance for your help;在此先感谢您的帮助; ;) ;)

The problem comes from the process of ThresholdBinary .问题来自ThresholdBinary的过程。 As I assume you understand, this method will return a binary image, whereby all pixels above or equal to the threshold parameter, will be pulled up to maxValue parameter, and all those below, pulled down to 0. The produced image will consist therefore of only two values (binary), 0 or maxValue .正如我假设您理解的那样,此方法将返回一个二进制图像,其中所有高于或等于threshold参数的像素将被拉高到maxValue参数,所有低于或等于 0 的像素将被拉低。因此生成的图像将包括只有两个值(二进制), 0maxValue If we follow your example with some assumed gray values:如果我们按照您的示例使用一些假定的灰度值:

输入图像

After Image<Gray, byte> image = receivedImage.Convert<Gray, byte>().ThresholdBinary(new Gray(80), new Gray(255)); Image<Gray, byte> image = receivedImage.Convert<Gray, byte>().ThresholdBinary(new Gray(80), new Gray(255)); , you will produce: ,你会产生:

二进制图像

This is in fact the image that you are passing to CvInvoke.FindContours() and subsequently finding only the out most contour.这实际上是您传递给CvInvoke.FindContours()并随后仅找到最外面的轮廓的图像。

What you need, if indeed you want to continue with FindContours , is an algorithm that will "bin", or "bandpass" your image to first produce the following segments, each to be converted to binary, and contour detected independently.如果您确实想继续使用FindContours ,您需要的是一种算法,该算法将“bin”或“带通”您的图像以首先生成以下片段,每个片段都将转换为二进制,并独立检测轮廓。

第 1 段 第 2 段

I feel that you currently example is probably and over simplification of the problem to offer you a solution on how you might achieve that here.我觉得您当前的示例可能是对问题的过度简化,以便为您提供有关如何在此处实现该目标的解决方案。 However please do ask another question with more realistic data, and I will be happy to provide some suggestions.但是,请用更真实的数据提出另一个问题,我很乐意提供一些建议。

Alternatively look towards more sophisticated edge detection methods such and Canny or Sobel.或者寻找更复杂的边缘检测方法,如 Canny 或 Sobel。 This video may be a good starting point: Edge Detection这个视频可能是一个很好的起点:边缘检测

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM