Commit d15a47db authored by Andrey Filippov's avatar Andrey Filippov

Improving cuas

parent 0630471a
......@@ -168,6 +168,10 @@ public class CalibrationFileManagement {
if ((dir!=null) && (!dir.isDirectory())){
dir=dir.getParentFile();
}
if (!smart) { // 05.29.2025
return null;
}
JFileChooser fc= new JFileChooser();
......
......@@ -42,8 +42,9 @@ public class CuasCenterLma {
private double [] good_or_bad_rms = null; // just for diagnostics, to read last (failed) rms
private double [] initial_rms = null; // {rms, rms_pure}, first-calcualted rms
private double [] last_ymfx = null;
private double [][] last_jt = null;
private double [][] last_jt = null;
/*
@Deprecated
public static double [][] getCenterATR(
QuadCLT [] quadCLTs,
int ref_index,
......@@ -83,6 +84,46 @@ public class CuasCenterLma {
}
return rslt;
}
*/
public static double [][] getCenterATR(
QuadCLT [] quadCLTs,
QuadCLT ref_scene,
int [] range,
int debugLevel) {
boolean [] param_select = new boolean[PARAMETER_NAMES.length];
Arrays.fill(param_select, true);
CuasCenterLma cuasCenterLma = new CuasCenterLma(
param_select, // boolean [] param_select,
quadCLTs, // QuadCLT [] quadCLTs,
ref_scene, // QuadCLT ref_scene,
range, // int [] range,
debugLevel); // int debugLevel)
double lambda = 0.1;
double lambda_scale_good = 0.5;
double lambda_scale_bad = 8.0;
double lambda_max = 100;
double rms_diff = 0.001;
int num_iter = 20;
int lmaResult = cuasCenterLma.runLma(
lambda, // double lambda, // 0.1
lambda_scale_good,// double lambda_scale_good,// 0.5
lambda_scale_bad, // double lambda_scale_bad, // 8.0
lambda_max, // double lambda_max, // 100
rms_diff, // double rms_diff, // 0.001
num_iter, // int num_iter, // 20
debugLevel); // int debug_level)
double [][] rslt = {cuasCenterLma.getCenter(),cuasCenterLma.getRadius()};
if (debugLevel > -3) {
System.out.println("lmaResult =" +lmaResult+" iterations, RMSE ="+
cuasCenterLma.getRMS()+" ("+cuasCenterLma.getInitialRMS()+")");
System.out.println("azimuth_center = "+ rslt[0][0]);
System.out.println(" tilt_center = "+ rslt[0][1]);
System.out.println(" average roll = "+ rslt[0][2]);
System.out.println("azimuth_radius = "+ rslt[1][0]);
System.out.println(" tilt_radius = "+ rslt[1][1]);
}
return rslt;
}
public static double [][] getCenterATR(
double [][] scenes_atr,
......@@ -122,6 +163,8 @@ public class CuasCenterLma {
return rslt;
}
/*
@Deprecated
public CuasCenterLma(
boolean [] param_select,
QuadCLT [] quadCLTs,
......@@ -136,7 +179,24 @@ public class CuasCenterLma {
range, // int [] range,
debugLevel); //int debugLevel)
}
*/
public CuasCenterLma(
boolean [] param_select,
QuadCLT [] quadCLTs,
QuadCLT ref_scene,
int [] range,
int debugLevel
) {
prepareLMA(
param_select, // boolean [] param_select,
quadCLTs, // QuadCLT [] quadCLTs,
ref_scene, //int ref_index,
range, // int [] range,
debugLevel); //int debugLevel)
}
public CuasCenterLma(
boolean [] param_select,
double [][] scenes_atr,
......@@ -149,8 +209,8 @@ public class CuasCenterLma {
debugLevel); //int debugLevel)
}
/*
@Deprecated
public int prepareLMA(
boolean [] param_select,
QuadCLT [] quadCLTs,
......@@ -160,7 +220,7 @@ public class CuasCenterLma {
this.param_select = param_select;
earliest_scene = range[0];
last_scene = range[1];
int num_scenes = last_scene- earliest_scene + 1;
// int num_scenes = last_scene- earliest_scene + 1;
ErsCorrection ers_reference = quadCLTs[ref_index].getErsCorrection();
double [][] scenes_atr = new double [quadCLTs.length][];
scenes_atr[ref_index] = new double[3]; // all zeros
......@@ -180,6 +240,37 @@ public class CuasCenterLma {
new int [] {earliest_scene,last_scene}, // int [] range,
debugLevel); // int debugLevel);
}
*/
public int prepareLMA(
boolean [] param_select,
QuadCLT [] quadCLTs,
QuadCLT ref_scene,
int [] range,
int debugLevel) {
this.param_select = param_select;
earliest_scene = range[0];
last_scene = range[1];
// int num_scenes = last_scene- earliest_scene + 1;
ErsCorrection ers_reference = ref_scene.getErsCorrection();
double [][] scenes_atr = new double [quadCLTs.length][];
// scenes_atr[ref_index] = new double[3]; // all zeros should not be needed, it should be in ers_reference.getSceneATR(ts) for "normal scenes
for (int nscene = last_scene; nscene >= earliest_scene; nscene--) {
// just checking it is not isolated
if (quadCLTs[nscene] == null) {
earliest_scene = nscene + 1;
break;
}
// now reference scene should also be in ers_reference.getSceneXYZ(ts)
String ts = quadCLTs[nscene].getImageName();
scenes_atr[nscene] = ers_reference.getSceneATR(ts);
}
return prepareLMA(
param_select, // boolean [] param_select,
scenes_atr, // double [][] scenes_atr,
new int [] {earliest_scene,last_scene}, // int [] range,
debugLevel); // int debugLevel);
}
public int prepareLMA(
boolean [] param_select,
......
......@@ -1132,6 +1132,16 @@ public class GpuQuad{ // quad camera description
int tilesY = wh[1] / GPUTileProcessor.DTT_SIZE;
return tilesY*tilesX*num_colors* 4 * GPUTileProcessor.DTT_SIZE * GPUTileProcessor.DTT_SIZE;
}
public int getNumTiles(boolean use_ref) {
int [] wh = use_ref ? gpu_clt_ref_wh : gpu_clt_wh;
int tilesX = wh[0] / GPUTileProcessor.DTT_SIZE;
int tilesY = wh[1] / GPUTileProcessor.DTT_SIZE;
return tilesY*tilesX; // *num_colors* 4 * GPUTileProcessor.DTT_SIZE * GPUTileProcessor.DTT_SIZE;
}
public int getCltTileLength() { // per camera, in floats
return num_colors * 4 * GPUTileProcessor.DTT_SIZE * GPUTileProcessor.DTT_SIZE;
}
/*
public int getCltLength(boolean use_ref) {
int [] wh = use_ref ? gpu_clt_ref_wh : gpu_clt_wh;
......
......@@ -1859,7 +1859,7 @@ public class Interscene {
public static double [][] getXyzatrImsCenter(
public static double [][] getXyzatrImsCenter( // Not used
final CLTParameters clt_parameters,
final boolean compensate_ims_rotation,
final boolean inertial_only,
......
......@@ -654,8 +654,10 @@ min_str_neib_fpn 0.35
public double mb_tau = 0.008; // time constant, sec
public double mb_max_gain = 5.0; // motion blur maximal gain (if more - move second point more than a pixel
public double mb_max_gain_inter = 2.0; // same for interscene correlation for pose adjustment
//CUAS mode
public int cuas_discard_border = 8; // Discard this number of pixels from each side when merging
public double cuas_max_fold = 50;
public int cuas_min_in_row_col = 4; // Minimal number of defined tiles in a row/column
// TODO: move next parameters elsewhere - they are not the motion blur ones.
public int mb_gain_index_pose = 5; // pose readjust pass to switch to full mb_max_gain from mb_max_gain_inter
public int mb_gain_index_depth = 5; // depth map refine pass (SfM) to switch to full mb_max_gain from mb_max_gain_inter
......@@ -1963,6 +1965,13 @@ min_str_neib_fpn 0.35
"Maximal gain for motion blur correction (if needed more for 1 pixel, increase offset). Will be forced fro the last adjustment");
gd.addNumericField("Maximal gain pose", this.mb_max_gain_inter, 5,7,"x",
"Maximal gain for motion blur correction during interscene correlation. Will be used for all but the last adjustment.");
gd.addTab("CUAS","CUAS Parameters");
gd.addNumericField("Discard margins", this.cuas_discard_border, 0,3,"pix",
"Discards this number of pixels from each side when merging images.");
gd.addNumericField("Maximal X,Y fold", this.cuas_max_fold, 5,7,"pix",
"Maximal non-monotonic Px, Py in PxPyD (usually near image edges).");
gd.addNumericField("Minimal tiles in a row/column", this.cuas_min_in_row_col, 0,3,"tiles",
"Discards rows then columns that have less defined tiles (noticed in a diagonal after folds removal).");
gd.addTab("LMA sequence","Interscene LMA sequence control");
gd.addMessage("Parameters for control of the LMA pose adjustment sequence");
gd.addNumericField("Pose readjust number for full mb_gain", this.mb_gain_index_pose, 0,3,"",
......@@ -2845,6 +2854,11 @@ min_str_neib_fpn 0.35
this.mb_tau = gd.getNextNumber();
this.mb_max_gain = gd.getNextNumber();
this.mb_max_gain_inter = gd.getNextNumber();
this.cuas_discard_border= (int) gd.getNextNumber();
this.cuas_max_fold = gd.getNextNumber();
this.cuas_min_in_row_col= (int) gd.getNextNumber();
this.mb_gain_index_pose = (int) gd.getNextNumber();
this.mb_gain_index_depth =(int) gd.getNextNumber();
......@@ -3659,6 +3673,10 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"mb_max_gain", this.mb_max_gain+""); // double
properties.setProperty(prefix+"mb_max_gain_inter", this.mb_max_gain_inter+""); // double
properties.setProperty(prefix+"cuas_discard_border", this.cuas_discard_border+""); // int
properties.setProperty(prefix+"cuas_max_fold", this.cuas_max_fold+""); // double
properties.setProperty(prefix+"cuas_min_in_row_col", this.cuas_min_in_row_col+""); // int
properties.setProperty(prefix+"mb_gain_index_pose", this.mb_gain_index_pose+""); // int
properties.setProperty(prefix+"mb_gain_index_depth", this.mb_gain_index_depth+""); // int
......@@ -4448,6 +4466,10 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"mb_max_gain")!=null) this.mb_max_gain=Double.parseDouble(properties.getProperty(prefix+"mb_max_gain"));
if (properties.getProperty(prefix+"mb_max_gain_inter")!=null) this.mb_max_gain_inter=Double.parseDouble(properties.getProperty(prefix+"mb_max_gain_inter"));
if (properties.getProperty(prefix+"cuas_discard_border")!=null) this.cuas_discard_border=Integer.parseInt(properties.getProperty(prefix+"cuas_discard_border"));
if (properties.getProperty(prefix+"cuas_max_fold")!=null) this.cuas_max_fold=Double.parseDouble(properties.getProperty(prefix+"cuas_max_fold"));
if (properties.getProperty(prefix+"cuas_min_in_row_col")!=null) this.cuas_min_in_row_col=Integer.parseInt(properties.getProperty(prefix+"cuas_min_in_row_col"));
if (properties.getProperty(prefix+"mb_gain_index_pose")!=null) this.mb_gain_index_pose=Integer.parseInt(properties.getProperty(prefix+"mb_gain_index_pose"));
if (properties.getProperty(prefix+"mb_gain_index_depth")!=null) this.mb_gain_index_depth=Integer.parseInt(properties.getProperty(prefix+"mb_gain_index_depth"));
......@@ -5239,6 +5261,10 @@ min_str_neib_fpn 0.35
imp.mb_max_gain = this.mb_max_gain;
imp.mb_max_gain_inter = this.mb_max_gain_inter;
imp.cuas_discard_border = this.cuas_discard_border;
imp.cuas_max_fold = this.cuas_max_fold;
imp.cuas_min_in_row_col = this.cuas_min_in_row_col;
imp.mb_gain_index_pose = this.mb_gain_index_pose;
imp.mb_gain_index_depth = this.mb_gain_index_depth;
......
......@@ -5786,16 +5786,15 @@ public class OpticalFlow {
double [] cuas_atr = ZERO3;
if (extract_center_orientation && clt_parameters.imp.lock_position) {
center_ATR = CuasCenterLma.getCenterATR(
quadCLTs, // QuadCLT [] quadCLTs,
ref_index, //int ref_index,
new int [] {earliest_scene, last_index}, //int [] range,
quadCLTs, // QuadCLT [] quadCLTs,
quadCLTs[ref_index], // QuadCLT ref_scene,ref_index, //int ref_index,
new int [] {earliest_scene, last_index}, // int [] range,
debugLevel); // int debugLevel);
// cuas_atr = new double [] {-center_ATR[0][0],-center_ATR[0][1],-center_ATR[0][2]};
cuas_atr = new double [] { center_ATR[0][0], center_ATR[0][1], center_ATR[0][2]};
}
boolean combine_clt = clt_parameters.imp.cuas_rotation; // (cuas_atr[0] != 0) || (cuas_atr[1] != 0) || (cuas_atr[2] != 0);
// TODO: Refine center_CLT if it exists, not crete
// TODO: Refine center_CLT if it exists, not create
if (combine_clt) {
......@@ -5810,10 +5809,11 @@ public class OpticalFlow {
if (combo_dsn_final == null) {
combo_dsn_final =quadCLTs[ref_index].restoreComboDSI(true); // also sets quadCLTs[ref_index].dsi and blue sky
}
center_CLT = Cuas.createCenterClt( // assuming cuas_rotation is true
clt_parameters, // CLTParameters clt_parameters,
quadCLTs, // QuadCLT [] quadCLTs,
ref_index, // int ref_index,
quadCLTs[ref_index], // QuadCLT ref_scene, // where combo_dsi is
null, // int [] range, // or null
combo_dsn_final, // double [][] ref_dsi, // DSI data for the reference scene (or null to read it from file)
condition_dsi, // boolean condition_dsi,
......@@ -5828,38 +5828,16 @@ public class OpticalFlow {
}
}
// just for verification
boolean apply_clt = true;
boolean show_clt = true;
int [] whc = new int[3];
if (apply_clt) { // set GPU with data
center_CLT.setQuadClt(); //2025 mark that GPU is used for center_CLT
// quadCLTs[ref_index].setComboToTD(
center_CLT.setComboToTD(
null, // new float [][] {center_CLT.getCenterClt()}, // ,combo_seq_clt, // final float [][] fclt,
true, // merge_clt, // final boolean merge_channels, // duplicate same data to all selected channels
sensor_mask_clt, // final int sensor_mask, // only if merge_channels
whc, // final int [] whc, // if int[2], will return width, height
false); // final boolean use_reference);
if (show_clt) {
String suffix="-virtual";
// ImagePlus imp_virtual = ref_clt.renderFromTD ( // do we need to update gpuQuad ?
ImagePlus imp_virtual = center_CLT.renderFromTD ( // do we need to update gpuQuad ?
sensor_mask_clt, // final int sensor_mask,
true, // merge_clt, // boolean merge_channels,
clt_parameters, // CLTParameters clt_parameters,
// clt_parameters.getColorProcParameters(ref_clt.isAux()), //ColorProcParameters colorProcParameters,
clt_parameters.getColorProcParameters(center_CLT.isAux()), //ColorProcParameters colorProcParameters,
clt_parameters.getRGBParameters(), //EyesisCorrectionParameters.RGBParameters rgbParameters,\
whc, // null, // int [] wh,
false, // toRGB, // boolean toRGB,
false, // use_reference, // boolean use_reference
suffix); // String suffix)
imp_virtual.show();
}
boolean show_clt = false;// true;
if (show_clt) {
center_CLT.showCenterClt(
clt_parameters); // CLTParameters clt_parameters,
center_CLT.showCenterCltWeights(
clt_parameters); // CLTParameters clt_parameters,
}
}
if (generate_egomotion) {
boolean ego_show = !clt_parameters.batch_run; //true;
String ego_path = quadCLTs[ref_index].getX3dDirectory()+Prefs.getFileSeparator()+
......
......@@ -212,8 +212,9 @@ public class QuadCLTCPU {
// combined clt for center view, only used in cuas mode
public float [] center_clt = null; // clt data (single accumulated channel)
public int [] center_clt_num = null; // same size as combo_clt - number of accumulated scenes for this point
public int center_clt_width = 0; // image width to save combo_clt (and combo_clt_num) as image
/// public int [] center_clt_num = null; // same size as combo_clt - number of accumulated scenes for this point
public float [] center_clt_weights= null; // 1/64 of center_clt (tilesX*tilesY)
/// public int center_clt_width = 0; // image width to save combo_clt (and combo_clt_num) as image
public boolean isPhotometricUpdated() {
......@@ -238,9 +239,10 @@ public class QuadCLTCPU {
}
public boolean hasCenterClt() {
return (center_clt != null) && (center_clt_num != null) && (center_clt_width != 0);
return (center_clt != null) && (center_clt_weights != null);
}
/*
public void setCenterClt(
float [] clt,
int [] clt_num,
......@@ -249,17 +251,31 @@ public class QuadCLTCPU {
center_clt_num = clt_num;
center_clt_width = clt_width;
}
*/
public void setCenterClt(
float [] clt,
float [] clt_weights) {
center_clt = clt;
center_clt_weights = clt_weights;
}
public float [] getCenterClt() {
return center_clt;
}
public float [] getCenterCltWeights() {
return center_clt_weights;
}
/*
public int [] getCenterCltNum() {
return center_clt_num;
}
public int [] getCenterCltWH() {
return new int [] {center_clt_width, center_clt.length / center_clt_width};
}
public boolean saveCenterClt() {
public boolean saveCenterClt_old() {
if (!hasCenterClt()) {
System.out.println("saveCenterCli(): center CLT data is not set");
return false;
......@@ -278,12 +294,15 @@ public class QuadCLTCPU {
getCenterCltWH()[1]); // int height)
return true;
}
*/
public static String getCenterDirName(String ref_name) {
return ref_name + CENTER_DIR_SUFFIX;
}
public static QuadCLT restoreCenterClt(QuadCLT ref_clt) {
/*
public static QuadCLT restoreCenterClt_old(QuadCLT ref_clt) {
String center_name = QuadCLT.getCenterDirName(ref_clt.getImageName());
String ref_dir_path = ref_clt.getX3dDirectory(center_name);
File cdir = new File(ref_dir_path);
......@@ -312,20 +331,49 @@ public class QuadCLTCPU {
num, // int [] clt_num,
wh[0]); // int clt_width);
}
// TwoQuadCLT.DSI_COMBO_SUFFIX
/*
center_CLT.restoreDSI(
TwoQuadCLT.DSI_COMBO_SUFFIX, // String suffix,
true); // boolean silent)
*/
center_CLT.restoreComboDSI(true);
return center_CLT;
}
*/
public static QuadCLT restoreCenterClt(QuadCLT ref_clt) {
String center_name = QuadCLT.getCenterDirName(ref_clt.getImageName());
String ref_dir_path = ref_clt.readX3dDirectory(center_name);
if (ref_dir_path == null) {
System.out.println("restoreCenterClt(): directory does not exist: "+ref_dir_path);
return null;
}
File cdir = new File(ref_dir_path);
if (!cdir.exists() || !cdir.isDirectory()) {
System.out.println("restoreCenterClt(): directory does not exist: "+ref_dir_path);
return null;
}
QuadCLT center_CLT = new QuadCLT(ref_clt, center_name);
center_CLT.setImagePath(cdir.getPath());
int [] wh = new int[2];
float [][] fclt_w = center_CLT.readFloatArrayFromModelDirectory(
CENTER_CLT_SUFFIX, // String suffix,
0, // int num_slices, // (0 - all)
wh); // int [] wh)
if (fclt_w != null) {
if (fclt_w.length != 1) {
System.out.println("restoreCenterClt(): expected a single-slice data, got "+fclt_w.length+" slices.");
return null;
}
int fclt_tile_length = center_CLT.getCltTileLength();
float [] center_clt_weights = new float [fclt_w[0].length/(fclt_tile_length + 1)];
float [] center_clt = new float [fclt_w[0].length/(fclt_tile_length + 1) * fclt_tile_length];
System.arraycopy(fclt_w[0], 0, center_clt, 0, center_clt.length);
System.arraycopy(fclt_w[0], center_clt.length, center_clt_weights, 0, center_clt_weights.length);
center_CLT.setCenterClt(
center_clt, // float [] clt,
center_clt_weights); // int clt_width);
}
center_CLT.restoreComboDSI(true);
return center_CLT;
}
public String getReferenceTimestamp() {
return timestamp_reference;
}
......@@ -2848,6 +2896,25 @@ public class QuadCLTCPU {
public TileProcessor getTileProcessor() {
return tp;
}
/*
public int getTileLength() {
return tp.getTileSize()*tp.getTileSize();
}
public int getCltTileLength() {
return 4*tp.getTileSize()*tp.getTileSize();
}
*/
public int getTileSize() {
return tp.getTileSize();
}
public int getTilesX() {
return tp.getTilesX();
}
public int getTilesY() {
return tp.getTilesY();
}
public int getNumSensors() {
if (geometryCorrection == null) {
System.out.println("*** BUG! geometryCorrection is not set, number of sensors is unknown! Will use 4 sensors ****");
......@@ -3050,6 +3117,14 @@ public class QuadCLTCPU {
true); //newAllowed, // save
return x3d_path;
}
public String readX3dDirectory(String name) { // replace direct calculations
String x3d_path = correctionsParameters.selectX3dDirectory( // for x3d and obj
name, // quad timestamp. Will be ignored if correctionsParameters.use_x3d_subdirs is false
correctionsParameters.x3dModelVersion,
false, // smart,
false); //newAllowed, // save
return x3d_path;
}
/**
* Discriminate "blue sky" areas with no details at infinity. Such areas
......@@ -11848,6 +11923,37 @@ public class QuadCLTCPU {
}
}
public ImagePlus show_pXpYD(
double [][] pXpYD,
String suffix,
boolean show) {
if (suffix == null) {
suffix = "";
}
String [] titles = {"pX","pY","Disparity"};
double [][] dbg_img = new double [titles.length][pXpYD.length];
for (int i = 0; i < dbg_img.length; i++) {
Arrays.fill(dbg_img[i], Double.NaN);
}
for (int nTile = 0; nTile < pXpYD.length; nTile++){
if (pXpYD[nTile] != null) {
for (int i = 0; i < pXpYD[nTile].length; i++) {
dbg_img[i][nTile] = pXpYD[nTile][i];
}
}
}
ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
dbg_img,
getTilesX(), // int width,
getTilesY(), // int height,
getImageName()+"-pXpYD"+suffix,
titles);
if (show) {
imp.show();
}
return imp;
}
public static void showPimuOffsets(CLTParameters clt_parameters) {
showPimuOffsets( clt_parameters.imp.get_pimu_offs());
}
......
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