float WeightedDIDCompass::computeAngle( Img *SS, Img *CV, bool useWeight ) { // Return the angle that the angle of rotation between the CV and SS by // finding the rotation of CV with the minimum difference to SS. float lowestSSD = FLT_MAX; int bestShift = 0; for ( int shift=0; shift < width; shift++ ) { ImgOps::rotate(CV, shift, &Rotated); ImgOps::sqdDiff(SS, &Rotated, &SqdDiff); if (smoothRadius > 0) ImgOps::smooth(&SqdDiff, &SqdDiffSmoothed, smoothRadius); else SqdDiffSmoothed = SqdDiff; if (useWeight) ImgOps::mult(&SqdDiffSmoothed, &FinalWeight, &SqdDiffSmoothed); float ssd = SqdDiffSmoothed.getSum(); if ( ssd < lowestSSD ) { lowestSSD = ssd; bestShift = shift; } } //if ( debug && learnIndex >= learnStart && learnIndex <= learnStop ) { if ( debug ) { Img* Temp1 = new Img(width, height); Img* Temp2 = new Img(width, height); float threshold = FinalWeight.getMax() / 4.0; Temp2 = ImgOps::threshold(&FinalWeight, threshold, Temp1); imgWindow->clear(); imgWindow->addImg("SS", *SS); imgWindow->addImg("InsWeight", InstWeight); imgWindow->addImg("FinalWeight", FinalWeight); imgWindow->addImg("Thresholded Weight", *Temp2); imgWindow->refresh(); Img* Overlay = new Img(width, height); for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { if ( Temp2->get(x, y) == 1 ) Overlay->set(x, y, 1); else Overlay->set(x, y, SS->get(x,y)); } } ostringstream oss; oss << setfill('0') << setw(2); oss << learnIndex; oss << ".png"; Overlay->save("overlay" + oss.str()); FinalWeight.save("weight" + oss.str()); Temp2->save("thresholded" + oss.str()); } // A negative image rotation (rotation to the left) corresponds // to a positive angle. Hence the negative sign below. return -Angles::int2angle(bestShift, CV->getWidth()); }