OpenCV_lection03_2012

40
с/к Обработка информации, осень 2013 3. Сглаживание изображений. Выделение контуров. Получение кадров с камеры. Геометрическое выравнивание изображений www.uralvision.blogspot.com [email protected] УрФУ / ИММ УрО РАН Денис Сергеевич Перевалов

Transcript of OpenCV_lection03_2012

Page 1: OpenCV_lection03_2012

с/к Обработка информации, осень 20133. Сглаживание изображений.

Выделение контуров. Получение кадров с камеры.

Геометрическое выравнивание изображений

www.uralvision.blogspot.com [email protected] УрФУ / ИММ УрО РАН

Денис Сергеевич Перевалов

Page 2: OpenCV_lection03_2012

Сглаживание изображенийСамая часто используемая функция для сглаживания:

void GaussianBlur(const Mat& src, //входное изображение Mat& dst, //выходное изображение Size ksize, //размер окна сглаживания double sigmaX, //параметры гауссиана double sigmaY=0, int borderType=BORDER_DEFAULT) //как работать с //границей

- Функция выполняет сглаживание src с использованием функции Гаусса.- dst будет иметь тот же тип и размеры, что и src.- Допустимо, чтобы dst == src.- ksize - размер ядра фильтра, когда размеры должны быть нечетными.- sigmaX, sigmaY - стандартные отклонения по X и Y. Если 0, то вычисляются из ksize.- borderType - как работать на границе, например, BORDER_REFLECT.

Page 3: OpenCV_lection03_2012

Сглаживание изображенийПримерMat image = imread( "3dart.jpg" );Mat blurred1, blurred2;GaussianBlur( image, blurred1, cv::Size( 11, 11 ), 0 );GaussianBlur( image, blurred2, cv::Size( 41, 41 ), 0 );

image blurred1 blurred2

http://www.innocentenglish.com/funny-pics/best-pics/stairs-sidewalk-art.jpg

Page 4: OpenCV_lection03_2012

Сглаживание изображенийДругие функции, выполняющие сглаживание:medianBlur - медианная фильтрацияblur - сглаживание квадратным окном (усреднение)

filter2D - сглаживание с любым фильтром, представленным в виде матрицы

GaussianBlur medianBlur blur

Все три метода работали с фильтром размером 11x11 пикселов. Гауссов фильтр дал самый естественный результат. Медианный - выделил области одного цвета и удалил мелкие детали.Фильтр усреднения - видны нежелательные артефакты - квадратные края у объектов.

Page 5: OpenCV_lection03_2012

Для чего применяется сглаживание

1. Устранение мелкого шума на изображении, для последующего анализа изображения.Делается с помощью фильтра небольшого размера.

Чаще всего - используют гауссов фильтр, реже - медианную фильтрацию.

Page 6: OpenCV_lection03_2012

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

В примере использована картинка, полученная инвертированием http://www.eyesontutorials.com/images/Designing/Jeka/tut180_dark_wallpaper/12.jpg

Исходная картинкас неоднородным фоном

Сглаживание фильтром размером 201x201 пиксел

Разность исходной и сглаженной картинок. Фон теперь однородно черный.

Page 7: OpenCV_lection03_2012

Для чего применяется сглаживание

3. Подчеркивание пикселов контуров объектов. (Факт из теории: разность двух гауссианов аппроксимирует лапласиан).Используется два гауссовых фильтра с размерами a и ~2a.

Исходное изображение Разность двух сглаженных картинок с радиусами 3 и 7, умноженная на 20. Ярким цветом выделились контура объектов.

Page 8: OpenCV_lection03_2012

Для чего применяется сглаживание4. Не относящееся к компьютерному зрению,а к компьютерной графике:

- гауссовым фильтром моделируется эффект дефокусировки.

- несимметричным фильтром создается эффект "скоростного смаза" (motion blur).

Боковое движение Движение вперед Вращение

Page 9: OpenCV_lection03_2012

Практическая задача 2 (вариант 1)

Сделать мультфильм, в котором исходная картинка подвергается размытию с возрастающим размером окна. То есть, постепенно размывается.

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

2. Для алгоритма размытия используйтегауссов фильтр (если ваша фамилия четной длины),или медианный фильтр (если ваша фамилия нечетной длины).

3. В мультфильме должно быть не менее 100 кадров.

4. Результат - высылайте ссылку на ваше видео на youtube, и cpp-код.

Page 10: OpenCV_lection03_2012

Уточнение, как делать

В OpenCV есть возможность явно создавать avi файлы. Мы предлагаем сделать проще.

1. Изображения записывать на диск в одну папку в формате .bmp, с названиямиimage000.bmp, image001.bmp, ....

2. Затем из них сделать avi-файл с помощью программы VirtualDub(File->Open video file, и в появившемся диалоге указать первую картинку из набора.После этого Video -> Compresson, выбрать кодек.Наконец, File -> Save as avi... - запись avi-файла).

3. Выложить полученный файл на youtube.

Page 11: OpenCV_lection03_2012

Практическая задача 2 (вариант 2)Используя1) вырезание части изображения, (см. "Работа с прямоугольными подобластями изображения")2) функцию изменения размера resize()3) суммирование изображений с весами (см. "Линейные операции над изображениями")

реализовать эффект "Движение вперед".

Результат представить в виде cpp-файла, а также входной и выходной картинок.Название объекта на входной картинке должно начинаться на первую букву вашей фамилии.

Page 12: OpenCV_lection03_2012

Уточнение, как делать

Вырезаем N=20 прямоугольных областей - image[i], их увеличиваем в размере,и из них строим сумму

1.0 / N * image[0] + 1.0 / N * image[1] + ... + 1.0 / N * image[N-1];

это и будет результат.

Page 13: OpenCV_lection03_2012

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

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

Page 14: OpenCV_lection03_2012

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

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

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

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

Внешний контур

Внутренний контур

Page 15: OpenCV_lection03_2012

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

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

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

Page 16: OpenCV_lection03_2012

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

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

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

Page 17: OpenCV_lection03_2012

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

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

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

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

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

Page 18: OpenCV_lection03_2012

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

Page 19: OpenCV_lection03_2012

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

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

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). (Гауссово сглаживание позволяет получить результат, устойчивый к шумам на изображении.)

Page 20: OpenCV_lection03_2012

Фильтр СобелаПример 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

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

Page 21: OpenCV_lection03_2012

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

Если трансформировать картинки в серый цвет и взять 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 );

Page 22: OpenCV_lection03_2012

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

Page 23: OpenCV_lection03_2012

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

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

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

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

Page 24: OpenCV_lection03_2012

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

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

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

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

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

Page 25: OpenCV_lection03_2012

Детектор краев Канни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| );

Page 26: OpenCV_lection03_2012

Детектор краев КанниПример Mat imageGray, edges;

cvtColor( image, imageGray, CV_RGB2GRAY );Canny( imageGray, edges, 230, 150 );

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

Page 27: OpenCV_lection03_2012

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

Page 28: OpenCV_lection03_2012

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

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

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

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

Page 29: OpenCV_lection03_2012

Трассировка контуров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

Page 30: OpenCV_lection03_2012

Трассировка контуровПример 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 );

Page 31: OpenCV_lection03_2012

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

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

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

Проблемы

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

Page 32: OpenCV_lection03_2012

Получение кадров с камеры.Геометрическое выравнивание

изображений

Page 33: OpenCV_lection03_2012

Получение кадров с камерыVideoCapture capture; //Класс для работы с камерами и видеофайламиcapture.open( 0 ); //открыть первую камеру (нумерация с 0)//а если задать строку VideoCapture capture.open( "myfile.avi" ); - будет читать avi-файл

if ( !capture.isOpened() ) { //если камеры нет, завершаем работуcout << "Нет камеры" << endl;return -1;

} Mat image, smoothed, edges;for(;;) { capture >> image; // получение кадра cvtColor(image, smoothed, CV_BGR2GRAY);

GaussianBlur(smoothed, smoothed, Size(7,7), 1.5, 1.5 ); Canny(smoothed, edges, 0, 30, 3 );

imshow( "image", image );imshow("edges", edges);

if(waitKey(30) >= 0) break; //ждем нажатия клавиши 30 мсек, если нажали - выход }

//Деструктор capture сам выключит камеруreturn 0;

Page 34: OpenCV_lection03_2012

Получение кадров с камеры

Page 35: OpenCV_lection03_2012

Геометрическое выравнивание изображений

Рассмотрим простейшую ситуацию, когда камера смотрит сбоку на плоскость. Требуется выровнять получаемую картинку, как будто бы камера смотрит строго сверху на эту плоскость.Рассмотрим простой алгоритм - использующий перспективное преобразование.(Есть более сложные методы калибровки, которые позволяют устранять искажения на краях изображения с камеры, связанные с неточностью оптики).

Исходное изображение Изображение с выделенными калибровочными точками

(углы красного 4-угольника)

Результат выравнивания изображения

Page 36: OpenCV_lection03_2012

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

В простейшем случае это просто 4 точки, указывающие, куда должны перейти углы изображения (A,B,C,D) -> [0,w] x [0,h]Примечание: координаты могут быть вещественными числами, что позволяет повысить точность результата.

Матрица проективного преобразования M - размер 3x3, осуществляет преобразование по правилу(x,y) -> M *(x,y,1)

2. C помощью функции getPerspectiveTransform вычисляется оптимальная матрица перспективного преобразования. Реализация OpenCV использует в точности 4 точки.

3. Наконец, данная матрица подставляется в функцию warpPerspective для получения калиброванного изображения.

T

Page 37: OpenCV_lection03_2012

const int K = 4; //будем использовать 4 точки. cv::Point2f src[K]; //координаты точек на изображенииcv::Point2f dst[K]; //координаты результирующих точек

src[ 0 ] = cv::Point2f( ..., ... ); //координаты углов A,B,C,D на изображенииsrc[ 1 ] = cv::Point2f( ..., ... ); //должны идти по часовой стрелке с левого верхнего углаsrc[ 2 ] = cv::Point2f( ..., ... ); //- в соответствии с dst, см. нижеsrc[ 3 ] = cv::Point2f( ..., ... );

dst[ 0 ] = cv::Point2f( 0, 0 ); //результирующие точки; w и h - размеры результатаdst[ 1 ] = cv::Point2f( w, 0 ); dst[ 2 ] = cv::Point2f( w, h );dst[ 3 ] = cv::Point2f( 0, h );

Mat transform = getPerspectiveTransform( src, dst ); //вычисляем матрицу преобразованияwarpPerspective( image, imageResult, transform, cv::Size( w, h ), INTER_LINEAR );//получаем по входному изображению image результат - imageResult

y

x0

h

AB

C

D

wW

H

Page 38: OpenCV_lection03_2012

Выравнивание с помощью билинейного преобразованияВозможно делать выравнивание не с помощью перспективного преобразования, а используя билинейное преобразование. В этом случае формула проще, но работает по другому и применяется для случая, когда требуется перевести прямоугольную картинку в произвольный 4-угольник.

точка (x,y) из [0,1]x[0,1] переводится в 4-угольник с углами A,B,C,D по формуле:

bilinear( x,y ) = (1-x)(1-y) A + x(1-y) B + (1-x)y C + xy D

y

x0

1

1

(x,y)

AB

C

D

a b

cd

Page 39: OpenCV_lection03_2012

Для прямоугольника произвольного размера [0,w] x [0,h]:

bilinear( x, y; w, h ) = bilinear( x / w, y / h )

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

Гладкого результата при деформации изображений можно добиться путем использования функции remap.Эта функция позволяет указать, куда должен перейти каждый пиксель изображения, и осуществляет это преобразование:

result( x, y ) = image( tx( x, y ), ty( x, y ) ),

здесь tx, ty - преобразования координат.Важно: remap делает “обратное преобразование”, поэтому его не так просто применить например для реализации билинейного преобразования(- так как там нужно бы result( tx(x,y), ty( x, y ) ) = image( x, y ). )

Подробнее про функцию remap:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/remap/remap.html )

Page 40: OpenCV_lection03_2012

Практическая задача 3 1. В программу загружается изображение размером w x h пикселей.

2. Пользователь мышью задает 4 точки на изображении A,B,C,D.

3. Программа с помощью перспективного преобразования строит выровненное изображение (A,B,C,D) -> [0,w] x [0,h]и сохраняет его в файл.

4. Программа с помощью билинейного преобразования (попиксельно) строит выровненное изображение[0,w] x [0,h] -> (A,B,C,D)и сохраняет его в файл.