// The strip alignment from S.DenovoBestAngle (followed by SetXY) // produces a transform A->B = best.T for the scaled down scapes. // Here's how to convert that to a transform between the original // montages: // // Recapitulate total process... // TAffine Rbi, Ra, t; // // Scale back up // best.T.MulXY( scr.crossscale ); // A.x0 *= scr.crossscale; // A.y0 *= scr.crossscale; // B.x0 *= scr.crossscale; // B.y0 *= scr.crossscale; // // A-montage -> A-oriented // Ra.NUSetRot( A.deg*PI/180 ); // // A-oriented -> A-scape // Ra.AddXY( -A.x0, -A.y0 ); // // A-scape -> B-scape // t = best.T * Ra; // // B-scape -> B-oriented // t.AddXY( B.x0, B.y0 ); // // B-oriented -> B-montage // Rbi.NUSetRot( -B.deg*PI/180 ); // best.T = Rbi * t; // static void ScapeStuff() { clock_t t0 = StartTiming(); CSuperscape A, B; ThmRec thm; CThmScan S; CorRec best; B.FindLayerIndices( gArgs.zb ); B.OrientLayer(); if( gArgs.ismb ) { char buf[256]; B.MakeWholeRaster(); sprintf( buf, "montages/M_%d_0.png", gArgs.zb ); B.DrawRas( buf ); B.KillRas(); B.WriteMeta( 'M', gArgs.zb ); t0 = StopTiming( flog, "MakeMontage", t0 ); } if( !gArgs.isab ) return; A.FindLayerIndices( gArgs.za ); A.OrientLayer(); MakeStripRasters( A, B ); t0 = StopTiming( flog, "MakeStrips", t0 ); A.MakePoints( thm.av, thm.ap ); A.WriteMeta( 'A', gArgs.za ); B.MakePoints( thm.bv, thm.bp ); B.WriteMeta( 'B', gArgs.zb ); thm.ftc.clear(); thm.reqArea = int(gW * gH * inv_scl * inv_scl); thm.olap1D = int(gW * inv_scl * 0.5); thm.scl = 1; S.Initialize( flog, best ); S.SetRThresh( scr.stripmincorr ); S.SetNbMaxHt( 0.99 ); S.SetSweepConstXY( false ); S.SetSweepPretweak( true ); S.SetSweepNThreads( scr.stripslots ); S.SetUseCorrR( true ); S.SetNewAngProc( NewAngProc ); gA = &A; gB = &B; gS = &S; if( gArgs.abdbg ) { //S.RFromAngle( best, gArgs.abctr, thm ); //S.Pretweaks( best.R, gArgs.abctr, thm ); dbgCor = true; S.RFromAngle( best, gArgs.abctr, thm ); } else { if( scr.stripsweepspan && scr.stripsweepstep ) { S.DenovoBestAngle( best, 0, scr.stripsweepspan / 2, scr.stripsweepstep, thm, true ); } else { best.A = 0; S.PeakHunt( best, 0, thm ); } best.T.Apply_R_Part( A.Opts ); best.X += B.Opts.x - A.Opts.x; best.Y += B.Opts.y - A.Opts.y; best.T.SetXY( best.X, best.Y ); fprintf( flog, "*T: [0,1,2,3,4,5] (strip-strip)\n" ); fprintf( flog, "[%f,%f,%f,%f,%f,%f]\n", best.T.t[0], best.T.t[1], best.T.t[2], best.T.t[3], best.T.t[4], best.T.t[5] ); } t0 = StopTiming( flog, "Corr", t0 ); }
// Return true if changes made. // static bool ThisBZ( vector<BlkZ> &vZ, vector<vector<Pair> > &P, const CSuperscape &A, ThmRec &thm, int &next_isN ) { clock_t t0 = StartTiming(); CSuperscape B; CThmScan S; CorRec best; fprintf( flog, "\n--- Start B layer ----\n" ); B.SetLabel( 'B' ); next_isN = B.FindLayerIndices( next_isN ); if( gArgs.abdbg ) { while( next_isN != -1 && TS.vtil[B.is0].z != gArgs.dbgz ) next_isN = B.FindLayerIndices( next_isN ); } if( next_isN == -1 ) { fprintf( flog, "$$$ Exhausted B layers $$$\n" ); return false; } if( !B.MakeRasB( A.bb ) ) return false; B.DrawRas(); if( !B.MakePoints( thm.bv, thm.bp ) ) { fprintf( flog, "No B points for z=%d.\n", TS.vtil[B.is0].z ); return false; } B.WriteMeta(); t0 = StopTiming( flog, "MakeRasB", t0 ); thm.ftc.clear(); thm.reqArea = int(kPairMinOlap * A.ws * A.hs); thm.olap1D = 4; thm.scl = 1; int Ox = int(A.x0 - B.x0), Oy = int(A.y0 - B.y0), Rx = int((1.0 - scr.blockxyconf) * A.ws), Ry = int((1.0 - scr.blockxyconf) * A.hs); S.Initialize( flog, best ); S.SetRThresh( scr.blockmincorr ); S.SetNbMaxHt( 0.99 ); S.SetSweepConstXY( false ); S.SetSweepPretweak( true ); S.SetSweepNThreads( scr.blockslots ); S.SetUseCorrR( true ); S.SetDisc( Ox, Oy, Rx, Ry ); if( gArgs.abdbg ) { S.Pretweaks( 0, gArgs.abctr, thm ); dbgCor = true; S.RFromAngle( best, gArgs.abctr, thm ); } else { S.Pretweaks( 0, 0, thm ); if( !S.DenovoBestAngle( best, 0, scr.blocksweepspan / 2, scr.blocksweepstep, thm, false ) ) { fprintf( flog, "Low corr [%g] for z=%d.\n", best.R, TS.vtil[B.is0].z ); return false; } Point Aorigin = A.Opts; best.T.Apply_R_Part( Aorigin ); best.X += B.Opts.x - Aorigin.x; best.Y += B.Opts.y - Aorigin.y; best.T.SetXY( best.X, best.Y ); fprintf( flog, "*T: [0,1,2,3,4,5] (block-block)\n" ); fprintf( flog, "[%f,%f,%f,%f,%f,%f]\n", best.T.t[0], best.T.t[1], best.T.t[2], best.T.t[3], best.T.t[4], best.T.t[5] ); } t0 = StopTiming( flog, "Corr", t0 ); if( gArgs.abdbg ) return false; // Build: montage -> montage transform TAffine s, t; // A montage -> A block image s.NUSetScl( inv_scl ); s.AddXY( -A.x0, -A.y0 ); // A block image -> B block image t = best.T * s; // B block image -> B montage t.AddXY( B.x0, B.y0 ); s.NUSetScl( scr.crossscale ); best.T = s * t; // Append to list vZ.push_back( BlkZ( best.T, best.R, TS.vtil[B.is0].z ) ); // Accumulate pairs FindPairs( vZ, P, A, B ); return true; }