Angle and Scale Invariant template matching using OpenCV -
function rotates template image 0 180 (or upto 360) degrees search related matches(in angles) in source image different scale.
the function had been written in opencv c interface. when tried port opencv c++ interface , getting lot of errors. 1 please me port opencv c++ interface.
void templatematch() { int i, j, x, y, key; double minval; char windownamesource[] = "original image"; char windownamedestination[] = "result image"; char windownamecoefficientofcorrelation[] = "coefficient of correlation image"; cvpoint minloc; cvpoint temploc; iplimage *sourceimage = cvloadimage("template_source.jpg", cv_load_image_anydepth | cv_load_image_anycolor); iplimage *templateimage = cvloadimage("template.jpg", cv_load_image_anydepth | cv_load_image_anycolor); iplimage *graysourceimage = cvcreateimage(cvgetsize(sourceimage), ipl_depth_8u, 1); iplimage *graytemplateimage =cvcreateimage(cvgetsize(templateimage),ipl_depth_8u,1); iplimage *binarysourceimage = cvcreateimage(cvgetsize(sourceimage), ipl_depth_8u, 1); iplimage *binarytemplateimage = cvcreateimage(cvgetsize(templateimage), ipl_depth_8u, 1); iplimage *destinationimage = cvcreateimage(cvgetsize(sourceimage), ipl_depth_8u, 3); cvcopy(sourceimage, destinationimage); cvcvtcolor(sourceimage, graysourceimage, cv_rgb2gray); cvcvtcolor(templateimage, graytemplateimage, cv_rgb2gray); cvthreshold(graysourceimage, binarysourceimage, 200, 255, cv_thresh_otsu ); cvthreshold(graytemplateimage, binarytemplateimage, 200, 255, cv_thresh_otsu); int templateheight = templateimage->height; int templatewidth = templateimage->width; float templatescale = 0.5f; for(i = 2; <= 3; i++) { int temptemplateheight = (int)(templatewidth * (i * templatescale)); int temptemplatewidth = (int)(templateheight * (i * templatescale)); iplimage *tempbinarytemplateimage = cvcreateimage(cvsize(temptemplatewidth, temptemplateheight), ipl_depth_8u, 1); // w - w + 1, h - h + 1 iplimage *result = cvcreateimage(cvsize(sourceimage->width - temptemplatewidth + 1, sourceimage->height - temptemplateheight + 1), ipl_depth_32f, 1); cvresize(binarytemplateimage, tempbinarytemplateimage, cv_inter_linear); float degree = 20.0f; for(j = 0; j <= 9; j++) { iplimage *rotatebinarytemplateimage = cvcreateimage(cvsize(tempbinarytemplateimage- >width, tempbinarytemplateimage->height), ipl_depth_8u, 1); //cvshowimage(windownamesource, tempbinarytemplateimage); //cvwaitkey(0); for(y = 0; y < temptemplateheight; y++) { for(x = 0; x < temptemplatewidth; x++) { rotatebinarytemplateimage->imagedata[y * temptemplatewidth + x] = 255; } } for(y = 0; y < temptemplateheight; y++) { for(x = 0; x < temptemplatewidth; x++) { float radian = (float)j * degree * cv_pi / 180.0f; int scale = y * temptemplatewidth + x; int rotatey = - sin(radian) * ((float)x - (float)temptemplatewidth / 2.0f) + cos(radian) * ((float)y - (float)temptemplateheight / 2.0f) + temptemplateheight / 2; int rotatex = cos(radian) * ((float)x - (float)temptemplatewidth / 2.0f) + sin(radian) * ((float)y - (float)temptemplateheight / 2.0f) + temptemplatewidth / 2; if(rotatey < temptemplateheight && rotatex < temptemplatewidth && rotatey >= 0 && rotatex >= 0) rotatebinarytemplateimage->imagedata[scale] = tempbinarytemplateimage->imagedata[rotatey * temptemplatewidth + rotatex]; } } //cvshowimage(windownamesource, rotatebinarytemplateimage); //cvwaitkey(0); cvmatchtemplate(binarysourceimage, rotatebinarytemplateimage, result, cv_tm_sqdiff_normed); //cvmatchtemplate(binarysourceimage, rotatebinarytemplateimage, result, cv_tm_sqdiff); cvminmaxloc(result, &minval, null, &minloc, null, null); printf(": %f%%\n", (int)(i * 0.5 * 100), j * 20, (1 - minval) * 100); if(minval < 0.065) // 1 - 0.065 = 0.935 : 93.5% { temploc.x = minloc.x + temptemplatewidth; temploc.y = minloc.y + temptemplateheight; cvrectangle(destinationimage, minloc, temploc, cv_rgb(0, 255, 0), 1, 8, 0); } } //cvshowimage(windownamesource, result); //cvwaitkey(0); cvreleaseimage(&tempbinarytemplateimage); cvreleaseimage(&result); } // cvshowimage(windownamesource, sourceimage); // cvshowimage(windownamecoefficientofcorrelation, result); cvshowimage(windownamedestination, destinationimage); key = cvwaitkey(0); cvreleaseimage(&sourceimage); cvreleaseimage(&templateimage); cvreleaseimage(&graysourceimage); cvreleaseimage(&graytemplateimage); cvreleaseimage(&binarysourceimage); cvreleaseimage(&binarytemplateimage); cvreleaseimage(&destinationimage); cvdestroywindow(windownamesource); cvdestroywindow(windownamedestination); cvdestroywindow(windownamecoefficientofcorrelation); }
result :
template image:
result image:
the function above puts rectangles around perfect matches (angle , scale invariant) in image .....
now, have been trying port code c++ interface. if needs more details please let me know.
c++ port of above code:
mat templatematch(mat sourceimage, mat templateimage){ double minval; point minloc; point temploc; mat graysourceimage = mat(sourceimage.size(),cv_8uc1); mat graytemplateimage = mat(templateimage.size(),cv_8uc1); mat binarysourceimage = mat(sourceimage.size(),cv_8uc1); mat binarytemplateimage = mat(templateimage.size(),cv_8uc1); mat destinationimage = mat(sourceimage.size(),cv_8uc3); sourceimage.copyto(destinationimage); cvtcolor(sourceimage, graysourceimage, cv_bgr2gray); cvtcolor(templateimage, graytemplateimage, cv_bgr2gray); threshold(graysourceimage, binarysourceimage, 200, 255, cv_thresh_otsu ); threshold(graytemplateimage, binarytemplateimage, 200, 255, cv_thresh_otsu); int templateheight = templateimage.rows; int templatewidth = templateimage.cols; float templatescale = 0.5f; for(int = 2; <= 3; i++){ int temptemplateheight = (int)(templatewidth * (i * templatescale)); int temptemplatewidth = (int)(templateheight * (i * templatescale)); mat tempbinarytemplateimage = mat(size(temptemplatewidth,temptemplateheight),cv_8uc1); mat result = mat(size(sourceimage.cols - temptemplatewidth + 1,sourceimage.rows - temptemplateheight + 1),cv_32fc1); resize(binarytemplateimage,tempbinarytemplateimage,size(tempbinarytemplateimage.cols,tempbinarytemplateimage.rows),0,0,inter_linear); float degree = 20.0f; for(int j = 0; j <= 9; j++){ mat rotatebinarytemplateimage = mat(size(tempbinarytemplateimage.cols, tempbinarytemplateimage.rows), cv_8uc1); for(int y = 0; y < temptemplateheight; y++){ for(int x = 0; x < temptemplatewidth; x++){ rotatebinarytemplateimage.data[y * temptemplatewidth + x] = 255; } } for(int y = 0; y < temptemplateheight; y++){ for(int x = 0; x < temptemplatewidth; x++){ float radian = (float)j * degree * cv_pi / 180.0f; int scale = y * temptemplatewidth + x; int rotatey = - sin(radian) * ((float)x - (float)temptemplatewidth / 2.0f) + cos(radian) * ((float)y - (float)temptemplateheight / 2.0f) + temptemplateheight / 2; int rotatex = cos(radian) * ((float)x - (float)temptemplatewidth / 2.0f) + sin(radian) * ((float)y - (float)temptemplateheight / 2.0f) + temptemplatewidth / 2; if(rotatey < temptemplateheight && rotatex < temptemplatewidth && rotatey >= 0 && rotatex >= 0) rotatebinarytemplateimage.data[scale] = tempbinarytemplateimage.data[rotatey * temptemplatewidth + rotatex]; } } matchtemplate(binarysourceimage, rotatebinarytemplateimage, result, cv_tm_sqdiff_normed); minmaxloc(result, &minval, 0, &minloc, 0, mat()); cout<<(int)(i * 0.5 * 100)<<" , "<< j * 20<<" , "<< (1 - minval) * 100<<endl; if(minval < 0.065){ // 1 - 0.065 = 0.935 : 93.5% temploc.x = minloc.x + temptemplatewidth; temploc.y = minloc.y + temptemplateheight; rectangle(destinationimage, minloc, temploc, cv_rgb(0, 255, 0), 1, 8, 0); } } } return destinationimage; }
Comments
Post a Comment