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

cvDistTransform

Recommended Posts

такое ощущение что cvDistTransform ничего не делает

или неправильно выводится через cvShowImage

CvMat* distance_transform(IplImage* grey)

{

	int depth= grey->nChannels;

	CvMat* dst = cvCreateMat(grey->height,grey->width, CV_32FC1 );

	cvDistTransform((CvMat*)grey,dst/*,CV_DIST_L2,5*/);

	return dst;

}
IplImage* grey= cvLoadImage("1_templ.PNG",0);

	CvMat* out= distance_transform(grey);

	cvShowImage("result", (IplImage*)out);

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


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

cvConvertScale

CvPoint minLoc, maxLoc;

	double minVal = 0, maxVal = 0;

	cvMinMaxLoc(out, &minVal, &maxVal, &minLoc, &maxLoc, 0);

	cvConvertScale(out,out1,(double)255/(maxVal-minVal),(double)(-minVal)*255/(maxVal-minVal));

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


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

только тут еще непонятно какого цвета должны быть границы, а какого фон?

т.е. например когда фон черный, а границы белые cvDistTransform выдает примерно то же что и было(если границы тонкие в 1 пиксель)

а так нечто уже более похожее на правду.

cvCanny(grey,grey,100,200);

	cvNot(grey,grey);

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


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

еще вопрос, хочу сделать на основе cvDistTransform что то наподобии chamfer matching

как можно выполнить операцию похожую на конволюцию?

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

потом сортируем и находим максимум это и будет местонахождение объекта(если он один), если несколько то берем какой то срез сверху.

cvFilter2D я так понял делает не то, но похожее.

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


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

cvFilter2D - то что нужно, ядро размером с шаблон, все забито отрицательными значениями (-1/на кол-во эл-тов ядра, или просто -1 ). Но быстрее в 2 прохода составным фильтром (Separable Convolution).

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


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

мне то надо получить разность

т.е. сумму(Abs(A(i,j)-B(i,j)))/template_size

где A(i,j) текущий участок на изображении, который лежит под темплейтом, B(i,j) сам темлейт.

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


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

Сразу не понял, тогда установить ROI, cvAbsDiff, и cvAvg. И так для каждой точки.

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


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

вот написал, вроде работает, в скорости вроде выгрыша особого(по сравнению с chamfer matching) нету, хотя работает быстрее, т.к. ищет всего 1 темплейт , и более просто-понятно реализовано.

потом возможно надо будет добавить использование пирамид(что возможно увеличит скорость), и еще есть идея проходить окном Image*max_scale внутри которого будут все скейлы вплоть до Image*min_scale(хотя так скорее всего выигрыша не будет), потом добавить повороты темлейтов и еще перенести это все на куду или хотя бы добавить многопоточность по данным.

/*IplImage**/CvMat* distance_transform(IplImage* grey)

{

	cvCanny(grey,grey,100,200);//не обязательно

	//cvNot(grey,grey);

	CvMat* dst = cvCreateMat(grey->height,grey->width, CV_32FC1 );

	cvDistTransform((CvMat*)grey,dst/*,CV_DIST_L2,5*/);

	return dst;

}
////проходим окном-темплейтом

/*CvMat**/IplImage* get_result_map(/*CvMat**/IplImage* src, /*CvMat**/IplImage* temp,float& min, int& min_x, int& min_y)

{

	//CvMat* dst= cvCreateMat(temp->height,temp->width, IPL_DEPTH_8U/*CV_32FC1*/);

	//CvMat* out= cvCreateMat(src->height,src->width, IPL_DEPTH_8U/*CV_32FC1*/ );

	IplImage* dst= cvCreateImage(cvSize(temp->width,temp->height),IPL_DEPTH_8U, 1);

	IplImage* out= cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U, 1);

	CvScalar sc;

	min=INT_MAX;

	min_x=0;

	min_y=0;


	/*for(int y=0;y<src->rows-temp->rows;++y)

	{

		for (int x=0;x<src->cols-temp->cols;++x)

		{*/

	for(int y=0;y<src->height-temp->height;++y)

	{

		for (int x=0;x<src->width-temp->width;++x)

		{

			cvSetImageROI(/*(IplImage*)*/src,cvRect(x,y,temp->width,temp->height));

			cvAbsDiff(src,temp,dst);

			sc= cvAvg(dst);

			float f =sc.val[0];

			if (f<min)

			{

				min=f;

                                min_x=x;

                                min_y=y;

			}

			cvResetImageROI(src); //может не обязательно

		}

	}

}

  • Like 1

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×