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

CyMKuH

Пользователи
  • Количество публикаций

    2
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные пользователем CyMKuH


  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;
    
    }


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

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

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

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

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

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

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

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

×