Алгоритм подгонки линии OpenCV

Я применил функцию обнаружения краев Canny к исходному изображению, а затем использовал функцию findContours, чтобы найти самый длинный контур. Но после этого я хотел бы использовать алгоритм подгонки линий (функция подгонки) в OpenCV, чтобы нарисовать линию вдоль линии небо-море на исходном изображении.

Исходное изображение:

Исходное изображение

После обнаружения края Кэнни и определения самого длинного контура:

После обнаружения края Кэнни и нахождения самого длинного контура

Результат, ожидаемый после подгонки линии:

Результат после подгонки линии

Любая помощь будет высоко ценится.

0

Решение

Вы не просто используете детектор края Canny для горизонта.

(1) Примените медианный фильтр достаточно большой, чтобы скрыть мелкие объекты.

cv::medianBlur( imgOriginal, blurred, 101 );

(2) Рассчитайте величину градиента. Например. используя некрасивую прямую разницу следующим образом:

cv::Mat m;
blurred.convertTo(m,CV_32F);
cv::Mat crop = m( cv::Rect(0,0,m.cols-1,m.rows-1) );
const cv::Mat shiftx = m( cv::Rect(1,0,m.cols-1,m.rows-1) );
const cv::Mat shifty = m( cv::Rect(0,1,m.cols-1,m.rows-1) );
cv::Mat dx,dy;
cv::subtract( shiftx, crop, dx );
cv::subtract( shifty, crop, dy );
cv::pow( dx, 2.0, dx );
cv::pow( dy, 2.0, dy );
cv::add( dx, dy, dx );
m.setTo(0);
cv::sqrt( dx, crop );

(3) Соберите точки, где величина градиента больше, скажем, наполовину максимальной.

cv::minMaxLoc( m, &mi, &ma );
const float thr = ma/2.0;
std::vector< cv::Point2f > pts;
for ( int y=0; y<m.rows;++y)
// ...

(4) И наложи на них линию.

Вы должны получить хорошую форму.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]