Lexm 0 Жалоба Опубликовано December 10, 2014 Добрый день, Подскажите, пожалуйста, есть ли какой-нибудь способ однозначно определить контур следующего объекта: Для обработки этого объекта выполняются следующие опреации: blur(); cvtColor(); threshold(); dilate(); canny(); findContours(); Результаты: Канни Контуры Видно, что контур не определяется как единое целое. Как быть в этой ситуации? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 10, 2014 В общем виде как-то сложно дать ответ. В твоём конкретном случае как на картинке можно сделать несколько раз дилатацию до момента соединения всех кусков в одно целое, а дальше произвести скелетизацию результата. Устроит тебя такой контур? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 10, 2014 случае как на картинке можно сделать несколько раз дилатацию до момента соединения всех кусков в одно целое, а дальше произвести скелетизацию результата. Попробую, но мне нужен контур, максимально приближенный к исходному изображению. Дилатация несколько раз, думаю, исказит контур. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 10, 2014 Ммм... Я бы, пожалуй, применил алгоритм A-star для поиска кратчайшего расстояния от крайних точек. Весами пусть служит результат Канни. Но это как-то по воде писано. Для конкретно этого примера сработает, конечно. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 11, 2014 К сожалению, морфологические преобразования не помогли, края объекта, граничащие с тенью, искажаются. Не подскажите, можно восстановить весь объект по какой-либо характерной его части, если заранее известна форма объекта и его размеры? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 11, 2014 А можно увидеть желаемый итоговый вид контура для данного экземпляра? Можно просто нарисовать от руки в графическом редакторе поверх исходного изображения. На первый взгляд - это отрезок, который довольно просто получить тем же МНК по результатам Канни. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 11, 2014 Цель - найти с достаточно высокой точностью данный объект на любом фоне. Соответственно, нужен контур данного объекта. В данном случае проблема с тенями в левом нижнем углу. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 11, 2014 С помощью метода получается Видно, что для границы объекта с тенью отрезки уезжают в сторону. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 11, 2014 1. Ну, если искать контур не целиком как контур, а только грани, то проблема решается поиском прямых (тем же Хафом, например). После эти прямые объединить в фигуру. 2. Я бы попробовал использовать chamferMatching для поиска. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 11, 2014 1. Ну, если искать контур не целиком как контур, а только грани, то проблема решается поиском прямых (тем же Хафом, например). После эти прямые объединить в фигуру. 2. Я бы попробовал использовать chamferMatching для поиска. Не нашел chamerMatching() в OpenCV 3.0. Походу, её выкинули или заменили чем-то. Не в курсе, какая ф-ция наиболее близка по смыслу? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 11, 2014 Мда, плохие новости. Выкинули не саму функцию, а весь модуль contrib, в состав которого она входила. Этот модуль теперь не поставляется в составе OpenCV, а в виде отдельного репозитория, который с одной стороны гораздо больше исходного, а с другой - не содержит некоторых функций, в том числе и chamerMatching. Советую протестировать работу функции в прошлой версии OpenCV. Если подойдёт по качеству работы, то просто взять её исходники в свой проект. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 12, 2014 Мда, плохие новости. Выкинули не саму функцию, а весь модуль contrib, в состав которого она входила. Этот модуль теперь не поставляется в составе OpenCV, а в виде отдельного репозитория, который с одной стороны гораздо больше исходного, а с другой - не содержит некоторых функций, в том числе и chamerMatching. Советую протестировать работу функции в прошлой версии OpenCV. Если подойдёт по качеству работы, то просто взять её исходники в свой проект. Проверил, chamerMatching справляется. Спасибо за помощь! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 12, 2014 Посмотрите еще пример generalized_hough.cpp из папки samples/gpu думаю это может работать даже получше chamferMatching, правда не тестил (чисто теоретически ). 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 16, 2014 Проверил, chamerMatching справляется. Спасибо за помощь! Просветите, плиз, chamerMatching только одну фигуру находит из нескольких одинаковых? Ерунда какая-то: есть две одинаковые фигуры разного цвета, после Канни есть два контура, так постоянно определяется последний по координате х, хотя его качество хуже, чем у первого. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 16, 2014 Посмотрите еще пример generalized_hough.cpp из папки samples/gpu думаю это может работать даже получше chamferMatching, правда не тестил (чисто теоретически ). Сейчас с chamerMatching разбираюсь, после проверю обязательно, спасибо за совет. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 16, 2014 Должно быть всё нормально: CV_EXPORTS_W int chamerMatching( Mat& img, Mat& templ, CV_OUT vector<vector<Point> >& results, CV_OUT vector<float>& cost, double templScale=1, int maxMatches = 20, double minMatchDistance = 1.0, int padX = 3, int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6, double orientationWeight = 0.5, double truncate = 20); По-умолчанию ставится максимум 20 возможных объектов. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 16, 2014 Должно быть всё нормально: CV_EXPORTS_W int chamerMatching( Mat& img, Mat& templ, CV_OUT vector<vector<Point> >& results, CV_OUT vector<float>& cost, double templScale=1, int maxMatches = 20, double minMatchDistance = 1.0, int padX = 3, int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6, double orientationWeight = 0.5, double truncate = 20); По-умолчанию ставится максимум 20 возможных объектов. Спасибо, мой косяк. У меня отрисовывается контур с минимальным отличием: int best = chamerMatching( img1, tpl, results, costs, templScale, maxMatches, minMatchDistance, padX, padY, scales, minScale, maxScale, orientationWeight, truncate); if( best < 0 ) { printf("matching not found"); return -1; } size_t i, n = results[best].size(); for( i = 0; i < n; i++ ) { Point pt = results[best][i]; if( pt.inside(Rect(0, 0, cimg.cols, cimg.rows)) ) cimg.at<Vec3b>(pt) = Vec3b(0, 255, 0); } imshow("result", cimg); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 16, 2014 Все равно не работает: Исходник: Контуры: Результат: Что я делаю не так? double templScale = 1; int maxMatches = 20; // 20 double minMatchDistance = 1; int padX = 3;//3; int padY = 3;//3; int scales = 40;//5; double minScale = 0.6; //0.2; double maxScale = 1.6; //1.8; double orientationWeight = 0.5; double truncate = 20; //20; int best = chamerMatching( img1, tpl, results, costs, templScale, maxMatches, minMatchDistance, padX, padY, scales, minScale, maxScale, orientationWeight, truncate); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано December 16, 2014 1. А results сколько элементов в себе содержит по итогу? 2. Если подать только левую половину изображения, объект найдётся? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Lexm 0 Жалоба Опубликовано December 16, 2014 В results, как и положено, 20 значений. Находится: Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах