29. OpenCV шаг за шагом. Интегральное изображение


Оглавление
1. OpenCV шаг за шагом. Введение.
2. Установка.
3. Hello World.
4. Загрузка картинки.
...
26. Операторы Собеля и Лапласа
27. Детектор границ Кенни (Canny)
28. Преобразование Хафа
29. Интегральное изображение

Раз уж мы научились брать производную от изображения, то было бы неплохо брать и интеграл изображения :)

Интегральное представление изображения — это матрица, размерность которой совпадает с размерностью исходного изображения. Элементы этой матрицы рассчитываются по формуле:
II(x,y) = Summ( I(i,j) )
, где I(i,j) — яркость пикселя исходного изображения.
Т.о., каждый элемент интегрального изображения II[x,y] содержит в себе сумму пикселей изображения в прямоугольнике от (0,0) до (x,y).
Рассчет интегрального изображения занимает линейное время, пропорциональное числу пикселей исходного изображении.

Рассчет интегрального изображения II можно производить по рекуррентной формуле:
II(x,y) = I(x,y) — II(x-1,y-1) + II(x,y-1) + II(x-1,y)

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

Например, интересующий нас прямоугольник ABCD:


Сумму внутри прямоугольника можно выразить через суммы и разности смежных прямоугольников по формуле:
SumOfRect(ABCD) = II(A) + II(С) — II(B) — II(D)


Не верится? Возьмём в руки Excel и проверим:


В OpenCV для подсчёта интегрального изображения уже есть функция cvIntegral():

#define cvIntegralImage     cvIntegral

CVAPI(void) cvIntegral( const CvArr* image, CvArr* sum,
                       CvArr* sqsum CV_DEFAULT(NULL),
                       CvArr* tilted_sum CV_DEFAULT(NULL));
— вычисление интегрального представления изображения (integral image) по формуле:
SUM(X,Y) = sum(x<X,y<Y)I(x,y)

image — исходное изображение WxH, 8-битное или 32F, 64F
sum — интегральное представление (W+1)x(H+1), 32F или 64F
sqsum — интегральное представление для квадрата величин пикселей (W+1)x(H+1), 64F
tilted_sum — интегральное представление для изображения, повёрнутого на 45 градусов, тип аналогичен sum

формулы:
sum(X,Y) = Summ( I(x,y) )
	sqsum(X,Y) = Summ( I(x,y)^2)


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

Пример:
//
// интегральное изображение cvIntegral()
//
// http://robocraft.ru
//

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
	IplImage *src=0, *dst=0, *dst2=0, *dst3=0;

	// имя картинки задаётся первым параметром
	char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
	// получаем картинку
	src = cvLoadImage(filename, 0);

	printf("[i] image: %s\n", filename);
	assert( src != 0 );

	// покажем изображение
	cvNamedWindow( "original", 1 );
	cvShowImage( "original", src );

	dst = cvCreateImage( cvSize(src->width+1, src->height+1), IPL_DEPTH_64F, 1);
	dst2 = cvCreateImage( cvSize(src->width+1, src->height+1), IPL_DEPTH_64F, 1);
	dst3 = cvCreateImage( cvSize(src->width+1, src->height+1), IPL_DEPTH_64F, 1);

	// получаем интегральное изображение
	cvIntegral(src, dst, dst2, dst3);

	cvNamedWindow( "cvIntegral", 1 );
	cvShowImage( "cvIntegral", dst );
	cvNamedWindow( "cvIntegral 2", 1 );
	cvShowImage( "cvIntegral 2", dst2 );
	cvNamedWindow( "cvIntegral tilted");
	cvShowImage( "cvIntegral tilted", dst3 );

	// ждём нажатия клавиши
	cvWaitKey(0);

	// освобождаем ресурсы
	cvReleaseImage(&src);
	cvReleaseImage(&dst);
	cvReleaseImage(&dst2);
	// удаляем окна
	cvDestroyAllWindows();
	return 0;
}

скачать иcходник (29-cvIntegral.cpp)


Применение:
интегральное изображение использутся для быстрого вычисления яркости заданных участков изображения ( в вейвлет-преобразованиях, фильтрах Хаара, рассчёте дескрипторов (SURF)).

Далее: Трансформация изображения — аффинные преобразования, гомография

Ссылки:
Интегральное представление изображений
en.wikipedia.org/wiki/Summed_area_table
en.wikipedia.org/wiki/Discrete_Green%27s_theorem
  • 0
  • 2 июня 2011, 20:03
  • noonv

Комментарии (1)

RSS свернуть / развернуть
+
+1
Огромное спасибо за прекрасные примеры и объяснения, просвятился аш свечусь :-)
С нетерпением жду продолжения(больше всего детектирование лица, в видео потоке)
Еще раз огромное спасибо.
avatar

Serega

  • 13 июля 2011, 16:23

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