cvFloodFill() — полезная функция, если требуется пометить или изолировать область изображения для дальнейшего анализа. Т.е. эта функция реализует заливку области, что наводит на мысли об аналогичных инструментах в графических редакторах :)
— заполняет связанную область заданным цветом. Начиная с заданной начальной точки и далее, определяя принадлежность области по близости значений соседних пикселей.
image — входное изображение (1- или 3-канальное), 8-битное или 32F. Изображение модифицируется функцией, если не установлен флаг CV_FLOODFILL_MASK_ONLY
seed_point — начальная точка
new_val — новое значение пикселей
lo_diff — максимальное нижнее значение разницы в яркости/цвете между наблюдаемым пикселем и одним из его соседей, чтобы добавить его в область. В случае 8-битного цветного изображения — это упакованное значение.
up_diff — максимальное верхнее значение разницы в яркости/цвете между наблюдаемым пикселем и одним из его соседей, чтобы добавить его в область. В случае 8-битного цветного изображения — это упакованное значение.
comp — указатель на структуру CvConnectedComp, которую заполняет функция, возвращая в неё информацию о заполненной области:
typedef struct CvConnectedComp
{
double area; /* площадь */
CvScalar value; /* усреднённый цвет области */
CvRect rect; /* ROI - область интереса */
CvSeq* contour; /* граница */
}
CvConnectedComp;
flags — флаг операции. Младшие биты содержат значение связности — 4(по-умолчанию) или 8, используемое функцией. Связность определяет сколько соседей пикселя обрабатываются. Старшие биты могут быть 0 или комбинацией флагов:
CV_FLOODFILL_FIXED_RANGE — если установлен, используется разница между текущим пикселем и начальным пикселем, в противном случае — используется разница между соседними пикселями (плавающий диапазон)
CV_FLOODFILL_MASK_ONLY — если установлен, то функция не вносит изменений в изображение, но заполняет маску (которая, в данном случа, должна быть отлична от NULL )
mask — маска операции, 1-канальное 8-битное изображение, на 2 пикселя шире и длинее, чем изображение. Если отлично от NULL, то функция использует и обновляет маску. Заполнение не будет идти поверх ненулевых пикселей маски. Например, детектор границ может использоваться в качестве маски для остановки заливки на границах. Возможно использование одной маски в нескольких вызовах функции, для уверенности, что заполненные области не перекроются.
! NB: т.к. маска больше, чем изображение — пиксель маски, соответствующий пикселю (x,y) изображения, имеет координаты (x+1, y+1)
//
// пример использования функции cvFloodFill()
// для заливки области
// начальный пиксель области выбирается по клику мышкой
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
// заливка области картинки цветом
void fill(IplImage* src, CvPoint seed, CvScalar color=CV_RGB(255, 0, 0))
{
assert(src);
CvConnectedComp comp;
cvFloodFill( src, seed, color,
cvScalarAll(10), // минимальная разность
cvScalarAll(10), // максимальная разность
&comp,
CV_FLOODFILL_FIXED_RANGE + 8,
0);
// покажем площадь заливки
printf("[filled area] %.2f\n", comp.area);
}
// обработчик событий от мышки
void myMouseCallback( int event, int x, int y, int flags, void* param )
{
IplImage* img = (IplImage*) param;
switch( event ){
case CV_EVENT_MOUSEMOVE:
break;
case CV_EVENT_LBUTTONDOWN:
printf("%d x %d\n", x, y);
// вызываем нашу функцию-обёртку вокруг cvFloodFill()
fill(img, cvPoint(x, y));
break;
case CV_EVENT_LBUTTONUP:
break;
}
}
int main(int argc, char* argv[])
{
IplImage *src=0, *dst=0;
// имя картинки задаётся первым параметром
char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
// получаем картинку
src = cvLoadImage(filename, 1);
printf("[i] image: %s\n", filename);
assert( src != 0 );
// покажем изображение
cvNamedWindow( "original", 1 );
// вешаем обработчик мышки
cvSetMouseCallback( "original", myMouseCallback, (void*) src);
while(1){
// показываем картинку
cvShowImage( "original", src );
char c = cvWaitKey(33);
if (c == 27) { // если нажата ESC - выходим
break;
}
}
// освобождаем ресурсы
cvReleaseImage(&src);
cvReleaseImage(&dst);
// удаляем окна
cvDestroyAllWindows();
return 0;
}
Пример работы функции при клике в верхнем левом углу и установленном флаге CV_FLOODFILL_FIXED_RANGE. Если же этот флаг убрать, то при той же начальной точке будет закрашена почти вся картинка.
Привет! Спасибо за классные уроки.
А есть ли способ обнаружить на картинке все пиксели заданного цвета, с некоторой разницей яркости, и изменить их цвет на другой?
Спасибо.
Комментарии (6)
RSS свернуть / развернуть*dst — походу лишние.:)
loGIc
А есть ли способ обнаружить на картинке все пиксели заданного цвета, с некоторой разницей яркости, и изменить их цвет на другой?
Спасибо.
Dreddik
noonv
Francuz
noonv
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.