Лекции OpenCV: 6. Выделение контуров

Preview:

Citation preview

с/к Анализ изображений, OpenCV

6. Выделение контуров

УрГУ / ИММ осень 2010лекции и объявления: вопросы отправляйте на адрес www.uralvision.blogspot.com perevalovds@gmail.com

http://howto.nicubunu.ro/gears/gears_16.png

Понятие контура

Понятие контураКонтур объекта - это линия, представляющая край формы объекта.

Если имеется разбиение изображения на области, соответствующие разным объектам, то их внешние контуры можно указать однозначно.

Для указания внутренних контуров нужна 3d модель объекта. В этом случае контурами будут проекции на изображение линий изгиба 3d объекта.

http://cvpr.uni-muenster.de/research/rack/index.html

Понятие контураЕсли дано изображение, на котором надо выделить контуры,но нет ни разбиения на области, ни 3d-модели, то возникают неоднозначности определения, что такое контур,

связанные с - масштабом (насколько мелкие интересуют объекты)- текстурой (являются ли элементы текстуры контурами)- семантикой (иногда линии на изображении являются просто нарисованными на объекте, и не отражают изгибов его формы)

Считать ли куст объектом, и искать только его контур, или объектами считать отдельные листья?

Понятие контураПоэтому в машинном зрении часто рассматривают задачу не поиска контуров объектов, а поиск контуров на изображении.

Контур на изображении - это линия, вдоль которой наблюдается скачок по яркости или цвету.

Контуров на изображении больше, чем контуров объектов на этом изображении. Поэтому после решения задачи поиска контуров на изображении производится их дополнительный анализ с целью выявления интересующих контуров объектов.

Зачем нужно находить контур

1. Распознавание

Контур объекта обычно хорошо характеризует его форму. Поэтому по контуру можно часто определить тип объекта, который мы наблюдаем.

2. Проведение измерений

С помощью контура можно точно оценить размеры объекта, их поворот и расположение - важно для для автоматизации промышленности, робототехники, интерактивных систем.

Поиск точек контура

Фильтр Собела

Для подчеркивания точек контуров чаще всего применяют фильтр Собела.

void Sobel(const Mat& src, //входное изображение Mat& dst, //выходное изображение, размер и каналов - как у src int ddepth, //глубина результата, например, CV_32F int xorder, //порядок производной по x int yorder, //порядок производной по y int ksize=3, //размер окна: 1, 3, 5, 7 double scale=1, double delta=0, //масштабирование и сдвиг результата int borderType=BORDER_DEFAULT) //работа с границей

Фильтр осуществляет Гауссово сглаживание и взятие частных производных 1, 2, 3 порядка или смешанных ( xorder по x, yorder по y). (Гауссово сглаживание позволяет получить результат, устойчивый к шумам на изображении.)

Фильтр СобелаПример Mat image = imread( "lodka.jpg" ); //Загрузить изображение с диска imshow( "image", image ); //Показать изображениеMat imageDX, imageDY;Sobel( image, imageDX, CV_32F, 1, 0, 3, 1.0 / 255.0 ); //производная по xSobel( image, imageDY, CV_32F, 0, 1, 3, 1.0 / 255.0 ); //производная по y

Обратите внимание, что показаны только положительные значения. Отрицательные и нулевые значения - показаны черным цветом.

Фильтр СобелаПример, продолжение

Если трансформировать картинки в серый цвет и взять sqrt( imageDX^2 + imageDY^2 ) - получим подчеркивание точек контура.Применив к ним пороговую обработку, получим набор точек контура. Mat grayX, grayY;cvtColor( imageDX, grayX, CV_RGB2GRAY );cvtColor( imageDY, grayY, CV_RGB2GRAY );pow(grayX, 2, grayX);pow(grayY, 2, grayY);

Mat contImg = grayX + grayY;sqrt(contImg, contImg);contImg.convertTo( temp, CV_8UC3, 255.0 );

Mat binary;threshold( contImg, binary, 0.7, 1.0, CV_THRESH_BINARY );

Фильтр СобелаПример, продолжение

Другие фильтры подчеркивания точек контура1. Scharr() , 2. Laplacian(), 3. разность двух Гауссианов (см. в лекции про сглаживание).

Все они работают по принципу, аналогичному методу Собела.

У всех рассмотренных методов такой недостаток: они работают на уровне отдельных пикселов, а потому получаемые контуры не являются непрерывными гладкими линиями.

Решение: использовать алгоритм Канни.

Детектор краев Канни

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

Использует метод двух порогов.

Идея - трассировать контур, двигаясь вдоль точек с максимальным значением "контура".

На выходе алгоритм дает бинарную картинку с найденными пикселами, соответствующими контурам.

Детектор краев Канниvoid Canny( const Mat& image, //входное изображение, 1-канальное, 8-битное Mat& edges, //выходное изображение double threshold1, //пороги, наибольший - для зародышей контура, double threshold2, //наименьший - для склейки контуров int apertureSize=3, //окно для фильтра Собела bool L2gradient=false //использовать ли евклидову длину вектора //производных Собела, sqrt( dx*dx + dy * dy), //или просто |dx| + |dy| );

Детектор краев КанниПример Mat imageGray, edges;cvtColor( image, imageGray, CV_RGB2GRAY );Canny( imageGray, edges, 230, 150 );

Исходная картинка Собел + пороговая обработка Детектор краев Канни

Векторизация контуров

Трассировка контура

Трассировка контура - это построение по набору пикселов ломаной, т.е. построение векторного представления контура.

Векторное представление удобно с точки зрения последующей обработки и анализа контура:

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

Трассировка контуровvoid findContours(const Mat& image, //Входное изображение, //1-канальное, 8-битное //трактуется как бинарное (0 и не 0) vector<vector<Point> >& contours, //Найденные контуры int mode, //Режим поиска контуров int method, //Способ аппроксимации контуров Point offset=Point() //Сдвиг всех результрующих контуров )

Значения mode: CV_RETR_EXTERNAL - только внешние контуры,CV_RETR_LIST - список всех контуровИспользуется другая форма функции, см. документацию:CV_RETR_CCOMP - 2-уровневая иерархия - внешние границы и границы дырок, CV_RETR_TREE - стоит дерево вложенных контуров,

Значения method:CV_CHAIN_APPROX_NONE - без аппроксимацииCV_CHAIN_APPROX_SIMPLE - выбрасявает горизонтальные и вертикальные точки внутри отрезковCV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS - аппроксимация методом Teh-Chin

Трассировка контуровПример vector<vector<Point> > contours;findContours( edges, contours, CV_RETR_LIST, CV_CHAIN_APPROX_TC89_L1 );

Mat draw = image.clone();drawContours( draw, contours, -1, Scalar( 255, 0, 0 ) );imshow( "find cont", draw );

Анализ контуров

Для определения того, какому объекту принадлежит контур, используют геометрические характеристики - длина контура, - площадь области, огороженной контуром,- распределение кривизны вдоль контура,

Также, статистические моменты и преобразование Фурье и алгоритмы прямого сопоставления контуров.

Проблемы

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