Перейти к содержимому
Compvision.ru
CyMKuH

FloodMask

Recommended Posts

Здравствуйте!

Недавно познакомился с библиотекой. Прошу помощи.

Есть широко известная функция cvFloodFill, выполняющая заливку смежных схожих пикселов с определенным порогом. Нужна функция, выполняющая только поиск таковых. Скажем, отмечающая область заливки маской, преобразующая ROI или сразу создающая дубликат области. В конечном счете хочется получить бинарную копию прямоугольника, ограничивающего искомую область, где "закрашиваемая часть" будет выделена одним цветом, а все остальное - другим.

Есть ли такая функция в библиотеке, или ее придется написать?

Я пока не очень осознал логику пакета и не хочу изобретать велосипеды. В документации и гайде от O'Reily не нашел.

И совсем ламерский вопрос. Для написания этой функции нужны тривиальные GetPixel(x,y) и SetPixel(x,y,v), их тоже нет. Нормально ли, что для доступа к данным автор предлагает пользовать эту конструкцию, или я что-то не уловил? о_О

float* ptr = (const float*)(mat->data.ptr + row * mat->step + cols);

Спасибо за внимание!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нужная Вам функция и есть FloodFill:

void cvFloodFill(

  CvArr* image,

  CvPoint seed point,

  CvScalar new_val,

  CvScalar lo diff=cvScalarAll(0),

  CvScalar up diff=cvScalarAll(0),

  CvConnectedComp* comp=NULL,

  int flags=4,

  CvArr* mask=NULL );

Если flag содержит CV_FLOODFILL_MASK_ONLY, то значение new_val игнорируется и заливается не само входное изображение image, а mask (естественно она не должна быть NULL). Только обратите внимание на то, что mask имеет ширину и высоту на 2 пиксела больше чем image и пикселу (x,y) на image соответствует пиксел (x-1,y-1) на mask.

Ответ на свой второй вопрос, Вы можите найди здесь http://www.compvision.ru/wiki/Доступ_к_элементам_и_подматрицам

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо за ответ! Помогло. Ниже примерный код, если кому пригодится.

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

// Возвращает указатель на матрицу, содержащую бинарное изображение только выделенной фигуры

CvMat* floodMask(int x, int y, CvMat* image) {

	// Создаем матрицу маски. Ее размер на 2 больше, чем у исходного изображения. Закрашиваем 0.

	CvMat* mask = cvCreateMat(image->height + 2, image->width + 2, CV_8UC1);

	cvSet(mask, cvScalar(0));


	// Флаги заливки - манипулируйте по необходимоcти

	int flags = 8 | CV_FLOODFILL_MASK_ONLY | CV_FLOODFILL_FIXED_RANGE | (255 << 8);


	// Выделяем фигуру в матрице с маской

	cvFloodFill(image, cvPoint(x,y), cvScalarAll(1), cvScalarAll(1), cvScalarAll(1), NULL, flags, mask);

	cvRectangle(mask, cvPoint(0,0), cvPoint(mask->width - 1, mask->height -1), cvScalar(0));


	// Вычисляем построчно/постолбно сумму всех пикселов в строке. Если не равна 0 - значит, в строке/столбце есть выделенная фигура

	CvMat* yys = cvCreateMat(mask->height, 1, CV_32SC1);

	CvMat* xxs = cvCreateMat(1, mask->width, CV_32SC1);

	cvReduce(mask, yys, 1, CV_REDUCE_SUM);

	cvReduce(mask, xxs, 0, CV_REDUCE_SUM);


	// Теперь ищем габариты выделенной фигуры

	int* ptr = yys->data.i;


	int y1 = 0;

	for (; (*ptr) == 0; ptr++)

		y1++;


	int height = 0;

	for (; (*ptr) != 0; ptr++) 

		height++;


	ptr = xxs->data.i;


	int x1 = 0;

	for (; (*ptr) == 0; ptr++)

		x1++;


	int width = 0;

	for (; (*ptr) != 0; ptr++)

		width++;


	// Сохраняем и возвращаем фигуру

	CvMat* out = cvCreateMat(width, height, CV_8UC1);

	cvGetSubRect(mask, out, cvRect(x1, y1, width, height));

	return out;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×