/** \brief Initializes the image pyramid from an input image (level 0). * * @param img - Input image (level 0). * @param useCv - Set to true, if opencv (cv::pyrDown) should be used for the pyramid creation. */ void computeFromImage(const cv::Mat& img, const bool useCv = false){ img.copyTo(imgs_[0]); centers_[0] = cv::Point2f(0,0); for(int i=1; i<n_levels; ++i){ if(!useCv){ halfSample(imgs_[i-1],imgs_[i]); centers_[i].x = centers_[i-1].x-pow(0.5,2-i)*(float)(imgs_[i-1].rows%2); centers_[i].y = centers_[i-1].y-pow(0.5,2-i)*(float)(imgs_[i-1].cols%2); } else { cv::pyrDown(imgs_[i-1],imgs_[i],cv::Size(imgs_[i-1].cols/2, imgs_[i-1].rows/2)); centers_[i].x = centers_[i-1].x-pow(0.5,2-i)*(float)((imgs_[i-1].rows%2)+1); centers_[i].y = centers_[i-1].y-pow(0.5,2-i)*(float)((imgs_[i-1].cols%2)+1); } } }
Transform12 registerVolume(Volume* baseVol1, Volume* regVol1) { Volume* baseVol2 = halfSample(baseVol1); Volume* baseVol4 = halfSample(baseVol2); Volume* baseVol8 = halfSample(baseVol4); Volume* regVol2 = halfSample(regVol1); Volume* regVol4 = halfSample(regVol2); Volume* regVol8 = halfSample(regVol4); int t1=clock(); Transform12 result; float medianScale=0; //8mm stage start initVolumeData(baseVol8,regVol8); float4* coarseGrid=new float4[coarseAngleCount*coarseAngleCount*coarseAngleCount]; coarseRegister(baseVol8,regVol8,coarseGrid,medianScale); float4* finerGrid=new float4[finerAngleCount*finerAngleCount*finerAngleCount]; float* finerResults=new float[finerAngleCount*finerAngleCount*finerAngleCount]; buildFinerGrid(coarseGrid,finerGrid); finerRegister( baseVol8, regVol8, finerGrid, finerResults, medianScale); freeVolumeData(); int* minima=new int[finerAngleCount*finerAngleCount*finerAngleCount / 8]; int minimaCount=0; findMinima(finerResults,minima,minimaCount); Transform7 globalMinima[FLIRT_MINIMA_COUNT]; sortMinima(finerGrid,finerResults,minima,minimaCount,globalMinima); printf("MedianScale is:%f,minimaCount is%d\n",medianScale,minimaCount); //4mm stage start initVolumeData(baseVol4,regVol4); Transform7 higherResStart[FLIRT_HIGHER_RESOLUTION_START]; Transform12 t12[FLIRT_HIGHER_RESOLUTION_START]; float finalResult[FLIRT_HIGHER_RESOLUTION_START]; perturbationStage(baseVol4,regVol4,globalMinima,higherResStart); freeVolumeData(); //2mm stage start initVolumeData(baseVol2,regVol2); for(int i=0;i<FLIRT_HIGHER_RESOLUTION_START;i++) t12[i]=optimize2mm(baseVol2,regVol2,higherResStart[i]); freeVolumeData(); //1mm stage start initVolumeData(baseVol1,regVol1); int t2=clock(); printf("\n\ntime used:%dms,global count is:%d\n",t2-t1,globalCount); float minValue=0; for(int i=0;i<FLIRT_HIGHER_RESOLUTION_START;i++) { Transform12 T=t12[i]; finalResult[i]=optimize1mm(baseVol1,regVol1,T); t12[i]=T; if(minValue>finalResult[i])result=t12[i]; printf("12 DOF 1mm:rotation(%f,%f,%f),trans(%f,%f,%f),scale(%f,%f,%f),skew(%f,%f,%f),value is:%f\n",T.rotation.x,T.rotation.y,T.rotation.z,T.translation.x,T.translation.y,T.translation.z,T.scale.x,T.scale.y,T.scale.z,T.skew.x,T.skew.y,T.skew.z,finalResult[i]); } freeVolumeData(); t2=clock(); printf("\n\ntime used:%dms,global count is:%d\n",t2-t1,globalCount); releaseVolume(baseVol2); releaseVolume(baseVol4); releaseVolume(baseVol8); releaseVolume(regVol2); releaseVolume(regVol4); releaseVolume(regVol8); return result; }