Подтвердить что ты не робот

Разница между "Обнаружение кромок" и "Контуры изображения"

Я работаю над следующим кодом:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

Mat src, grey;
int thresh = 10;

const char* windowName = "Contours";

void detectContours(int,void*);

int main()
{
    src = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg");

    //Convert to grey scale
    cvtColor(src,grey,CV_BGR2GRAY);

    //Remove the noise
    cv::GaussianBlur(grey,grey,Size(3,3),0);

    //Create the window
    namedWindow(windowName);

    //Display the original image
    namedWindow("Original");
    imshow("Original",src);

    //Create the trackbar
    cv::createTrackbar("Thresholding",windowName,&thresh,255,detectContours);

    detectContours(0,0);
    waitKey(0);
    return 0;

}

void detectContours(int,void*)
{
    Mat canny_output,drawing;

    vector<vector<Point>> contours;
    vector<Vec4i>heirachy;

    //Detect edges using canny
    cv::Canny(grey,canny_output,thresh,2*thresh);

    namedWindow("Canny");
    imshow("Canny",canny_output);

    //Find contours
    cv::findContours(canny_output,contours,heirachy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));

    //Setup the output into black
    drawing = Mat::zeros(canny_output.size(),CV_8UC3);



    //Draw contours
    for(int i=0;i<contours.size();i++)
    {
        cv::drawContours(drawing,contours,i,Scalar(255,255,255),1,8,heirachy,0,Point());
    }

    imshow(windowName,drawing);

}

Теоретически, Contours означает обнаружение кривых. Edge detection края означает обнаружение края. В моем коде выше, я сделал обнаружение края с помощью Canny и обнаружения кривой с помощью findContours(). Ниже приведены полученные изображения

Canny Image

enter image description here

Контуры изображения

enter image description here

Так что теперь, как видите, разницы нет! Итак, в чем же разница между этими двумя? В руководствах OpenCV дается только код. Я нашел объяснение того, что такое "Контуры", но оно не решает эту проблему.

4b9b3361

Ответ 1

Края вычисляются как точки, которые являются экстремумами градиента изображения в направлении градиента. если это помогает, вы можете думать о них как о минимальных и максимальных точках в 1D-функции. Дело в том, что краевые пиксели являются локальным понятием: они просто указывают на значительную разницу между соседними пикселями.

Контуры часто получаются из ребер, но они нацелены на контуры объектов. Таким образом, они должны быть замкнутыми кривыми. Вы можете думать о них как о границах (некоторые алгоритмы обработки изображений и библиотеки называют их такими). Когда они получены из ребер, вам нужно соединить края, чтобы получить замкнутый контур.

Ответ 2

Основное различие между поиском ребер и счетчиками состоит в том, что если вы запустите поиск краев, выход будет новым. На этом новом (краевом изображении) изображение будет выделено краями. Существует множество алгоритмов для обнаружения ребер посмотреть на wiki см. Также.

Например, оператор Sobel дает гладкие "туманные" результаты. В вашем конкретном случае улов заключается в том, что вы используете детектор края канна. Это делает несколько шагов дальше, чем другие детекторы. На самом деле он выполняет дополнительные шаги по уточнению края. Таким образом, выход детектора Canny является двоичным изображением с шириной линий 1 px вместо ребер.

С другой стороны, алгоритм Contours обрабатывает произвольное двоичное изображение. Поэтому, если вы нанесете белый квадрат на черном фоне. После запуска алгоритма Contours вы получите белый пустой квадрат, только границы.

Другой добавленный бонус обнаружения контура, он фактически возвращает множество точек! Это здорово, потому что вы можете использовать эти точки дальше для некоторой обработки.

В вашем конкретном случае совпадение совпадает только с обоими изображениями. Это не правило, а в вашем случае это из-за уникального свойства алгоритма Canny.

Ответ 3

Контуры могут на самом деле немного больше, чем "просто" определять края. Алгоритм действительно находит края изображений, но также помещает их в иерархию. Это означает, что вы можете запросить внешние границы объектов, обнаруженных на ваших изображениях. Такая вещь не была бы (напрямую) возможной, если вы только проверяете наличие ребер.

Как можно прочитать в документации, контуры в основном используются для распознавания объектов, где детектор canny edge является более "глобальной" операцией. Я не удивлюсь, если в алгоритме контура используется какое-то определение canny edge.

Ответ 4

Понятие контуров используется как инструмент для работы с реберными данными. Не все грани одинаковы. Но во многих случаях, например, объекты с унимодальным распределением цветов (т.е. один цвет), ребра - это фактические контуры (контур, форма).

  • Обнаруживать не только кривые, но и все, что связано с картой края. (анализ компонентных компонентов) [1]
  • Полезно для объектов с унимодальным распределением цветов (макрос переднего плана легко найти с простым порогом). Образец образца не подходит.

[1] Топологический структурный анализ оцифрованных двоичных Изображения по границе После Сатоши Судзуки, 1985 год.