Commit c911c2a7 authored by Andrey Filippov's avatar Andrey Filippov

Implementing scene-sequence (several segments) functionality

parent c999976d
...@@ -30,6 +30,7 @@ import java.util.Arrays; ...@@ -30,6 +30,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import org.apache.commons.math3.complex.Quaternion; import org.apache.commons.math3.complex.Quaternion;
...@@ -420,7 +421,39 @@ public class ErsCorrection extends GeometryCorrection { ...@@ -420,7 +421,39 @@ public class ErsCorrection extends GeometryCorrection {
scenes_poses.remove(timestamp); scenes_poses.remove(timestamp);
} }
public String [] getScenes() { // provide first/last scenes to avoid stale values
public String [] getScenes(
String first,
String last)
{
HashSet<String> names_set = new HashSet<String>(scenes_poses.size());
for (String ts:scenes_poses.keySet()) {
if ((first.compareTo(ts)<=0) && (last.compareTo(ts)>=0)) {
names_set.add(ts);
}
}
String [] scenes = names_set.toArray(new String [0]);
Arrays.sort(scenes);
return scenes;
}
public boolean refreshScenes(
String first,
String last)
{
boolean modified = false;
for (String ts:scenes_poses.keySet()) {
if ((first.compareTo(ts) > 0) || (last.compareTo(ts) < 0)) {
scenes_poses.remove(ts);
modified=true;
}
}
return modified;
}
public String [] getScenes() { // can provide stale values
int num_scenes = scenes_poses.size(); int num_scenes = scenes_poses.size();
String [] scenes = new String[num_scenes]; String [] scenes = new String[num_scenes];
int i = 0; int i = 0;
......
...@@ -28,6 +28,7 @@ package com.elphel.imagej.tileprocessor; ...@@ -28,6 +28,7 @@ package com.elphel.imagej.tileprocessor;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
...@@ -35,6 +36,8 @@ import java.nio.ByteBuffer; ...@@ -35,6 +36,8 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.Properties; import java.util.Properties;
//import java.util.Random; //import java.util.Random;
...@@ -6111,6 +6114,46 @@ if (debugLevel < -100) { ...@@ -6111,6 +6114,46 @@ if (debugLevel < -100) {
getGPU().resetBayer(); getGPU().resetBayer();
} }
} }
public QuadCLT spawnQuadCLT(
String scene_name,
CLTParameters clt_parameters,
int debugLevel)
{
QuadCLT quadCLT = new QuadCLT(this, scene_name); //null
if (correctionsParameters == null) {
if (debugLevel > -3) System.out.println("spawnQuadCLT(): this.correctionsParameters==null");
return null;
}
if ((correctionsParameters.x3dDirectory == null) || (correctionsParameters.x3dDirectory.length()==0)){
if (debugLevel > -3) System.out.println("spawnQuadCLT(): this.correctionsParameters.x3dDirectory==null");
return null;
}
if ((correctionsParameters.x3dModelVersion == null) || (correctionsParameters.x3dModelVersion.length()==0)){
if (debugLevel > -3) System.out.println("spawnQuadCLT(): this.correctionsParameters.x3dModelVersion==null");
return null;
}
// model/version absolute path
Path x3d_path=Paths.get(correctionsParameters.x3dDirectory).resolve(scene_name).resolve(correctionsParameters.x3dModelVersion);
Path interframe_path = x3d_path.resolve(scene_name+INTERFRAME_SUFFIX+CONFIGURATION_EXTENSION);
File interframe_file = new File(interframe_path.toString());
if (!interframe_file.exists()) {
if (debugLevel > -3) System.out.println("spawnQuadCLT(): "+interframe_path.toString()+" does not exist");
return null;
}
// read all parameters? from //fish://elphel@192.168.0.137/home/elphel/lwir16-proc/NC/linked/linked_1763232117-1763234145-v88/1763232148_284331-index/v88/1763232148_284331-SETTINGS.corr-xml
// read interscene parameters and <entry key="EYESIS_DCT_AUX.refscenes_1763232144_433048"></entry>
quadCLT.restoreInterProperties( // restore properties for interscene processing (extrinsics, ers, ...)
interframe_file.toString(), // path, // full name with extension or null to use x3d directory
false, // boolean all_properties,
debugLevel); // int debugLevel)
quadCLT.isPhotometricUpdatedAndReset(); // reset changed 12/25/2025
// get directory with version from name and this
// read existing parameters and inter-intra
// all data should exist, inter-intra and ims
return quadCLT;
}
public QuadCLT spawnQuadCLT( public QuadCLT spawnQuadCLT(
String set_name, String set_name,
......
...@@ -6077,11 +6077,8 @@ LogTee.clearSceneLog(); // stop per‑scene logging ...@@ -6077,11 +6077,8 @@ LogTee.clearSceneLog(); // stop per‑scene logging
if (clt_parameters.imp.ims_use) { if (clt_parameters.imp.ims_use) {
restoreIms( restoreIms(
clt_parameters, // // CLTParameters clt_parameters, clt_parameters, // // CLTParameters clt_parameters,
// clt_parameters.imp.ims_offset, // double ims_offset,
// clt_parameters.imp.gmt_plus, // double gmt_plus,
null, // String ims_path, null, // String ims_path,
true, // boolean create, true, // boolean create,
// false, // boolean rebuild,
debugLevelInner); // int debugLevel); debugLevelInner); // int debugLevel);
} }
return this; // can only be QuadCLT instance return this; // can only be QuadCLT instance
...@@ -6148,11 +6145,8 @@ LogTee.clearSceneLog(); // stop per‑scene logging ...@@ -6148,11 +6145,8 @@ LogTee.clearSceneLog(); // stop per‑scene logging
if (clt_parameters.imp.ims_use) { if (clt_parameters.imp.ims_use) {
restoreIms( restoreIms(
clt_parameters, // // CLTParameters clt_parameters, clt_parameters, // // CLTParameters clt_parameters,
// clt_parameters.imp.ims_offset, // double ims_offset,
// clt_parameters.imp.gmt_plus, // double gmt_plus,
null, // String ims_path, null, // String ims_path,
true, // boolean create, true, // boolean create,
// false, // boolean rebuild,
debugLevelInner); // int debugLevel); debugLevelInner); // int debugLevel);
} }
return this; // can only be QuadCLT instance return this; // can only be QuadCLT instance
...@@ -6326,8 +6320,6 @@ LogTee.clearSceneLog(); // stop per‑scene logging ...@@ -6326,8 +6320,6 @@ LogTee.clearSceneLog(); // stop per‑scene logging
*/ */
public boolean restoreIms( public boolean restoreIms(
CLTParameters clt_parameters, CLTParameters clt_parameters,
// double ims_offset,
// double gmt_plus,
String ims_path, String ims_path,
boolean create, boolean create,
//boolean rebuild, //boolean rebuild,
...@@ -6392,8 +6384,6 @@ LogTee.clearSceneLog(); // stop per‑scene logging ...@@ -6392,8 +6384,6 @@ LogTee.clearSceneLog(); // stop per‑scene logging
} }
saveIms( saveIms(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
// ims_offset,
// gmt_plus,
ims_path, ims_path,
debugLevel); debugLevel);
} }
......
package com.elphel.imagej.tileprocessor;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.ims.Did_ins_2;
import com.elphel.imagej.ims.Imx5;
public class SeriesInfinityCorrection {
public static double getInfinityMuliSeries(
CLTParameters clt_parameters,
QuadCLT [] refCLTs,
QuadCLT index_CLT, // normally - just the last in quadCLTs
final int debugLevel) {
for (QuadCLT ref_scene:refCLTs) {
ref_scene.restoreAnyDSI(debugLevel);
}
// get all scenes used in at least one segment.
HashSet<String> scene_set = new HashSet<String>();
for (QuadCLT ref_scene:refCLTs) {
ErsCorrection ers_reference = ref_scene.getErsCorrection();
String [] names = ers_reference.getScenes();
for (String s:names)scene_set.add(s);
}
String [] all_scene_names = scene_set.toArray(new String[0]);
Arrays.sort(all_scene_names);
HashMap<String,QuadCLT> scene_map = new HashMap<String,QuadCLT>();
String models_dir = index_CLT.correctionsParameters.x3dDirectory;
final String suffix = index_CLT.correctionsParameters.imsSuffix; // assuming common for all
final QuadCLT[] scenes = new QuadCLT[all_scene_names.length];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int iScene = ai.getAndIncrement(); iScene < scenes.length; iScene = ai.getAndIncrement()) {
QuadCLT scene = new QuadCLT(index_CLT, all_scene_names[iScene]);
Path ims_path = Paths.get(models_dir).resolve(all_scene_names[iScene]).resolve(all_scene_names[iScene]+suffix);
scene.restoreIms(
clt_parameters, // // CLTParameters clt_parameters,
ims_path.toString(), // String ims_path,
true, // boolean create,
debugLevel-1); // debugLevelInner); // int debugLevel);
scenes[iScene] = scene;
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int nscene = 0; nscene < all_scene_names.length; nscene++) { // scene_name:all_scene_names) {
scene_map.put(all_scene_names[nscene], scenes[nscene]);
}
// Now iterate through the reference scenes, using IMS data from the scene_map scenes.
// initially will use earliest and latest scenes only. Improve for the future non-linear flying multicopters
// and account for sync loss (far samples with random coordinates)
double [] img_scales = new double[refCLTs.length];
double [] dist_visual = new double[refCLTs.length];
double [] dist_ims2 = new double[refCLTs.length];
for (int nref = 0; nref < refCLTs.length; nref++) {
QuadCLT ref_scene = refCLTs[nref];
ErsCorrection ers_reference = ref_scene.getErsCorrection();
// This does not work, as there can be stale in ers_reference.getScenes();
// String [] sts = ers_reference.getScenes();
// String [] first_last_ts = {sts[0],sts[sts.length - 1]};
String [] first_last_ts = ref_scene.getFirstLastTimestamps();
double[][] xyz_fl = new double [first_last_ts.length][];
Did_ins_2 [] did_2_fl= new Did_ins_2 [first_last_ts.length];
for (int n = 0; n < first_last_ts.length; n++) {
String ts= first_last_ts[n];
xyz_fl[n] = ers_reference.getSceneXYZ(ts);
did_2_fl[n] = scene_map.get(ts).did_ins_2;
}
double travel_visual2 = 0;
double travel_ims2 = 0;
double [] dned = Imx5.nedFromLla (did_2_fl[1].lla, did_2_fl[0].lla);
for (int i = 0; i < 3; i++) {
double dv = xyz_fl[1][i]-xyz_fl[0][i];
travel_visual2 += dv*dv;
travel_ims2 += dned[i]*dned[i];
}
dist_visual[nref] = Math.sqrt(travel_visual2);
dist_ims2[nref] = Math.sqrt(travel_ims2);
img_scales[nref] = Math.sqrt(travel_visual2/travel_ims2);
}
double sw = 0.0, swd = 0.0, sw_vis=0, sw_ims=0;
for (int nref = 0; nref < refCLTs.length; nref++) {
double w = 1.0;
sw += w;
swd += w * img_scales[nref];
sw_vis += dist_visual[nref];
sw_ims += dist_ims2[nref];
}
double img_scale = swd/sw;
if (debugLevel > -3) {
System.out.println("ts\timg_scale\tdist_visual\tdist_ims");
for (int nref = 0; nref < refCLTs.length; nref++) {
System.out.println(refCLTs[nref].getImageName()+"\t"+img_scales[nref]+"\t"+dist_visual[nref]+"\t"+dist_ims2[nref]);
}
System.out.println("Average\t"+img_scale+"\t"+(sw_vis/sw)+"\t"+(sw_ims/sw));
}
return img_scale;
}
/*
SetChannels [] set_channels=quadCLT_main.setChannels(debugLevel);
QuadCLT [] quadCLTs = new QuadCLT [set_channels.length];
for (int i = 0; i < quadCLTs.length; i++) {
quadCLTs[i] = (QuadCLT) quadCLT_main.spawnQuadCLT(
set_channels[i].set_name,
clt_parameters,
colorProcParameters, //
threadsMax,
debugLevel);
quadCLTs[i].setDSRBG(
clt_parameters, // CLTParameters clt_parameters,
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus, // boolean updateStatus,
debugLevel); // int debugLevel)
}
if (ref_index < 0) {
ref_index += quadCLTs.length;
}
*
*
public static double getImgImsScale( // correctInfinityFromIMS(
QuadCLT [] quadCLTs,
QuadCLT master_CLT,
int earliest_scene,
int latest_scene) { // -1 will use quadCLTs.length -1;
*/
}
...@@ -8579,19 +8579,18 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8579,19 +8579,18 @@ if (debugLevel > -100) return true; // temporarily !
int segment_index = -1; int segment_index = -1;
String [] scene_names = null; String [] scene_names = null;
String [] ref_scene_names = null; String [] ref_scene_names = null;
if (keep_segments) {
System.out.println("want to keep segments"); SetChannels [] set_channels_main = quadCLT_main.setChannels(debugLevel);
// inside OpticalFlow it was twice - some remnants from main/aux? if (set_channels_main != null) {
SetChannels [] set_channels_main = quadCLT_main.setChannels(debugLevel); scene_names = new String[ set_channels_main.length];
if (set_channels_main != null) { for (int i = 0; i < scene_names.length; i++) {
scene_names = new String[ set_channels_main.length]; scene_names[i] = set_channels_main[i].name();
for (int i = 0; i < scene_names.length; i++) {
scene_names[i] = set_channels_main[i].name();
}
Arrays.sort(scene_names);
} }
Arrays.sort(scene_names);
} }
/* /*
// Process UAS logs // Process UAS logs
UasLogReader uasLogReader = null; UasLogReader uasLogReader = null;
...@@ -8606,6 +8605,76 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8606,6 +8605,76 @@ if (debugLevel > -100) return true; // temporarily !
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null")); System.out.println("cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
} }
String index_name = null;
QuadCLT index_clt = null;
// only try to recover reference scenes if keep_segments
// if (keep_segments) {
// System.out.println("want to keep segments");
// }
boolean pre_series = true; // perform actions
int pre_series_orient = 1; // it is 1 now
int pre_series_accum = 2; // it is 2 now
boolean run_pre_series = false;
QuadCLT [] ref_scenes = null;
if (keep_segments && (scene_names != null)) {
// use last scene as index // ref_index
int index_index = ref_index;
if (index_index <0) index_index+=scene_names.length;
index_name = scene_names[index_index];
// get instance of the index scene if it exists and contains a list of ther reference scenes
index_clt = quadCLT_main.spawnQuadCLT(
index_name, // String set_name,
clt_parameters, // CLTParameters clt_parameters,
debugLevel); // int debugLevel);
index_scenes[0] = index_clt;
if (index_clt != null) {
ref_scene_names = index_clt.getRefScenes(); // ordered String[]
}
if (ref_scene_names != null) {
if (pre_series) {
ref_scenes = new QuadCLT [ref_scene_names.length];
// scan all reference scenes and find if they have enough orientations and accumulations
run_pre_series = true;
int [][] nums_orient_accum = new int [ref_scene_names.length][2];
for (int nref = 0; nref < nums_orient_accum.length; nref++) {
ref_scenes[nref] = quadCLT_main.spawnQuadCLT(
ref_scene_names[nref], // String set_name,
clt_parameters, // CLTParameters clt_parameters,
debugLevel); // int debugLevel);
int norient = ref_scenes[nref].getNumOrient();
int naccum = ref_scenes[nref].getNumAccum();
if (debugLevel > -4) {
System.out.println(String.format("# %2d, Scene:%s norient=%2d(%2d) naccum=%2d(%2d)",
nref, ref_scene_names[nref], norient, pre_series_orient, naccum, pre_series_accum));
}
if ((norient < pre_series_orient) || (naccum < pre_series_accum)) {
if (debugLevel > -4) {
System.out.println("Not enougth adjustments");
}
run_pre_series = false;
break;
}
}
}
}
}
boolean series_infinity = true;
if (run_pre_series) {
if (debugLevel > -4) {
System.out.println("===== Conditions met for all segment of the scene series, will run per-series calibrations =====");
}
if (series_infinity) {
double infinity_multi = SeriesInfinityCorrection.getInfinityMuliSeries(
clt_parameters, // CLTParameters clt_parameters,
ref_scenes, // QuadCLT [] quadCLTs,
index_scenes[0], // QuadCLT index_CLT, // normally - just the last in quadCLTs
debugLevel); // int debugLevel)
}
}
// boolean continue_ly = clt_parameters.imp.continue_ly; // calculate field calibration for this series even if it was calibrated earlier // boolean continue_ly = clt_parameters.imp.continue_ly; // calculate field calibration for this series even if it was calibrated earlier
int operation_mode = 0; int operation_mode = 0;
if (run_ly && (run_ly_mode > 0) && (run_ly_mode <= 3) ) { // do not yet know if ity is needed if (run_ly && (run_ly_mode > 0) && (run_ly_mode <= 3) ) { // do not yet know if ity is needed
...@@ -8688,9 +8757,16 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8688,9 +8757,16 @@ if (debugLevel > -100) return true; // temporarily !
break; break;
} }
ref_index = start_ref_pointers[0]; // continue from the same attached to the previous reference ref_index = start_ref_pointers[0]; // continue from the same attached to the previous reference
// System.out.println("Continue from index "+ref_index);
// continue; // and go to the to next scene sequence from the list
} }
// put test here, temporarily:
if (index_scenes[0] != null) {
SeriesInfinityCorrection.getInfinityMuliSeries(
clt_parameters, // CLTParameters clt_parameters,
null, // QuadCLT [] quadCLTs,
index_scenes[0], // QuadCLT index_CLT, // normally - just the last in quadCLTs
debugLevel); // int debugLevel)
}
stop_now_asap = sync_command.stopNow(false); stop_now_asap = sync_command.stopNow(false);
if ((model_directory == null) && !stop_now_asap) { if ((model_directory == null) && !stop_now_asap) {
System.out.println("Continue from index "+ref_index); System.out.println("Continue from index "+ref_index);
...@@ -8726,22 +8802,6 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8726,22 +8802,6 @@ if (debugLevel > -100) return true; // temporarily !
if( (scene_names != null) && (index_scenes[0] != null)) { if( (scene_names != null) && (index_scenes[0] != null)) {
if (ref_scene_names == null) { // proceesed first (latest by ts) segment if (ref_scene_names == null) { // proceesed first (latest by ts) segment
ref_scene_names = index_scenes[0].getRefScenes(); ref_scene_names = index_scenes[0].getRefScenes();
/*
ref_indices = new int [ref_scene_names.length];
Arrays.fill(ref_indices, -1);
// both are ordered
int scene_index =0;
for (int ref_indx = 0; ref_indx < ref_indices.length; ref_indx++) {
String ref_name = ref_scene_names[ref_indx];
for (; scene_index < scene_names.length; scene_index++) {
if (ref_name.equals(scene_names[scene_index])) {
ref_indices[ref_indx] = scene_index;
break;
}
}
}
*/
segment_index = ref_scene_names.length -1; segment_index = ref_scene_names.length -1;
} else { } else {
System.out.println("Using next segment's reference index"); System.out.println("Using next segment's reference index");
...@@ -8868,6 +8928,14 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8868,6 +8928,14 @@ if (debugLevel > -100) return true; // temporarily !
if (debugLevel > -4){ if (debugLevel > -4){
System.out.println("5. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null")); System.out.println("5. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
} }
// TODO: calculate infinity correction if needed using IMS
/*
SeriesInfinityCorrection.double getImgImsScale( // correctInfinityFromIMS(
QuadCLT [] quadCLTs,
QuadCLT master_CLT,
int earliest_scene,
int latest_scene)
*/
// List ground planes in this series: // List ground planes in this series:
Map<String, GroundPlane> map_gp = GroundPlane.getGroundPlanes( Map<String, GroundPlane> map_gp = GroundPlane.getGroundPlanes(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
......
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