Пиксельное представление изображений. Введение в opencv

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

Upload: denis-perevalov

Post on 02-Aug-2015

8.281 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Пиксельное представление изображений. Введение в OpenCV

с/к Обработка информации, осень 20121. Пиксельное представление

изображений.Введение в OpenCV

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

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

Page 2: Пиксельное представление изображений. Введение в OpenCV

План лекции1. Пиксельное представление изображений. Полутоновые, бинарные, многоканальные изображения. Цветовые пространства. 2. Понятие попиксельного преобразования. Преобразования: пороговое, линейное, негативное, логарифмическое, гамма-коррекция, кусочнолинейное. Гистограмма изображения. Эквализация гистограммы. 3’. Библиотека OpenCV - описание, установка, пример программы (загрузка и показ картинки). Класс Mat как основной в OpenCV для хранения изображений: конструкторы разных типов изображений. Операции копирования. Загрузка, запись, показ на экране.Вырезание фрагмента, конвертирование цветов. Работа с каналами - разбить на каналы, создать многоканальное изображение. 4’. OpenCV: доступ к пикселам, пример попиксельной пороговой обработки и гамма-коррекции. Оперирование с изображениями как с элементами линейного пространства (суммирование, умножение на скаляр). Создание изображений постоянной яркости (setTo). Домашнее задание: реализовать эквализацию гистограммы (попиксельно), а также оперирование фрагментами изображения.

Page 3: Пиксельное представление изображений. Введение в OpenCV

Изображение является матрицей пикселей.Каждый пиксель может хранить некоторые данные.Если пиксель хранит векторные данные, то размерность вектора называется числом каналов изображения.

Двуцветное изображение - называют бинарным.1-канальное изображение - называют полутоновым.2-канальное - хранит векторные поля3-канальное изображение - обычно состоят из трех компонент (Red, Green, Blue), представляет цветное изображение.4-канальные - цвет, к которому добавлен aльфа-канал (прозрачность)

Полутоновые, бинарные, многоканальные изображения

Page 4: Пиксельное представление изображений. Введение в OpenCV

Цветовые пространстваСуществует несколько цветовых пространств.

1. RGB - Самое "физическое" (red, green, blue), аддитивная модель.

2. CMYK - используется при печати ( Cyan, Magenta, Yellow, Key color), субтрактивная модель - из белого вычитаются первичные цвета.

3. HSL - модель, удобная для художников-дизайнеров

цветовыми координатами являются тон, насыщенность и светлота. ■ H — тон [0; 360]■ S — насыщенность [0; 1]■ L — яркость [0; 1]

Разложение изображение по HSL

Page 5: Пиксельное представление изображений. Введение в OpenCV

Понятие попиксельного преобразования. Преобразования: линейное, негативное, кусочнолинейное

Попиксельные преобразования - такие преобразования изображений, которые меняют значения пикселов по одинаковому закону, вне зависимости от положения пиксела на изображении.Изображение A[x,y] -> f(A[x,y]), где f - функция на пространстве значений пикселов.

Линейное, негативное, кусочнолинейное.

Page 6: Пиксельное представление изображений. Введение в OpenCV

Пороговое преобразование

Пороговое преобразованиеf(v) = 1, если v>t, и 0 иначе. t - порог.

Чаще всего она применяются для выделения пикселов интересующих объектов на изображении.

http://www.svi.nl/wikiimg/SeedAndThreshold_02.png

Page 7: Пиксельное представление изображений. Введение в OpenCV

Гамма-коррекция

Гамма-коррекция — коррекция яркости цифрового изображения или видеопотока. Обыкновенно, используется степенная функция в виде

G( v ) = v^gamma

Гамма-коррекция изначально служитдля демонстрации изображений на устройствах вывода с нелинейной яркостной характеристикой;для хранения оцифрованного изображения в форме, где на темные цвета приходится меньший относительный шум квантования, чем на светлые.

Page 8: Пиксельное представление изображений. Введение в OpenCV

Логарифмическое преобразованиеОбщий вид логарифмического преобразования, выражается формулой

s = c*log(l+r), где с — константа и предполагается, что c > 0.

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

http://studdi.ru/images/gradational_transformation.JPG

Page 9: Пиксельное представление изображений. Введение в OpenCV

Гистограмма изображенияГистогра́мма — это график распределения полутонов изображения, в котором по горизонтальной оси представлена яркость, а по вертикали — относительное число пикселей с данным значением яркости.

Вычисление гистограммы для 8-битного полутонового изображения:vector<int> hist( 256, 0 );for (int y=0; y<h; y++) { for (int x=0; x<w; x++) { int color = image.at<unsigned char>(y,x); hist[ color ]++; }}

Page 10: Пиксельное представление изображений. Введение в OpenCV

Яркостная нормализация изображенияЭто один из способов автоматического улучшения качества изображения для восприятия человеком (но также и для последующей автоматической обработки).

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

Пусть дано изображение A, считаем в диапазоне [0..255].Amin = min( A(x,y) по всем (x,y) );Amax = max( A(x,y) по всем (x,y) );

Norm(A)(x,y) = 255 * ( A(x,y) - Amin ) / (Amax - Amin).- в результате диапазон яркостей линейно растянется на всю область.В результате изображение станет более контрастным, так как расстояние между соседники яркостями в нем увеличится.

Page 11: Пиксельное представление изображений. Введение в OpenCV

Яркостная нормализация изображения

http://www.desicolours.com/colourful-nature-pics/19/09/2008

Исходное изображение Нормализованное изображение

Page 12: Пиксельное представление изображений. Введение в OpenCV

Это также один из способов автоматического улучшения качества изображения.Целью эквализация гистограммы (эту процедуру называют также выравниванием гистограммы) является такое преобразование, чтобы, в идеале, гистограмма яркостей максимально близко отвечала бы равномерному закону распределения:1. в выходном изображении должны использоваться по-возможности все допустимые значения интенсивности,2. выходное изображения должно содержать примерно равное количество пикселей для каждого значения интенсивности.

То есть, если диапазон составляет N (=256) значений яркости, то одному значению яркости должно в идеале соответствовать w * hq = ------- пикселей. N

Эквализация гистограммы

Page 13: Пиксельное представление изображений. Введение в OpenCV

Поэтому, в значение яркости 0 должны перейти пиксели с яркостями 0, 1, 2..i(0), пока их сумма не превысит q, то есть с максимальным i(0), для которогоSum( hist[i], i=0 .. i(0) ) <= q.

Аналогично, в значение 1 должны перейти пиксели с яркостями i(0)+1, i(0)+2, ..., i(1), с условием Sum( hist[i], i=i(0)+1.. i(1) ) <= q, или, иными словами, Sum( hist[i], i=0 .. i(1) ) <= 2q....В значение n должны перейти пиксели с максимальным i(n), для которогоSum( hist[i], i=0 .. i(n) ) <= (n+1)q.

Так как q = w*h / N, получаем

Nn >= -------- Sum( hist[i], i=0 .. i(n) ) - 1. w * hтак как n целое, а равенство в дроби будет достигаться очень редко, то можно считать что Nn = int -------- Sum( hist[i], i=0 .. i(n) ). И можно сформулировать такой алгоритм: w * h

Эквализация гистограммы

Page 14: Пиксельное представление изображений. Введение в OpenCV

Алгоритм для преобразования 8-битного изображения (N = 256)Яркость n (от 0 до N-1) переходит в

Sum( hist[ i ], i = 0..n ) Eq(n) = min( int( N * ------------------------------ ), N-1 ). w * h

(берем min с N-1, так как иногда формула может дать N. Вопрос на самостоятельное размышление - когда именно это может случиться? )

В случае, когда гистограмма изображения А в диапазоне Amin, Amax примерно однородна, результат эквализации почти неотличим от яркостной нормализации.Если же нет, то эквализация позволяет проявить на изображении ранее не заметные детали и контуры.

Эквализация гистограммы

Page 15: Пиксельное представление изображений. Введение в OpenCV

Эквализация гистограммы

http://www.desicolours.com/colourful-nature-pics/19/09/2008

Исходное изображение Изображение с эквализованной гистограммой

Page 16: Пиксельное представление изображений. Введение в OpenCV

Сравнение нормализации и эквализации

http://www.desicolours.com/colourful-nature-pics/19/09/2008

Изображение с эквализованной гистограммой

Нормализованное изображение

Page 17: Пиксельное представление изображений. Введение в OpenCV

Библиотека OpenCV

"Open Computer Vision Library" Открытая библиотека с набором функций для обработки, анализа и распознавания изображений, C/C++.

Page 18: Пиксельное представление изображений. Введение в OpenCV

История развития OpenCV2000 - первая альфа-версия, поддержка Intel, C-интерфейсОсновная разработка - г. Нижний Новгород (фирма Intel).

2006 - версия 1.0

Основная разработка - г. Нижний Новгород (фирма ItSeez)2008 - поддержка Willow Garage (лаб. робототехники)

2009 - версия 2.0, классы С++

2010 - версия 2.2, реализована работа с CUDA/GPU

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

2013 (?) - планируется введение в состав khronos.org (то есть стандартизация наравне с OpenGL, OpenCL).

Page 19: Пиксельное представление изображений. Введение в OpenCV

Подключение OpenCV к VisualStudio 2010Предполагаем, что Microsoft Visual C++ 2008/2010 Express Edition и OpenCV 2.4 уже установлены - http://sourceforge.net/projects/opencvlibrary/files/latest/download

1. Запускаем VS2010

2. Создаем консольный проектFile - New - Project - Win32 Console Application, в Name ввести Project1, нажать ОК.

3. Настраиваем путиAlt+F7 - откроется окно свойств проекта

* Configuration Properties - C/C++ - General - Additional Include Directories,там добавляем "C:\Program Files\OpenCV2.4\build\include";"C:\Program Files\OpenCV2.4\build\include\opencv";

* Linker - General - Additional Library Directories:C:\Program Files\OpenCV2.4\build\x86\vc10\lib

* Linker - Input - Additional Dependencies:Release: opencv_core240.lib;opencv_features2d240.lib;opencv_highgui240.lib;opencv_imgproc240.libDebug: opencv_core240d.lib;opencv_features2d240d.lib;opencv_highgui240d.lib;opencv_imgproc240d.lib

4. Добавляем в Windows пути к dll - D:\Program Files\Opencv2.4\build\x86\vc10\bin\либо можно просто скопировать нужные dll в Release и Debug вашего проекта.

Page 20: Пиксельное представление изображений. Введение в OpenCV

Проверка работы OpenCV - считывание изображения и показ его на экране

1. Готовим входные данные:файл http://www.fitseniors.org/wp-content/uploads/2008/04/green_apple.jpgпишем в C:\green_apple.jpg 2. Пишем в Project1.cpp:#include "stdafx.h"#include "cv.h"#include "highgui.h" using namespace cv;

int main( int argc, const char** argv ){ Mat image = imread( "C:\\green_apple.jpg" ); //Загрузить изображение с диска imshow( "image", image ); //Показать изображение waitKey( 0 ); //Ждем нажатия клавиши return 0;} 3. Нажимаем F7 - компиляция, F5 - запуск. Программа покажет изображение в окне, и по нажатию любой клавиши завершит свою работу.

Внимание: если при старте напишется, что "Нет библиотеки tbb_debug.dll" - значит, на вашем компьютере ее не хватает. Можно пересобрать OpenCV с помощью CMake, а можно скачать пересобранные dll тут: www.expo32.ru/download/OpenCV2.4Dll.zip

Page 21: Пиксельное представление изображений. Введение в OpenCV

Класс Mat

Mat - основной класс для хранения изображений OpenCV.

Конструкторы:

* Пустое изображение без определенного типа : Mat imageEmpty;

* Изображение w x h пикселов, значения 0..255 :

int w=150; int h=100; Mat imageGray( cv::Size( w, h ), CV_8UC1 );

CV_8UC1 : 8U значит "unsigned 8 bit", C1 значит "один канал"

Page 22: Пиксельное представление изображений. Введение в OpenCV

* 1-канальное со значениями с плавающей точкой

Mat imageFloat( cv::Size(w, h), CV_32FC1 );

"float 32 bit"

* 3-канальное изображения со значениями 0..255 в каждом канале:

Mat imageRGB( cv::Size(w, h), CV_8UC3 );

Класс Mat

Page 23: Пиксельное представление изображений. Введение в OpenCV

1. Память для изображений выделяется и очищается автоматически

OpenCV сам создает изображение нужного типа и размера, если это изображение является выходным параметром некоторой функции:

Image imageFloat;imageGray.convertTo( imageFloat, CV_32FC1, 1.0 / 255.0 ); - здесь OpenCV сам выделит память под imageFloat.Важно, что если изображение уже нужного размера, то никаких операций по выделению памяти не производится.

2. Операции присваивания осуществляются не копированием данных (как это делает std::vector), и не путем копирования указателей, а с использованием механизма счетчика ссылок.

Класс MatУправление памятью

Page 24: Пиксельное представление изображений. Введение в OpenCV

Так как операция Mat B = A; не копирует изображение A в B, то для того, чтобы создать копию изображения для последующего независимого использования, имеются явные команды copyTo и clone:

image1.copyTo( image2 );image3 = image1.clone();

Класс MatУправление памятью

Page 25: Пиксельное представление изображений. Введение в OpenCV

Итог: 1) операция присваивания Mat B = A; работает очень быстро, и не осуществляет копирование данных, а настраивает специальным образом указатели на них. Это позволяет передавать Mat в функции прямо, без указателей и ссылок. При этом не возникнет нежелательного копирования Mat в стек (как это бы сталал std::vector).

Хотя, конечно, const Mat & будет передаваться все равно быстрее.

2) для копирования изображений нужно пользоваться явными командами copyTo и clone.

Класс MatУправление памятью

Page 26: Пиксельное представление изображений. Введение в OpenCV

Механизм счетчика ссылок (в STL это shared_ptr, в Java он на всех указателях) работает так:{

Mat A( cv::Size( 100, 100 ), CV_8UC1 );//выделилась память под изображение, при этом запомнилось,

//что эта память используется одним изображением.{

Mat B = A;//Тут память под изображение не выделяется, а просто

//данные в B указывают на ту же область в памяти. //Поэтому, если менять B, то изменится и A. //Счетчик ссылок изображения увеличился, стал равным 2.

}//Тут B вышло из области видимости, счетчик ссылок уменьшился, //и стал равен 1.

}//Тут A вышло из области видимости, счетчик ссылок стал равен 0,//и память, выделенная для него, автоматически очищается.

Класс MatУправление памятью

Page 27: Пиксельное представление изображений. Введение в OpenCV

Для этого служит функция setTo( s ),где s - цвет, задаваемый типом cv::Scalar.

Mat grayImage( cv::Size( 100, 100 ), CV_8UC1 );grayImage.setTo( cv::Scalar( 50 ) );

Mat colorImage( cv::Size( 100, 100 ), CV_8UC3 );colorImage.setTo( cv::Scalar( 50, 60, 70 ) );

Класс MatУстановка в изображение нужного значения

Page 28: Пиксельное представление изображений. Введение в OpenCV

Линейные операции над изображениями

int main( int argc, const char** argv ){ Mat image = imread( "C:\\green_apple.jpg" ); //image1 попиксельно равен 0.3*image Mat image1 = 0.3 * image;

imshow( "image", image ); imshow( "image1", image1 ); waitKey( 0 ); return 0; }

Page 29: Пиксельное представление изображений. Введение в OpenCV

Работа с прямоугольными подобластями изображения

Заменяем текст в main из предыдущего примера на:

int main( int argc, const char** argv ){ Mat image = imread( "C:\\green_apple.jpg" ); //Вырезание части картинки Rect rect = Rect(100, 100, 200, 200); //прямоугольник вырезания Mat image3; image( rect ).copyTo( image3 ); //копирование части image imshow( "image3", image3 );

//Изменение части картинки внутри самой картинки image( rect ) *= 2; imshow( "image changed", image );

waitKey( 0 ); return 0; }

Page 30: Пиксельное представление изображений. Введение в OpenCV

В OpenCV есть несколько способов попиксельного доступа к изображениям. Они различны по степени безопасности (контроль типов и выхода за границы), по скорости работы и удобству.

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

Один из способов доступа к пикселам для изображений, у которых известен тип - использование метода at. Для одноканального изображения 0...255 это делается так:

//Взятие значенияint value = imageGray.at<uchar>(y, x);

//Установка значенияimageGray.at<uchar>(y, x) = 100;

Обратите внимание, что x и y в вызове переставлены местами.

Класс MatПопиксельный доступ к изображениям

Page 31: Пиксельное представление изображений. Введение в OpenCV

Класс MatРазбиение на каналы

Функция split разбивает многоканальное изображение на каналы.Функция merge склеивает несколько одноканальных изображений в многоканальное.

void split ( const Mat& mtx, //исходное цветное изображение vector<Mat>& mv //результирующий набор 1-канальных //изображений )

void merge ( const vector<Mat>& mv, //исходный набор 1-канальных //изображений Mat& dst //результирующее цветное //изображение )

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

Page 32: Пиксельное представление изображений. Введение в OpenCV

Класс MatРазбиение на каналы

int main( int argc, const char** argv ){ Mat image = imread( "C:\\green_apple.jpg" ); //Разделение исходной картинки на три канала // - channels[0], channels[1], channels[2] vector<Mat> channels; split( image, channels ); //Показываем каналы в отдельных окнах //Обратите внимание, что красный канал - 2, а не 0. imshow( "Red", channels[2] ); imshow( "Green", channels[1] ); imshow( "Blue", channels[0] );

waitKey( 0 ); return 0; }

Page 33: Пиксельное представление изображений. Введение в OpenCV

ПримечаниеПри выводе на экране изображений с плавающей точкой средствами OpenCV надо иметь в виду, что они отображаются в предположении, что их значения лежат в [0,1]. Поэтому при конвертации 8-битных изображений в изображения с плавающей точкой нужно делать трансформацию — умножение на 1.0 / 255.0.

Для конвертации типов изображений разной битности (float и unsigned char) используется член класса convertTo. В нем второй параметр — тип получаемого изображения.

imageGray.convertTo( imageFloat, CV_32FC1, 1.0 / 255.0 );

Число каналов входа и выхода должно совпадать!

Класс MatКонвертация типов

Page 34: Пиксельное представление изображений. Введение в OpenCV

Для конвертации различных цветовых пространств используется функция cvtColor. При необходимости она способна менять число каналов.

Например, конвертация 3-канального RGB-изображения в полутоновое:

cvtColor( inputRGB, outputGray, CV_BGR2GRAY );

наоборот:cvtColor( inputGray, outputRGB, CV_GRAY2BGR );

Класс MatКонвертация типов

Page 35: Пиксельное представление изображений. Введение в OpenCV

ЛитератураКомпьютерное зрение

1. Гонсалес Р., Вудс Р. Цифровая Обработка Изображений.2. Л. Шапиро, Дж. Стокман Компьютерное зрение.

OpenCV

1. Документация OpenCV C++: http://opencv.willowgarage.com/documentation/cpp/index.html

2. G. Bradski, A. Kaehler Learning OpenCV: Computer Vision with the OpenCV Library- к сожалению, для версии OpenCV для C, а не C++.

3. Laganière R. OpenCV 2 Computer Vision Application Programming Cookbook- полезная.