mrgloom 242 Жалоба Опубликовано August 15, 2011 такое ощущение что 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); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 15, 2011 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)); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 15, 2011 только тут еще непонятно какого цвета должны быть границы, а какого фон? т.е. например когда фон черный, а границы белые cvDistTransform выдает примерно то же что и было(если границы тонкие в 1 пиксель) а так нечто уже более похожее на правду. cvCanny(grey,grey,100,200); cvNot(grey,grey); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 15, 2011 еще вопрос, хочу сделать на основе cvDistTransform что то наподобии chamfer matching как можно выполнить операцию похожую на конволюцию? т.е. проходим скользящим окном(темплейтом(над которым наверно тоже надо выполнить cvDistTransform)) по изображению которое получено с помощью cvDistTransform и вычитаем из пикселей изображения пиксели темплейта и записываем в массив допустим с координатами точки применения. потом сортируем и находим максимум это и будет местонахождение объекта(если он один), если несколько то берем какой то срез сверху. cvFilter2D я так понял делает не то, но похожее. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 15, 2011 cvFilter2D - то что нужно, ядро размером с шаблон, все забито отрицательными значениями (-1/на кол-во эл-тов ядра, или просто -1 ). Но быстрее в 2 прохода составным фильтром (Separable Convolution). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 16, 2011 мне то надо получить разность т.е. сумму(Abs(A(i,j)-B(i,j)))/template_size где A(i,j) текущий участок на изображении, который лежит под темплейтом, B(i,j) сам темлейт. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 16, 2011 Сразу не понял, тогда установить ROI, cvAbsDiff, и cvAvg. И так для каждой точки. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 17, 2011 вот написал, вроде работает, в скорости вроде выгрыша особого(по сравнению с 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); //может не обязательно } } } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах