EmguCV C#: FindContours () для обнаружения различных форм - PullRequest
1 голос
/ 27 мая 2020

У меня есть это изображение:

enter image description here

Я пытаюсь определить его контуры. Поэтому, просмотрев документацию и код в Интернете, я сделал это:

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);

Затем он обнаруживает этот контур синим цветом:

enter image description here

Теперь я хотел бы обнаружить оба прямоугольника в разных контурах. Таким образом, результат будет следующим:

enter image description here

(сделано с помощью краски) Итак, теперь я хотел бы обнаружить два прямоугольника по отдельности (синий и красный прямоугольники будут двумя разными контурами). Но я понятия не имею, как это сделать!

Заранее благодарим за помощь! ;)

1 Ответ

1 голос
/ 28 мая 2020

Проблема возникает из-за процесса ThresholdBinary. Как я предполагаю, вы понимаете, этот метод вернет двоичное изображение, при этом все пиксели выше или равные параметру threshold будут подтянуты до параметра maxValue, а все пиксели ниже - до 0. Созданное изображение поэтому будет состоять только из двух значений (двоичных), 0 или maxValue. Если мы последуем вашему примеру с некоторыми предполагаемыми значениями серого:

Input Image

После Image<Gray, byte> image = receivedImage.Convert<Gray, byte>().ThresholdBinary(new Gray(80), new Gray(255)); вы получите:

Binary Image

Фактически, это изображение, которое вы передаете на CvInvoke.FindContours() и впоследствии находите только самый крайний контур.

Что вам нужно , если вы действительно хотите продолжить с FindContours, - это алгоритм, который будет "бин" или "пропускать" ваше изображение, чтобы сначала создать следующие сегменты, каждый из которых будет преобразован в двоичный, а контур будет обнаружен независимо.

Segment 1 Segment 2

Я чувствую, что ваш пример, вероятно, и чрезмерное упрощение проблемы, чтобы предложить вам решение на как вы могли бы добиться этого здесь. Однако, пожалуйста, задайте другой вопрос с более реалистичными c данными, и я буду рад предоставить несколько предложений.

В качестве альтернативы обратите внимание на более сложные методы обнаружения границ, такие как Canny или Sobel. Это видео может стать хорошей отправной точкой: Обнаружение краев

...