Commit af0e34b9 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

CLAUDE: renderNadirSequence(): null rim tiles with corrupt grid positions



Analysis of the -NADIR-SCENE-PXPYD[-NULLCAM] dumps (graveyard ref
1763232420_274928) showed the transformFromVirtual() refinement output is
accurate to <0.3 px in the interior, but produces garbage coordinates
(5..100 px off) in a rim band at the edge of the valid region, where the
interpolation works one-sided over NaN-filled disparity. Rendered, those
tiles put wrong content in a border strip: COLMAP fit it as fake barrel
distortion (f=1000, k1=-0.38) and image-based rotation measurements were
contaminated (apparent ~0.6x roll).

A correct scene-frame grid position is the tile center + small ERS
displacement, so tiles straying more than 4 px are nulled and render as
NaN instead of wrong content, slightly shrinking the usable FOV at the rim.

Co-authored-by: default avatarClaude <claude@elphel.com>
parent 35fd4536
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -10987,6 +10987,24 @@ java.lang.NullPointerException
    				scene_atr,                // final double []   scene_atr,
    				ref_scene,                // final QuadCLT     reference_QuadClt,
    				selected_scenes[nscene]); // final QuadCLT     scene_QuadClt
    		// Null rim tiles where transformFromVirtual()'s refinement produced garbage
    		// coordinates (one-sided interpolation over NaN-filled disparity at the edge
    		// of the valid region - errors of 5..100 px observed). A correct grid position
    		// is the tile center plus a small (<~2 px) ERS displacement, so a tile whose
    		// position strays farther than max_grid_err renders wrong content and must be
    		// skipped rather than rendered.
    		final double max_grid_err = 4.0; // px
    		{
    			int tX = ref_scene.getTilesX();
    			int tsz = ref_scene.getTileSize();
    			for (int t = 0; t < pXpYD_scene.length; t++) if (pXpYD_scene[t] != null) {
    				double ctrX = ((t % tX) + 0.5) * tsz;
    				double ctrY = ((t / tX) + 0.5) * tsz;
    				if (Math.hypot(pXpYD_scene[t][0] - ctrX, pXpYD_scene[t][1] - ctrY) > max_grid_err) {
    					pXpYD_scene[t] = null;
    				}
    			}
    		}
    		if (undistort) {
    			undistortPxPy(pXpYD_scene, selected_scenes[nscene].getErsCorrection());
    		}