Commit d23011b4 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: CuasPoseRT: save -POSE-RT-RELIABLE mask + -POSE-RT-HYPER measurement stack

Per Andrey: characterize the per-scene measurement, incl. the eigenvector data.
-POSE-RT-HYPER (80x64, z=scenes, t=components, make_hyper layout): dx, dy,
strength, dxy=|dx,dy| from vector_XYS; sqrt_l0, sqrt_l1 (peak-ellipse half-axes,
pix), elong=sqrt(l1/l0) (linear-feature indicator), eig0_ang (precise-axis
direction, [0,PI)) from coord_motion eigen {eig_x,eig_y,l0,l1} - NaN unless
imp.eig_use. Data = last LMA cycle's coord_motion via the existing
coord_motion_rslt out-param. -POSE-RT-RELIABLE = tile selection mask.

Verified with standalone javac against target/classes (Eyesis live - no mvn;
Eclipse rebuilds on restart).
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 472435db
...@@ -26,6 +26,8 @@ package com.elphel.imagej.cuas.rt; ...@@ -26,6 +26,8 @@ package com.elphel.imagej.cuas.rt;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.gpu.TpTask;
...@@ -36,7 +38,10 @@ import com.elphel.imagej.tileprocessor.QuadCLT; ...@@ -36,7 +38,10 @@ import com.elphel.imagej.tileprocessor.QuadCLT;
import com.elphel.imagej.tileprocessor.QuadCLTCPU; import com.elphel.imagej.tileprocessor.QuadCLTCPU;
import com.elphel.imagej.tileprocessor.TwoQuadCLT; import com.elphel.imagej.tileprocessor.TwoQuadCLT;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs; import ij.Prefs;
import ij.process.FloatProcessor;
/** /**
* Phase A of the RT pose-adjustment package (design: ANDREY_CONTINUE 2026-07-03, * Phase A of the RT pose-adjustment package (design: ANDREY_CONTINUE 2026-07-03,
...@@ -71,6 +76,15 @@ import ij.Prefs; ...@@ -71,6 +76,15 @@ import ij.Prefs;
*/ */
public class CuasPoseRT { public class CuasPoseRT {
public static final double [] ZERO3 = {0.0, 0.0, 0.0}; public static final double [] ZERO3 = {0.0, 0.0, 0.0};
// Per-scene measurement characterization slices of the -POSE-RT-HYPER stack
// (z = scenes, t = components, matching the renderSceneSequence make_hyper convention).
// dx,dy,strength from coord_motion[1] (vector_XYS); the eigen four from coord_motion[2]
// {eig_x,eig_y,l0,l1} (filled when imp.eig_use is on; NaN otherwise): sqrt_l0/sqrt_l1 =
// correlation-peak ellipse half-axes (pix), elong = sqrt(l1/l0) (large = linear feature,
// e.g. straight horizon: precise only perpendicular), eig0_ang = direction of the
// precise axis (eigenvector of the smaller eigenvalue), radians [0,PI).
public static final String [] HYPER_COMPONENTS =
{"dx", "dy", "strength", "dxy", "sqrt_l0", "sqrt_l1", "elong", "eig0_ang"};
/** /**
* Re-generate per-scene poses against the virtual-center reference, RT-style. * Re-generate per-scene poses against the virtual-center reference, RT-style.
...@@ -179,6 +193,15 @@ public class CuasPoseRT { ...@@ -179,6 +193,15 @@ public class CuasPoseRT {
} }
// ---- Ascending per-scene loop (the RT iterator) ---- // ---- Ascending per-scene loop (the RT iterator) ----
final int tilesX = center_CLT.getTilesX();
final int tilesY = center_CLT.getTilesY();
final int num_pix = tilesX * tilesY;
final ArrayList<float [][]> hyper_scenes = new ArrayList<float [][]>(); // per used scene: [component][tile]
final ArrayList<String> hyper_ts = new ArrayList<String>();
if (!clt_parameters.imp.eig_use && (debugLevel > -4)) {
System.out.println("CuasPoseRT.testPoseSequence(): imp.eig_use is OFF - the 4 eigen slices of "+
"-POSE-RT-HYPER (sqrt_l0, sqrt_l1, elong, eig0_ang) will be all NaN");
}
final double [][][] fitted = new double [quadCLTs.length][][]; final double [][][] fitted = new double [quadCLTs.length][][];
final int [] fail_reason = new int [1]; final int [] fail_reason = new int [1];
final StringBuffer sb = new StringBuffer(); final StringBuffer sb = new StringBuffer();
...@@ -206,6 +229,7 @@ public class CuasPoseRT { ...@@ -206,6 +229,7 @@ public class CuasPoseRT {
quadCLTs[nscene].getErsCorrection().setErsDt( quadCLTs[nscene].getErsCorrection().setErsDt(
QuadCLTCPU.scaleDtToErs(clt_parameters, dxyzatr_dt)); QuadCLTCPU.scaleDtToErs(clt_parameters, dxyzatr_dt));
fail_reason[0] = 0; fail_reason[0] = 0;
final double [][][] coord_motion_rslt = new double [3][][]; // [centers, vector_XYS, eigen] of the last LMA cycle
double [][] pose = Interscene.adjustPairsLMAInterscene( double [][] pose = Interscene.adjustPairsLMAInterscene(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
true, // boolean initial_adjust, true, // boolean initial_adjust,
...@@ -232,7 +256,7 @@ public class CuasPoseRT { ...@@ -232,7 +256,7 @@ public class CuasPoseRT {
mb_tau, // double mb_tau, mb_tau, // double mb_tau,
mb_max_gain, // double mb_max_gain, mb_max_gain, // double mb_max_gain,
null, // double [][] mb_vectors (MB off in phase A), null, // double [][] mb_vectors (MB off in phase A),
null, // double [][][] coord_motion_rslt, coord_motion_rslt, // double [][][] coord_motion_rslt (last-cycle measurement, for -POSE-RT-HYPER),
debugLevel - 2); // int debug_level debugLevel - 2); // int debug_level
final boolean ok = (pose != null); final boolean ok = (pose != null);
if (ok) { if (ok) {
...@@ -247,6 +271,34 @@ public class CuasPoseRT { ...@@ -247,6 +271,34 @@ public class CuasPoseRT {
fail_reason[0]+" ("+Interscene.getFailReason(fail_reason[0])+"), coasting prediction"); fail_reason[0]+" ("+Interscene.getFailReason(fail_reason[0])+"), coasting prediction");
} }
} }
// Collect measurement characterization slices for -POSE-RT-HYPER
{
final float [][] comps = new float [HYPER_COMPONENTS.length][num_pix];
for (float [] c : comps) Arrays.fill(c, Float.NaN);
final double [][] vxys = coord_motion_rslt[1]; // {dx,dy,strength} per tile or null
final double [][] eig = (coord_motion_rslt.length > 2) ? coord_motion_rslt[2] : null;
if (vxys != null) {
for (int i = 0; i < num_pix; i++) {
if (vxys[i] != null) {
comps[0][i] = (float) vxys[i][0];
comps[1][i] = (float) vxys[i][1];
comps[2][i] = (float) vxys[i][2];
comps[3][i] = (float) Math.sqrt(vxys[i][0]*vxys[i][0] + vxys[i][1]*vxys[i][1]);
}
if ((eig != null) && (eig[i] != null)) { // {eig_x, eig_y, l0, l1}, l0 <= l1
final double l0 = eig[i][2], l1 = eig[i][3];
comps[4][i] = (float) Math.sqrt(l0);
comps[5][i] = (float) Math.sqrt(l1);
comps[6][i] = (l0 > 0) ? (float) Math.sqrt(l1/l0) : Float.NaN;
double ang = Math.atan2(eig[i][1], eig[i][0]); // precise-axis direction
if (ang < 0) ang += Math.PI; // fold to [0, PI)
comps[7][i] = (float) ang;
}
}
}
hyper_scenes.add(comps);
hyper_ts.add(ts_name);
}
// CSV row + comparison stats // CSV row + comparison stats
final double [] st = (stored[nscene] != null) ? stored[nscene][1] : null; final double [] st = (stored[nscene] != null) ? stored[nscene][1] : null;
sb.append(nscene+", "+ts_name); sb.append(nscene+", "+ts_name);
...@@ -279,6 +331,29 @@ public class CuasPoseRT { ...@@ -279,6 +331,29 @@ public class CuasPoseRT {
} catch (IOException e) { } catch (IOException e) {
System.out.println("CuasPoseRT.testPoseSequence(): FAILED to save "+csv_path+": "+e.getMessage()); System.out.println("CuasPoseRT.testPoseSequence(): FAILED to save "+csv_path+": "+e.getMessage());
} }
// reliable_tiles selection mask (1=selected), same grid as the DSI
{
final float [] frel = new float [num_pix];
for (int i = 0; i < num_pix; i++) frel[i] = reliable_ref[i] ? 1.0f : 0.0f;
final ImagePlus imp_rel = new ImagePlus(center_CLT.getImageName()+"-POSE-RT-RELIABLE",
new FloatProcessor(tilesX, tilesY, frel));
center_CLT.saveImagePlusInModelDirectory(null, imp_rel); // title as filename
}
// -POSE-RT-HYPER: z = scenes (top slider), t = components (bottom slider) -
// same layout as renderSceneSequence make_hyper (component is the outer slice order)
if (!hyper_scenes.isEmpty()) {
final ImageStack stack_hyper = new ImageStack(tilesX, tilesY);
for (int nc = 0; nc < HYPER_COMPONENTS.length; nc++) {
for (int ns = 0; ns < hyper_scenes.size(); ns++) {
stack_hyper.addSlice(HYPER_COMPONENTS[nc]+":"+hyper_ts.get(ns), hyper_scenes.get(ns)[nc]);
}
}
final ImagePlus imp_hyper = new ImagePlus(center_CLT.getImageName()+"-POSE-RT-HYPER", stack_hyper);
imp_hyper.setDimensions(1, hyper_scenes.size(), HYPER_COMPONENTS.length);
imp_hyper.setOpenAsHyperStack(true);
imp_hyper.getProcessor().resetMinAndMax();
center_CLT.saveImagePlusInModelDirectory(null, imp_hyper); // title as filename
}
System.out.println("CuasPoseRT.testPoseSequence(): scenes OK="+num_ok+", failed(coasted)="+num_fail+ System.out.println("CuasPoseRT.testPoseSequence(): scenes OK="+num_ok+", failed(coasted)="+num_fail+
", compared="+num_cmp); ", compared="+num_cmp);
if (num_cmp > 0) { if (num_cmp > 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment