Детектор Canny Edge в C

Я ищу немного разъяснений о том, как алгоритмы реализованы в обнаружении границ Canny — запись в Википедии - работай. Кажется довольно простым выполнить шумоподавление с помощью 2D-фильтра Гаусса, но я слышал, что с помощью двух 1D-фильтров — как это достигается? Также просто вычислить градиент и направление края. Однако при выполнении не максимального подавления есть ли изящный трюк для получения закругленного угла? Что я сейчас делаю, так это делю значение направления края (тета) на число пи/4, привожу его к целому числу и использую оператор switch. Но как обрабатывать отрицательные тета-значения, т.е. следует ли обрабатывать -pi/4 так же, как 3*pi/4, или так же, как pi/4?

Любые советы/ссылки очень ценятся!

Спасибо, Бен


person user21293    schedule 08.09.2009    source источник


Ответы (3)


Распределение Гаусса:

[константы опущены для простоты]

g2d(x,y)=exp(-xx-yy)=exp(-x^2) * exp(-y^2)=g1d(x) * g1d(y)

Таким образом, его можно разделить на умножение 1d-распределений. Таким образом, фильтрация может выполняться сначала в направлении x (независимо от каждой строки), а затем в направлении y (независимо от каждого столбца).

закругленный угол:

Если угол выходит за пределы [0..pi) в этом случае правильно прибавлять/вычитать число pi столько раз, сколько необходимо (или использовать функцию fmod), а для [0..pi) все понятно.

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

person maxim1000    schedule 08.09.2009

Вы должны реализовать это самостоятельно или вы можете использовать библиотеку? OpenCv — это огромная библиотека C алгоритмов компьютерного зрения, включая обнаружение границ: http://opencv.willowgarage.com/documentation/image_processing.html?highlight=canny#cvCanny .

Если вы делаете это в образовательных целях, предлагаю подумать о покупке хорошего текста по компьютерному зрению. Почти в любом вступительном тексте будет обсуждаться фильтрация по Гауссу (и хорошо задокументированный трюк с 1d), а также хитрое обнаружение границ и немаксимальное подавление.

person ldog    schedule 08.09.2009

Я думаю, что -pi/4 следует обрабатывать так же, как 3*pi/4, потому что оба определяют одну и ту же диагональ.

Если вы можете нормализовать угол градиента так, чтобы он лежал в [0, пи), то вы могли бы использовать простую функцию, подобную следующей, для квантования угла:

enum Angle
{
    HORIZONTAL,
    DIAG_UP,
    VERTICAL,
    DIAG_DOWN
};

Angle quantizeAngle(double theta)
{
    if (0 <= theta && theta < PI/8.0) || (7.0*PI/8.0 <= theta && theta < PI))
        return HORIZONTAL;
    else if (PI/8.0 <= theta && theta < 3.0*PI/8.0)
        return DIAG_UP;
    else if (3.0*PI/8.0 <= theta && theta < 5.0*PI/8.0)
        return VERTICAL;
    else 
        return DIAG_DOWN;
}
person Zachary Blair    schedule 03.10.2012