#include "stdafx.h" #include "NCC.h" #include #include #include double InnerProduct( unsigned char *sourcePixels, int sourceCols, int sourceRows ,unsigned char *patternPixels, int patternCols, int patternRows ,double norm ,int xx ,int yy) { double NCC_value; int numerator; int i,j,x,y; i=yy;j=xx; { numerator=0; for(y=0;yImgLayer[0].Array2D[cy][cx]; int Qfront=0; int Qrear=1; int Rfront=0; int Rrear=0; int g[4]; while(Qfront= Pyd_level_max-2)//4) continue; //================================= //Divide region to 4 sub-block //cal homogeneity of 4 sub-block //================================= level++; int h=patternRows>>level; g[0]=cur_GPyd->ImgLayer[level].Array2D[yy+cy ][xx+cx ]; g[1]=cur_GPyd->ImgLayer[level].Array2D[yy+cy ][xx+cx+h]; g[2]=cur_GPyd->ImgLayer[level].Array2D[yy+cy+h][xx+cx ]; g[3]=cur_GPyd->ImgLayer[level].Array2D[yy+cy+h][xx+cx+h]; //======================== //Push g into queue //======================== if(g[0]>=_G_TH) { OrderQueue[Qrear].x=xx; OrderQueue[Qrear].y=yy; OrderQueue[Qrear].level=level; OrderQueue[Qrear].g=g[0];//*scale[level]; Qrear++; }else{ ResidualQueue[Rrear].x=xx; ResidualQueue[Rrear].y=yy; ResidualQueue[Rrear].level=level; Rrear++; } if(g[1]>=_G_TH) { OrderQueue[Qrear].x=xx+h; OrderQueue[Qrear].y=yy; OrderQueue[Qrear].level=level; OrderQueue[Qrear].g=g[1];//*scale[level]; Qrear++; }else{ ResidualQueue[Rrear].x=xx+h; ResidualQueue[Rrear].y=yy; ResidualQueue[Rrear].level=level; Rrear++; } if(g[2]>=_G_TH) { OrderQueue[Qrear].x=xx; OrderQueue[Qrear].y=yy+h; OrderQueue[Qrear].level=level; OrderQueue[Qrear].g=g[2];//*scale[level]; Qrear++; }else{ ResidualQueue[Rrear].x=xx; ResidualQueue[Rrear].y=yy+h; ResidualQueue[Rrear].level=level; Rrear++; } if(g[3]>=_G_TH) { OrderQueue[Qrear].x=xx+h; OrderQueue[Qrear].y=yy+h; OrderQueue[Qrear].level=level; OrderQueue[Qrear].g=g[3];//*scale[level]; Qrear++; }else{ ResidualQueue[Rrear].x=xx+h; ResidualQueue[Rrear].y=yy+h; ResidualQueue[Rrear].level=level; Rrear++; } }//while(Qfront>plevel; for(yy=0; yy=1.0) temp_hash_idx=0; else temp_hash_idx = (int)(_HASH_SIZE-BoundryValue*_HASH_SIZE); int temp_list_idx = Hash[temp_hash_idx].end; //================== //If new bucket //================== if(Hash[temp_hash_idx].front == -1) { Hash[temp_hash_idx].front = i; Hash[temp_hash_idx].end = i; Hash[temp_hash_idx].len = 0; } else { //========================== //add to the end of list //========================== listarray[temp_list_idx].next = i; //========================== //update hash.end //========================== Hash[temp_hash_idx].end = i; } listarray[i].next = -1;//end of list i++; } //=========================================== //Winner Update Strategy //=========================================== int IsReachTop=_FALSE; int idxNonEmpty=0; int Idx_c_nn; int level; int g_count=0; double dv; //======================================================= //Update Winner Until Reach the Max Level //======================================================= while( !IsReachTop ) { //============================= //Finding the non_empty bucket //============================= while ( Hash[idxNonEmpty].front == -1) idxNonEmpty++; //===================================== //pop temporary winner from List_array //===================================== Idx_c_nn=Hash[idxNonEmpty].front; //================================================================ //Upate the Upper Bound (UB) and LEVEL of temporary winnder //================================================================ level = listarray[Idx_c_nn].LEVEL; UB = listarray[Idx_c_nn].Hash_UB_table; norm = listarray[Idx_c_nn].Hash_Norm; xx = listarray[Idx_c_nn].position.x; yy = listarray[Idx_c_nn].position.y; idx=level; //=============================================== //Calculate Boundary Value of temporary winner //=============================================== //=========================== //pop block from Queue, //=========================== px=OrderQueue[idx].x; py=OrderQueue[idx].y; plevel=OrderQueue[idx].level; //==================================== //subtract the value of block //==================================== Template2D = TemplatePyd.ImgLayer[plevel].Array2D; Candidate2D = SourcePyd.ImgLayer[plevel].Array2D; dv=sqrt(double(Candidate2D[yy+py][xx+px])*(Template2D[cy+py][cx+px])); UB-=dv; plevel++; //=================================== //add the value of four sub_blocks //=================================== Template2D = TemplatePyd.ImgLayer[plevel].Array2D; Candidate2D = SourcePyd.ImgLayer[plevel].Array2D; h=patternCols>>plevel; v1=sqrt(double(Candidate2D[yy+py ][xx+px ])*(Template2D[cy+py ][cx+px ])); v2=sqrt(double(Candidate2D[yy+py+h][xx+px ])*(Template2D[cy+py+h][cx+px ])); v3=sqrt(double(Candidate2D[yy+py ][xx+px+h])*(Template2D[cy+py ][cx+px+h])); v4=sqrt(double(Candidate2D[yy+py+h][xx+px+h])*(Template2D[cy+py+h][cx+px+h])); // update Upper Bound UB=UB+v1+v2+v3+v4; // update Boundary value BoundryValue=UB/(norm); //=============================================== // Push temporary winner into Hash Table //=============================================== //=============================================== // Calculate Bucket Number by Boundary Value //=============================================== if(BoundryValue>=1.0) temp_hash_idx=0; else temp_hash_idx = (int)(_HASH_SIZE-BoundryValue*_HASH_SIZE); // Update level level++; listarray[Idx_c_nn].LEVEL = level; listarray[Idx_c_nn].Hash_UB_table = UB; // Is reach the top level? if(level >= level_max) { IsReachTop = _TRUE; best_x = listarray[Idx_c_nn].position.x; best_y = listarray[Idx_c_nn].position.y; break; } else { //====================================================== //remove from node_array, point to the next position //====================================================== Hash[idxNonEmpty].front = listarray[Idx_c_nn].next; } //============================================ //push temporary winner back to Hash Table //============================================ int temp_list_idx = Hash[temp_hash_idx].end; //============================== //If new bucket //============================== if(Hash[temp_hash_idx].front == -1) { Hash[temp_hash_idx].front = Idx_c_nn; Hash[temp_hash_idx].end = Idx_c_nn; Hash[temp_hash_idx].len = 0; } else { //============================== //add to the end of list //============================== listarray[temp_list_idx].next = Idx_c_nn; //update hash.end Hash[temp_hash_idx].end = Idx_c_nn; Hash[temp_hash_idx].len++; } listarray[Idx_c_nn].next = -1; g_count++; } double NCC_max; double NCC_value; int best_idx; if(IsReachTop) { // Checking all candidates in the same bucket // bucket: idxNonEmpty //=================== //init //=================== int idx=Hash[idxNonEmpty].front; int x1 = listarray[idx].position.x; int y1 = listarray[idx].position.y; //======================== //similarity measure //======================== best_idx = idx; NCC_max =InnerProduct( sourcePixels, sourceCols, sourceRows ,patternPixels, patternCols, patternRows ,listarray[idx].Hash_Norm ,x1//j ,y1);//i); //============================== //tracing the next position //============================== idx=listarray[idx].next; while( -1 != idx ) { //======================= //similarity measure //======================= x1 = listarray[idx].position.x; y1 = listarray[idx].position.y; NCC_value =InnerProduct( sourcePixels, sourceCols, sourceRows ,patternPixels, patternCols, patternRows ,listarray[idx].Hash_Norm ,x1//j ,y1);//i); //=============================== //update the min and min_idx //=============================== if(NCC_value > NCC_max) { NCC_max=NCC_value; best_idx=idx; } //tracing idx=listarray[idx].next; } } best_x = listarray[best_idx].position.x; best_y = listarray[best_idx].position.y; //================== //free memory //================== free(Hash); free(listarray); delete [] GradientMap; TemplatePyd.ClearPyd(); GradientPyd.ClearPyd(); SourcePyd.ClearPyd(); free(OrderQueue); free(ResidualQueue); return NCC_max; }