Commit 2c6707fb authored by Andrey Filippov's avatar Andrey Filippov

Matching and processing series

parent d0c338fe
...@@ -876,6 +876,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -876,6 +876,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
jpanelLWIRWorld = new JPanel(); jpanelLWIRWorld = new JPanel();
jpanelLWIRWorld.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap jpanelLWIRWorld.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addJButton("Aux Build Series", jpanelLWIRWorld, color_stop); addJButton("Aux Build Series", jpanelLWIRWorld, color_stop);
addJButton("CUAS Combine", jpanelLWIRWorld, color_stop);
addJButton("Build World", jpanelLWIRWorld, color_process); addJButton("Build World", jpanelLWIRWorld, color_process);
addJButton("Test IMX5", jpanelLWIRWorld, color_process); addJButton("Test IMX5", jpanelLWIRWorld, color_process);
addJButton("Show mice", jpanelLWIRWorld, color_process); addJButton("Show mice", jpanelLWIRWorld, color_process);
...@@ -1283,6 +1284,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -1283,6 +1284,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
panelLWIRWorld = new Panel(); panelLWIRWorld = new Panel();
panelLWIRWorld.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap panelLWIRWorld.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Aux Build Series", panelLWIRWorld, color_stop); addButton("Aux Build Series", panelLWIRWorld, color_stop);
addButton("CUAS Combine", panelLWIRWorld, color_stop);
addButton("Build World", panelLWIRWorld, color_process); addButton("Build World", panelLWIRWorld, color_process);
addButton("Test IMX5", panelLWIRWorld, color_process); addButton("Test IMX5", panelLWIRWorld, color_process);
addButton("Show mice", panelLWIRWorld, color_process); addButton("Show mice", panelLWIRWorld, color_process);
...@@ -5688,9 +5690,21 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -5688,9 +5690,21 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
DEBUG_LEVEL = MASTER_DEBUG_LEVEL; DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
CLT_PARAMETERS.batch_run = true; CLT_PARAMETERS.batch_run = true;
buildSeries(true); buildSeries(
true,
0); // int cuas_proc_mode); // 0 - old, 1 combine scene series) {);
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("CUAS Combine")) {
DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
CLT_PARAMETERS.batch_run = true;
buildSeries(
true,
1); // int cuas_proc_mode); // 0 - old, 1 combine scene series) {);
return;
//"CUAS Combine"
/* ======================================================================== */
} else if (label.equals("Aux Inter Test")) { } else if (label.equals("Aux Inter Test")) {
DEBUG_LEVEL = MASTER_DEBUG_LEVEL; DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
...@@ -7832,7 +7846,9 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -7832,7 +7846,9 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
} }
public boolean buildSeries(boolean use_aux) { public boolean buildSeries(
boolean use_aux,
int cuas_proc_mode) { // 0 - old, 1 combine scene series) {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
// load needed sensor and kernels files // load needed sensor and kernels files
if (!prepareRigImages()) if (!prepareRigImages())
...@@ -7893,23 +7909,21 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -7893,23 +7909,21 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
try { try {
TwoQuadCLT.buildSeriesTQ( TwoQuadCLT.buildSeriesTQ(
0, // int cuas_proc_mode, // 0 - old, 1 combine scene series cuas_proc_mode, // int cuas_proc_mode, // 0 - old, 1 combine scene series
quadCLT, // QUAD_CLT, // QuadCLT quadCLT_main, quadCLT, // QUAD_CLT, // QuadCLT quadCLT_main,
-1, // int ref_index, -1, // int ref_index,
0, // int ref_step, 0, // int ref_step,
// QUAD_CLT_AUX, // QuadCLT quadCLT_aux, CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters, DEBAYER_PARAMETERS, // EyesisCorrectionParameters.DebayerParameters debayerParameters,
DEBAYER_PARAMETERS, // EyesisCorrectionParameters.DebayerParameters debayerParameters, colorProcParameters, // COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters
colorProcParameters, // COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters CHANNEL_GAINS_PARAMETERS, // CorrectionColorProc.ColorGainsParameters channelGainParameters,
// colorProcParameters, RGB_PARAMETERS, // EyesisCorrectionParameters.RGBParameters rgbParameters,
CHANNEL_GAINS_PARAMETERS, // CorrectionColorProc.ColorGainsParameters channelGainParameters,
RGB_PARAMETERS, // EyesisCorrectionParameters.RGBParameters rgbParameters,
EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters
// equirectangularParameters, // equirectangularParameters,
PROPERTIES, // Properties properties, PROPERTIES, // Properties properties,
true, // false, // boolean reset_from_extrinsics, true, // false, // boolean reset_from_extrinsics,
THREADS_MAX, // final int threadsMax, // maximal number of threads to launch THREADS_MAX, // final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, // final boolean updateStatus, UPDATE_STATUS, // final boolean updateStatus,
DEBUG_LEVEL); DEBUG_LEVEL);
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
......
...@@ -131,9 +131,16 @@ public class CuasMotion { ...@@ -131,9 +131,16 @@ public class CuasMotion {
public int getSeqLength() { public int getSeqLength() {
return clt_parameters.imp.cuas_corr_offset + clt_parameters.imp.cuas_corr_pairs; return clt_parameters.imp.cuas_corr_offset + clt_parameters.imp.cuas_corr_pairs;
} }
public int getCorrInc() { // == frame_step;
public static int getCorrInc(
CLTParameters clt_parameters) {
return clt_parameters.imp.cuas_half_step ? (clt_parameters.imp.cuas_corr_offset/2) : clt_parameters.imp.cuas_corr_offset; return clt_parameters.imp.cuas_half_step ? (clt_parameters.imp.cuas_corr_offset/2) : clt_parameters.imp.cuas_corr_offset;
} }
public int getCorrInc() { // == frame_step;
return getCorrInc(clt_parameters);
// return clt_parameters.imp.cuas_half_step ? (clt_parameters.imp.cuas_corr_offset/2) : clt_parameters.imp.cuas_corr_offset;
}
public int getNumCorrSamples() { public int getNumCorrSamples() {
return slice_titles.length; return slice_titles.length;
} }
...@@ -148,6 +155,26 @@ public class CuasMotion { ...@@ -148,6 +155,26 @@ public class CuasMotion {
return 0.5* getCorrInc()/corr_offset; return 0.5* getCorrInc()/corr_offset;
} }
/**
* Multiply RESULT_VX,RESULT_VX to get pixel offset per scene (at ~60Hz)
* @param clt_parameters
* @return coefficient for VX, VY
*/
public static double getFrameVelocityScale(CLTParameters clt_parameters) {
return 1.0/clt_parameters.imp.cuas_corr_offset;
}
/**
* Multiply RESULT_VX,RESULT_VX to get pixel offset per key frame (now ~6Hz)
* @param clt_parameters
* @return coefficient for VX, VY
*/
public static double getKeyFrameVelocityScale(CLTParameters clt_parameters) {
return getCorrInc(clt_parameters)/clt_parameters.imp.cuas_corr_offset;
}
public String [] getSceneTitles() { public String [] getSceneTitles() {
return scene_titles; return scene_titles;
} }
...@@ -1914,7 +1941,7 @@ public class CuasMotion { ...@@ -1914,7 +1941,7 @@ public class CuasMotion {
return vf; return vf;
} }
public static double [][][] getTargetsFromHyperAugment( public static double [][][] getTargetsFromHyperAugment_old(
String path){ // add empty fields to the end of each target if shorter than CuasMotionLMA.RSLT_LEN String path){ // add empty fields to the end of each target if shorter than CuasMotionLMA.RSLT_LEN
int [] wh = new int [2]; int [] wh = new int [2];
String [][] pvf_top_titles = new String[1][]; String [][] pvf_top_titles = new String[1][];
...@@ -1952,6 +1979,56 @@ public class CuasMotion { ...@@ -1952,6 +1979,56 @@ public class CuasMotion {
return target_sequence; return target_sequence;
} }
public static double [][][] getTargetsFromHyperAugment(
String path) {
return getTargetsFromHyperAugment(
null, // String [][] pvf_top_titles,
null, // String [][] pvf_titles,
path); //String path)
}
public static double [][][] getTargetsFromHyperAugment(
String [][] pvf_top_titles,
String [][] pvf_titles,
String path){ // add empty fields to the end of each target if shorter than CuasMotionLMA.RSLT_LEN
int [] wh = new int [2];
if (pvf_top_titles == null) pvf_top_titles = new String[1][];
if (pvf_titles == null) pvf_titles = new String[1][];
double [][][] targets_file = ShowDoubleFloatArrays.readDoubleHyperstack(
path, // String path,
wh, // int [] wh, // should be null or int[2]
pvf_top_titles, // String [][] ptop_titles, // should be null or String [1][]
pvf_titles); // String [][] pslice_titles){// should be null or String [1][]
if (targets_file == null) {
return null;
}
int num_fields = targets_file.length;
// fix - discarding last slice if it is called CuasMotionLMA.EXTRA_SLICE_DISCARD_ON_LOAD ("Targets")
if (pvf_top_titles[0][pvf_top_titles[0].length-1].equals(CuasMotionLMA.EXTRA_SLICE_DISCARD_ON_LOAD)) {
System.out.println("getTargetsFromHyperAugment(): removing last slice called "+ pvf_top_titles[0][pvf_top_titles[0].length-1]);
num_fields--;
String [] ss = new String[num_fields];
System.arraycopy(pvf_top_titles[0], 0, ss, 0, num_fields);
pvf_top_titles[0] = ss;
}
int num_fields_augmented = Math.max(num_fields, CuasMotionLMA.RSLT_LEN);
int num_seq = targets_file[0].length;
int num_tiles = targets_file[0][0].length;
double [][][] target_sequence = new double [num_seq][num_tiles][];
for (int nseq=0; nseq < num_seq; nseq++) {
for (int ntile = 0; ntile < num_tiles; ntile++) if (!Double.isNaN(targets_file[0][nseq][ntile])){
double [] v = new double[num_fields_augmented]; // cut to originally calculated fields
for (int i = 0; i < num_fields; i++) {
v[i] = targets_file[i][nseq][ntile];
}
for (int i = num_fields; i < num_fields_augmented; i++) {
v[i] = Double.NaN;
}
target_sequence[nseq][ntile] = v;
}
}
return target_sequence;
}
...@@ -6101,7 +6178,7 @@ public class CuasMotion { ...@@ -6101,7 +6178,7 @@ public class CuasMotion {
} }
/** /**
* Same for singl-layer targets (one target per tile) * Same for single-layer targets (one target per tile)
* @param targets_single [num_sequences][num_tiles][CuasMotionLMA.RSLT_LEN] source targets array * @param targets_single [num_sequences][num_tiles][CuasMotionLMA.RSLT_LEN] source targets array
* @return variable-length (may be empty) arrays following targets * @return variable-length (may be empty) arrays following targets
*/ */
......
...@@ -98,8 +98,8 @@ public class CuasMotionLMA { ...@@ -98,8 +98,8 @@ public class CuasMotionLMA {
public static final int RSLT_FL_DISP = 56; // flight log true disparity public static final int RSLT_FL_DISP = 56; // flight log true disparity
public static final int RSLT_FL_RANGE = 57; // flight log range (meters) public static final int RSLT_FL_RANGE = 57; // flight log range (meters)
public static final int RSLT_INFINITY = 58; // disparity at infinity used for range calculation public static final int RSLT_INFINITY = 58; // disparity at infinity used for range calculation
public static final int RSLT_TARGET_ID = 59; // unique target id for the whole sequence of segments. 1 is reserved for the UAS
public static final int RSLT_LEN = RSLT_INFINITY + 1; public static final int RSLT_LEN = RSLT_TARGET_ID + 1;
public static final String [] LMA_TITLES = public static final String [] LMA_TITLES =
{"X-OFFS","Y-OFFS", "AMPLITUDE", "RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS", {"X-OFFS","Y-OFFS", "AMPLITUDE", "RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS",
...@@ -117,7 +117,8 @@ public class CuasMotionLMA { ...@@ -117,7 +117,8 @@ public class CuasMotionLMA {
"WHEN", "FAILURE", "WHEN", "FAILURE",
"Disparity","Disparity-Diff","Strength","Range","Global-index", "Disparity","Disparity-Diff","Strength","Range","Global-index",
"segment-length","segment-disparity","segment_disp-diff", "segment-strength", "segment-range", "segment-length","segment-disparity","segment_disp-diff", "segment-strength", "segment-range",
"FLOG-px","FLOG-pY","FLOG-DISP","FLOG-range","infinity"}; "FLOG-px","FLOG-pY","FLOG-DISP","FLOG-range","infinity",
"GTarget-ID"};
public static final String EXTRA_SLICE_DISCARD_ON_LOAD = "Targets"; public static final String EXTRA_SLICE_DISCARD_ON_LOAD = "Targets";
public static final int FAIL_NONE = 0; public static final int FAIL_NONE = 0;
public static final int FAIL_MOTION = 1; // motion strength/fraction too low public static final int FAIL_MOTION = 1; // motion strength/fraction too low
......
package com.elphel.imagej.cuas;
import java.awt.Point;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.gpu.GPUTileProcessor;
import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.QuadCLT;
import ij.ImagePlus;
import ij.io.FileSaver;
public class CuasMultiSeries {
public static final int TARGET_INDEX_NONE = 0;
public static final int TARGET_INDEX_UAS = 1;
final CLTParameters clt_parameters;
final File [] model_dirs;
final String [] model_names;
final double [][][][] targets_multi_series; // [nser][nseq][ntile][nfield]
final int [][][][] linked_targets_multi; // [nser][ntarg][nseq]{ntile,0} // was {ntile, alt}
final int [][] target_map; // [nser][ntarg] global target index, 1 for UAS
final int [][] local_map; // [nser][ntarg]
final int [][][] local_imap; // [nser][ntarg_grp]{ntarg1, ...}
final int [][][] targets_start_end; //[nser][ntarg]{start_nseq,end_nseq}
final int [][] uas_tiles;
final String [][] scene_titles;
int global_targets = 0;
QuadCLT master_CLT = null;
// int debugLevel = 0;
public CuasMultiSeries (
CLTParameters clt_parameters,
QuadCLT quadCLT_main,
String path,
String version) {
// System.out.println ("CuasMultiSeries(): path="+path);
this.clt_parameters = clt_parameters;
File [] scene_dirs = (new File(path)).listFiles(); // may contain non-directories, will be filtered by filterScenes
Arrays.sort(scene_dirs);
int num_series = scene_dirs.length;
targets_multi_series = new double [num_series][][][];
scene_titles = new String [num_series][];
linked_targets_multi = new int [num_series][][][];
target_map = new int [num_series][];
local_map = new int [num_series][];
local_imap= new int [num_series][][];
targets_start_end = new int [num_series][][]; // [nser][ntarg]{start, end}
uas_tiles = new int [num_series][];
master_CLT = quadCLT_main;
model_dirs = new File[num_series];
model_names = new String[num_series];
for (int nser = 0; nser < num_series; nser++) {
model_names[nser] = scene_dirs[nser].getName(); // 1747803230_276111-CENTER
model_dirs[nser] = new File(scene_dirs[nser], version);
String target_file_name = model_names[nser]+ CuasMotion.getParametersSuffixRanging(clt_parameters,CuasRanging.TARGET_DISPARITIES_SUFFIX)+".tiff";
File target_file=new File(model_dirs[nser], target_file_name);
String [][] scen_titles_w = new String[1][];
targets_multi_series[nser] = CuasMotion.getTargetsFromHyperAugment(
null, // String [][] pvf_top_titles,
scen_titles_w, // String [][] pvf_titles,
target_file.toString());
scene_titles[nser] = scen_titles_w[0];
linked_targets_multi[nser] = CuasMotion.getLinkedTargets(targets_multi_series[nser]); // [nser][ntarg(zero-based]{ntile,0}
target_map[nser] = new int [linked_targets_multi[nser].length];
for (int i = 0; i < target_map[nser].length; i++) {
target_map[nser][i] = TARGET_INDEX_NONE;
}
uas_tiles[nser] = new int [targets_multi_series[nser].length]; // number of key frames
Arrays.fill(uas_tiles[nser], -1);
targets_start_end[nser] = new int [linked_targets_multi[nser].length][2];
for (int ntarg = 0; ntarg < targets_start_end[nser].length; ntarg++) {
int i = 0;
for (; i < linked_targets_multi[nser][ntarg].length; i++) {
if (linked_targets_multi[nser][ntarg][i] != null) {
targets_start_end[nser][ntarg][0] = i;
break;
}
}
for ( i++; i < linked_targets_multi[nser][ntarg].length; i++) {
if (linked_targets_multi[nser][ntarg][i] == null) {
break;
}
}
targets_start_end[nser][ntarg][1] = i-1;
}
}
printAssignmentStats();
// show missing here
return;
}
public void saveUpdatedTargets() {
int num_series =targets_multi_series.length;
for (int nser = 0; nser < num_series; nser++) {
String target_file_name = model_names[nser]+ CuasMotion.getParametersSuffixRanging(clt_parameters,CuasRanging.TARGET_GLOBALS_SUFFIX)+".tiff";
File target_file=new File(model_dirs[nser], target_file_name);
String file_path = target_file.toString();
ImagePlus imp_with_globals = CuasMotion.showTargetSequence(
targets_multi_series[nser], // double [][][] vector_fields_sequence,
scene_titles[nser] , // String [] titles, // all slices*frames titles or just slice titles or null
target_file_name,
false, // boolean show,
master_CLT.getTilesX()); // int tilesX) {
FileSaver fs=new FileSaver(imp_with_globals);
fs.saveAsTiff(file_path); // image processor null?
System.out.println("saveUpdatedTargets(): saved "+file_path);
}
}
public void processGlobals() {
int debugLevel = 0;
int setup_uas = setupUasTiles();
System.out.println("processGlobals(): setupUasTiles() -> "+setup_uas);
int assign_uas_target = assignUasTarget();
System.out.println("processGlobals(): assignUasTarget() -> "+assign_uas_target);
printAssignmentStats();
printUasStats();
printAssignments();
combineLocalTargets(
true, // boolean skip_assigned, // if global ID is assigned, do not mess wi that pair
debugLevel); // int debugLevel)
printLocalAssignments();
combineGlobalTargets(
true, // boolean skip_assigned, // if global ID is assigned, do not mess wi that pair
debugLevel); // int debugLevel)
printAssignmentStats();
printAssignments();
saveUpdatedTargets();
return;
}
public void printUasStats() {
System.out.println("printUasStats(): UAS detected in segments:");
for (int nseg = 0; nseg < target_map.length; nseg++) {
System.out.print(nseg+" ("+model_names[nseg]+"): ");
for (int ntarg =0; ntarg < target_map[nseg].length; ntarg++) {
if (target_map[nseg][ntarg] == TARGET_INDEX_UAS) {
System.out.print(ntarg+" ");
}
}
System.out.println();
}
return;
}
public void printAssignmentStats() {
int [] stats = getAssignmentStatus();
System.out.println("Number of global targets: "+stats[0]+", number of local targets: "+stats[1]+", of them assigned: "+stats[2]);
return;
}
public void printLocalAssignments() {
System.out.println("void printLocalAssignments(): local target group assignments");
for (int nseg = 0; nseg < local_map.length; nseg++) {
System.out.print(nseg+ " ("+model_names[nseg]+") ("+local_map[nseg].length+"): ");
for (int i = 0; i < local_map[nseg].length; i++) {
System.out.print(local_map[nseg][i]+" ");
}
System.out.println();
}
return;
}
public void printAssignments() {
System.out.println("void printAssignments(): local-to-global target assignments");
for (int nseg = 0; nseg < target_map.length; nseg++) {
System.out.print(nseg+ " ("+model_names[nseg]+") ("+target_map[nseg].length+"): ");
for (int i = 0; i < target_map[nseg].length; i++) {
System.out.print(target_map[nseg][i]+" ");
}
System.out.println();
}
return;
}
/**
* Get total number of local targets and number of assigned ones
* Sets global_targets to the total number of global targets
* @return {global_targets, num_total, num_assigned}
*/
public int [] getAssignmentStatus() {
global_targets= 0;
int num_total = 0;
int num_assigned = 0;
for (int nser = 0; nser < target_map.length; nser++) {
num_total += target_map[nser].length;
for (int ntarg = 0; ntarg < target_map[nser].length; ntarg++) {
global_targets = Math.max(global_targets,target_map[nser][ntarg]);
if (target_map[nser][ntarg] > 0) {
num_assigned++;
}
}
}
return new int [] {global_targets, num_total, num_assigned};
}
/**
* Setup sequences of tiles corresponding to the UAS movements
* @return number of keyframes with missing UAS log (should be 0)
*/
public int setupUasTiles() {
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger amiss = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSer = ai.getAndIncrement(); nSer < targets_multi_series.length; nSer = ai.getAndIncrement()) {
for (int nseq = 0; nseq < targets_multi_series[nSer].length; nseq++) {
for (int ntile = 0; ntile < targets_multi_series[nSer][nseq].length; ntile++) {
double [] target = targets_multi_series[nSer][nseq][ntile];
if ((target != null) && !Double.isNaN(target[CuasMotionLMA.RSLT_FL_PX])) {
uas_tiles[nSer][nseq] = ntile;
break; // only one reference UAS in the air
}
}
if (uas_tiles[nSer][nseq] < 0) {
amiss.getAndIncrement();
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return amiss.get();
}
/**
* Find which of the local (per series targets correspond to the UAS with a flight log)
* @return number of assigned local targets
*/
public int assignUasTarget() {
final double tmtch_pix= clt_parameters.imp.cuas_tmtch_pix;
final double tmtch_frac = clt_parameters.imp.cuas_tmtch_frac;
final int tileSize = GPUTileProcessor.DTT_SIZE;
final double tmtch_pix2 = tmtch_pix * tmtch_pix;
final int tilesX = master_CLT.getTilesX();
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger aglob = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSer = ai.getAndIncrement(); nSer < targets_multi_series.length; nSer = ai.getAndIncrement()) {
int [][][] ltargets = linked_targets_multi[nSer];
double [][][] mtargets = targets_multi_series[nSer];
int [] utiles = uas_tiles[nSer];
int num_targets = ltargets.length;
int [] num_def = new int [num_targets];
int [] num_match = new int [num_targets];
boolean [][] conflict = new boolean [num_targets][num_targets]; // both halves defined are defined
for (int nseq = 0; nseq < utiles.length; nseq++) {
int utile = utiles[nseq];
if (utile >= 0) {
double [] utarget = mtargets[nseq][utile];
double upx = utarget[CuasMotionLMA.RSLT_FL_PX];
double upy = utarget[CuasMotionLMA.RSLT_FL_PY];
for (int ntarg = 0; ntarg < num_targets; ntarg++) if (ltargets[ntarg][nseq] != null) {
int ltile = ltargets[ntarg][nseq][0];
double [] ltarget = mtargets[nseq][ltile];
int tileX = ltile % tilesX;
int tileY = ltile / tilesX;
double px = tileSize * tileX + tileSize/2 + ltarget[CuasMotionLMA.RSLT_X];
double py = tileSize * tileY + tileSize/2 + ltarget[CuasMotionLMA.RSLT_Y];
double dx = px - upx;
double dy = py - upy;
double err2 = dx*dx + dy*dy;
// match[ntarg][nseq] = (err2 <= known_err2);
num_def[ntarg]++;
if (err2 <= tmtch_pix2) {
num_match[ntarg]++;
}
for (int ntarg1 = ntarg+1;ntarg1 < num_targets; ntarg1++) if (ltargets[ntarg1][nseq] != null){
conflict[ntarg][ntarg1] = true;
conflict[ntarg1][ntarg] = true;
}
}
}
}
// keep only that have enough fraction, if conflict - keep best fraction
int num_good = 0;
for (int ntarg = 0; ntarg < num_targets; ntarg++) if (num_match[ntarg] > 0){
if (num_match[ntarg] < num_def[ntarg] * tmtch_frac) {
num_match[ntarg] = 0;
} else {
num_good++;
}
}
if (num_good > 0) {
if (num_good > 1) { // check/remove conflicting
for (int ntarg = 0; ntarg < num_targets; ntarg++) if (num_match[ntarg] > 0){
for (int ntarg1 = 0; ntarg1 < num_targets; ntarg1++) if ((ntarg1 != ntarg) && (num_match[ntarg1] > 0)){
if (conflict[ntarg][ntarg1] && (num_match[ntarg1] > num_match[ntarg])) {
num_match[ntarg] = 0;
}
}
}
}
// now all ntarg with num_match[ntarg] > 0 match UAS
for (int ntarg = 0; ntarg < num_targets; ntarg++) if (num_match[ntarg] > 0){
target_map[nSer][ntarg] = TARGET_INDEX_UAS;
aglob.getAndIncrement();
for (int nseq = 0; nseq< mtargets.length; nseq++) {
if (ltargets[ntarg][nseq] != null) {
double [] target = mtargets[nseq][ltargets[ntarg][nseq][0]];
target[CuasMotionLMA.RSLT_TARGET_ID] = TARGET_INDEX_UAS;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return aglob.get();
}
/**
* Combine same-sequence targets that may correspond to the same actual target
* @return
*/
public int combineLocalTargets(
boolean skip_assigned, // if global ID is assigned, do not mess wi that pair
int debugLevel) {
int debug_min = -2; // if >= then print
boolean debug = debugLevel>= debug_min;
final int tmtch_gaps = clt_parameters.imp.cuas_tmtch_gaps;
final double tmtch_apix = clt_parameters.imp.cuas_tmtch_apix;
// final double tmtch_axv = clt_parameters.imp.cuas_tmtch_axv;
// final double tmtch_axv_k = clt_parameters.imp.cuas_tmtch_axv_k;
// final double tmtch_disp = clt_parameters.imp.cuas_tmtch_disp;
final boolean shortest_gap = clt_parameters.imp.cuas_tmtch_short; // if two merges conflict, use one with the shortest gap (false - longest combo). Pairwise only
final double tmtch_pix2 = tmtch_apix * tmtch_apix;
// final double velocity_scale = 1.0/clt_parameters.imp.cuas_corr_offset;
final int tilesX = master_CLT.getTilesX();
final int tileSize = GPUTileProcessor.DTT_SIZE;
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 nSer = ai.getAndIncrement(); nSer < targets_multi_series.length; nSer = ai.getAndIncrement()) {
double fps = getFps(nSer);
int num_targ = targets_start_end[nSer].length;
int num_after = 0;
boolean [][] after = new boolean [num_targ][num_targ];
// skip pairs that have global target_id >0 (at least skip UAS
for (int ntarg = 0; ntarg < num_targ; ntarg++) if (!skip_assigned ||(target_map[nSer][ntarg] <= 0)) { // no globally assigned
for (int ntarg1 = ntarg+1; ntarg1 < num_targ; ntarg1++) if (!skip_assigned || (target_map[nSer][ntarg1] <= 0)) { // no globally assigned
if (targets_start_end[nSer][ntarg][1] < targets_start_end[nSer][ntarg1][0]) {
if ((targets_start_end[nSer][ntarg1][0] - targets_start_end[nSer][ntarg][1]) <= tmtch_gaps) {
after[ntarg][ntarg1] = true; // ntarg1 is after ntarg
num_after++;
}
}
if (targets_start_end[nSer][ntarg1][1] < targets_start_end[nSer][ntarg][0]) {
if ((targets_start_end[nSer][ntarg][0] - targets_start_end[nSer][ntarg1][1]) <= tmtch_gaps) {
after[ntarg1][ntarg] = true; // ntarg1 is after ntarg
num_after++;
}
}
}
}
local_map[nSer] = new int [num_targ]; // [nser][ntarg]
local_imap[nSer]= new int [num_targ][1]; // [nser][ntarg]
for (int i = 0; i < num_targ; i++) {
local_map[nSer][i] = i; // trivial mapping
local_imap[nSer][i][0] = i; // trivial mapping
}
if (num_after > 0) {
ArrayList<Point> pair_list = new ArrayList<Point>();
for (int ntarg0 = 0; ntarg0 < num_targ; ntarg0++) {
for (int ntarg1 = 0; ntarg1 < num_targ; ntarg1++) if (after[ntarg0][ntarg1]){
int nseq0= targets_start_end[nSer][ntarg0][1]; // end of 0
int nseq1= targets_start_end[nSer][ntarg1][0]; // start of 1
int ntile0 = linked_targets_multi[nSer][ntarg0][nseq0][0];
int ntile1 = linked_targets_multi[nSer][ntarg1][nseq1][0];
double [] target0 = targets_multi_series[nSer][nseq0][ntile0];
double [] target1 = targets_multi_series[nSer][nseq1][ntile1];
double err2 = getMispatch2(
clt_parameters, // CLTParameters clt_parameters,
target0, // double [] target0,
target1, // double [] target1,
scene_titles[nSer][nseq0], // String sts0,
scene_titles[nSer][nseq1], // String sts1,
ntile0, // int ntile0,
ntile1, // int ntile1,
tilesX, // int tilesX,
tileSize, // int tileSize,
fps); // double fps,
// check gap size
// check ranges/disparity
if (err2 <= tmtch_pix2) {
pair_list.add(new Point(ntarg0, ntarg1));
if (debug) {
System.out.println("combineLocalTargets(): nSer="+nSer+", ntarg0="+ntarg0+", ntarg1="+ntarg1+
", err="+Math.sqrt(err2));
}
}
}
}
if (!pair_list.isEmpty()) {
// check for conflicts
removeConflictPairs(
pair_list, // ArrayList<Point> pair_list, // in each pair, .x is earlier than .y
nSer, // int nser0, // corresponds to .x, may be the same as nser1 (for local merging)
nSer, // int nser1, // corresponds to .y, may be the same as nser0 (for local merging)
shortest_gap, // boolean shortest_gap,
debugLevel); // int debugLevel) {
// combine all the remaining pairs
for (Point p:pair_list) {
int mn = Math.min(local_map[nSer][p.x], local_map[nSer][p.y]);
int mx = Math.max(local_map[nSer][p.x], local_map[nSer][p.y]);
for (int i = 0; i < local_map[nSer].length; i++) {
if (local_map[nSer][i] == mx) {
local_map[nSer][i] = mn;
} else if (local_map[nSer][i] > mx) {
local_map[nSer][i] --;
}
}
}
local_imap[nSer] = new int[num_targ - pair_list.size()][];
for (int i = 0; i < local_imap[nSer].length; i++) {
int nt = 0;
for (int j: local_map[nSer]) {
if (j==i) nt++;
}
//local_imap[nSer][i] = new int [nt];
Integer [] itargets = new Integer[nt];
nt = 0;
for (int j = 0; j < num_targ; j++) {
if (local_map[nSer][j] == i) {
// local_imap[nSer][i][nt++] = j;
itargets[nt++] = j;
}
}
// reorder local_imap[nSer][i] in the order of first nscene //local_imap[nSer][i]
Arrays.sort(itargets, new Comparator<Integer>() { //
@Override
public int compare(Integer lhs, Integer rhs) {
return Integer.compare(lhs, rhs);
}
});
local_imap[nSer][i] = Arrays.stream(itargets)
.filter(ii -> ii != null) // Filter out nulls if present
.mapToInt(Integer::intValue)
.toArray();
}
} // if (!pair_list.isEmpty()) {
} // if (num_after > 0) {
}
}
};
}
ImageDtt.startAndJoin(threads);
return 0;
}
public int combineGlobalTargets(
boolean skip_assigned, // if global ID is assigned, do not mess wi that pair
int debugLevel) {
int debug_min = -2; // if >= then print
boolean debug = debugLevel>= debug_min;
final int tmtch_ends = clt_parameters.imp.cuas_tmtch_ends;
// final int tmtch_gaps = clt_parameters.imp.cuas_tmtch_gaps;
final double tmtch_apix = clt_parameters.imp.cuas_tmtch_apix;
final double tmtch_rpix = clt_parameters.imp.cuas_tmtch_rpix;
final double tmtch_axv = clt_parameters.imp.cuas_tmtch_axv;
final double tmtch_axv_k = clt_parameters.imp.cuas_tmtch_axv_k;
final double min_disp = clt_parameters.imp.cuas_tmtch_disp + clt_parameters.imp.cuas_infinity; // minimal "raw" disparity (with infinity at cuas_infinity)
final boolean shortest_gap = clt_parameters.imp.cuas_tmtch_short; // if two merges conflict, use one with the shortest gap (false - longest combo). Pairwise only
// final double tmtch_pix2 = tmtch_apix * tmtch_apix;
// final double velocity_scale = 1.0/clt_parameters.imp.cuas_corr_offset;
final int tilesX = master_CLT.getTilesX();
final int tileSize = GPUTileProcessor.DTT_SIZE;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(1);
final int [][][] pairs = new int [local_map.length][][]; // [nSer][npair]{target_group_prev_nser,target_group_nser}
if (pairs.length > 0) {
pairs[0] = new int [0][];
}
// pair[0] is local target index, not the target group
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSer = ai.getAndIncrement(); nSer < targets_multi_series.length; nSer = ai.getAndIncrement()) {
double fps = getFps(nSer);
int prev_ser = nSer -1;
ArrayList<Point> pair_list = new ArrayList<Point>();
for (int ntgrp0 = 0; ntgrp0 < local_imap[prev_ser].length; ntgrp0++) {
int [] targs0 = local_imap[prev_ser][ntgrp0];
if (targs0.length > 0){
int ntarg0 = targs0[targs0.length -1]; // last if several are connected
if (!skip_assigned || (target_map[prev_ser][ntarg0] <= 0)) { // not globally assigned
int nseq0 = targets_start_end[prev_ser][ntarg0][1]; // end of the last segment in previous series
int end_gap = linked_targets_multi[prev_ser][ntarg0].length -1 - nseq0;
if (end_gap <= tmtch_ends) {
int ntile0 = linked_targets_multi[prev_ser][ntarg0][nseq0][0];
double [] target0 = targets_multi_series[prev_ser][nseq0][ntile0];
double ts0 = QuadCLT.getTimeStamp(scene_titles[prev_ser][nseq0]);
for (int ntgrp1 = 0; ntgrp1 < local_imap[nSer].length; ntgrp1++) {
int [] targs1 = local_imap[nSer][ntgrp1];
if (targs1.length > 0){
int ntarg1 = targs1[0]; // first if several are connected
if (!skip_assigned || (target_map[nSer][ntarg1] <= 0)) { // no globally assigned
int nseq1 = targets_start_end[nSer][ntarg1][0]; // start of the first segment in this series
if (nseq1 <= tmtch_ends) {
int ntile1 = linked_targets_multi[nSer][ntarg1][nseq1][0];
double [] target1 = targets_multi_series[nSer][nseq1][ntile1];
double ts1 = QuadCLT.getTimeStamp(scene_titles[nSer][nseq1]);
double dt = ts1-ts0;
double lat_err2 = getMispatch2(
clt_parameters, //CLTParameters clt_parameters
target0, // double [] target0,
target1, // double [] target1,
scene_titles[prev_ser][nseq0], // String sts0,
scene_titles[nSer][nseq1], // String sts1,
ntile0, // int ntile0,
ntile1, // int ntile1,
tilesX, // int tilesX,
tileSize, // int tileSize,
fps); // double fps,
double max_lat_err = tmtch_apix + tmtch_rpix * dt;
// calculate maximal allowable error adding time difference
double max_lat_err2 = max_lat_err * max_lat_err;
if (lat_err2 <= max_lat_err2) {
// calculate axial error and verify, print debug
// TODO: average ranging if there are several local targets corresponding to the same object
double [] middle_target0 = getMiddleTarget(
prev_ser, // int nser,
ntarg0); // int local_target)
double [] middle_target1 = getMiddleTarget(
nSer, // int nser,
ntarg1); // int local_target)
// only check matches if disparity is sufficient
boolean range_match = true;
if ((middle_target0 != null) && (middle_target1 != null) && // do not have measured disparity at all
(middle_target0[CuasMotionLMA.RSLT_GDISPARITY] > min_disp) &&
(middle_target1[CuasMotionLMA.RSLT_GDISPARITY] > min_disp)) {
double range0 = middle_target0[CuasMotionLMA.RSLT_GRANGE];
double range1 = middle_target1[CuasMotionLMA.RSLT_GRANGE];
double avelocity = (range1 - range0)/dt;
double lvelocity = getLateralVelocity (
clt_parameters, //CLTParameters clt_parameters,
middle_target0, // double [] target0, // should contain RSLT_VX, RSLT_VX, RSLT_GRANGE,
middle_target1, // double [] target1, // should contain RSLT_VX, RSLT_VX, RSLT_GRANGE,
fps); // double fps){ // velocity_scale times fps
double max_axial_velocity = Math.max(tmtch_axv, lvelocity * tmtch_axv_k);
if (Math.abs (avelocity) > max_axial_velocity) {
range_match = false;
}
if (debug) {
System.out.println("combineGlobalTargets(): nSer="+nSer+", ntarg0="+ntarg0+", ntarg1="+ntarg1+
", range0="+range0+", range1="+range1+", avelocity="+avelocity+"m/s, lvelocity="+
lvelocity+"m/s, disparity="+
middle_target0[CuasMotionLMA.RSLT_GDISPARITY]+
":"+middle_target1[CuasMotionLMA.RSLT_GDISPARITY] +
", max_axial_velocity="+max_axial_velocity+"m/s, range_match="+range_match);
}
} else {
if (debug) {
double disp0 = (middle_target0 == null)? Double.NaN: middle_target0[CuasMotionLMA.RSLT_GDISPARITY];
double disp1 = (middle_target1 == null)? Double.NaN: middle_target1[CuasMotionLMA.RSLT_GDISPARITY];
System.out.println("combineGlobalTargets(): nSer="+nSer+", ntarg0="+ntarg0+", ntarg1="+ntarg1+
". Bypassing axial matching - disparity="+disp0+
":"+disp1+" < "+min_disp+" .");
}
}
if (range_match) {
pair_list.add(new Point(ntarg0, ntarg1));
}
}
}
}
}
}
}
}
}
} // for (int ntgrp0 = 0; ntgrp0 < local_imap[prev_ser].length; ntgrp0++) {
// find and resolve conflicts between pairs
// pair.x is in previous segment (prev_seg), and in case of a chain - the last one
// pair.y is the local index of a target in this (nSeg) segment, and in case of a chain - the first one
// will compare only these 2 targets, not the total length for the chain
if (!pair_list.isEmpty()) {
// check for conflicts
removeConflictPairs(
pair_list, // ArrayList<Point> pair_list, // in each pair, .x is earlier than .y
prev_ser, // int nser0, // corresponds to .x, may be the same as nser1 (for local merging)
nSer, // int nser1, // corresponds to .y, may be the same as nser0 (for local merging)
shortest_gap, // boolean shortest_gap,
debugLevel); // int debugLevel) {
// combine all the remaining pairs
// convert pair_list to array -> pairs[nSer]
pairs[nSer] = new int [pair_list.size()][2];
for (int i = 0; i < pairs[nSer].length; i++) {
Point p = pair_list.get(i);
pairs[nSer][i] = new int[] {p.x, p.y};
}
} else {
pairs[nSer] = new int [0][];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// process pairs, assign global indices
// non -threaded part
int next_global_target_id = TARGET_INDEX_UAS + 1; // 2
for (int nser = 0; nser < target_map.length; nser++) {
int num_seq = targets_multi_series[nser].length;
if (nser > 0) {
// start with pairs
for (int [] pair : pairs[nser]) { // null?
int target_id = target_map[nser-1][pair[0]];
int tgrp = local_map[nser][pair[1]];
for (int i = 0; i < local_imap[nser][tgrp].length; i++) {
int ntarg = local_imap[nser][tgrp][i];
target_map[nser][ntarg] = target_id;
for (int nseq = 0; nseq < num_seq; nseq++) {
int [] ltm = linked_targets_multi[nser][ntarg][nseq];
if (ltm != null) {
int ntile = ltm[0];
double [] target = targets_multi_series[nser][nseq][ntile];
target[CuasMotionLMA.RSLT_TARGET_ID] = target_id;
}
}
}
}
}
for (int tgrp = 0; tgrp < local_imap[nser].length; tgrp++) if (local_imap[nser][tgrp].length > 0){
int target_id = -1;
for (int i = 0; i < local_imap[nser][tgrp].length; i++) {
int ntarg = local_imap[nser][tgrp][i];
if (target_map[nser][ntarg] == TARGET_INDEX_NONE) { // 0, not yet assigned
if (target_id <= 0) { // assign once
target_id = next_global_target_id++;
}
target_map[nser][ntarg] = target_id;
for (int nseq = 0; nseq < num_seq; nseq++) {
int [] ltm = linked_targets_multi[nser][ntarg][nseq];
if (ltm != null) {
int ntile = ltm[0];
double [] target = targets_multi_series[nser][nseq][ntile];
target[CuasMotionLMA.RSLT_TARGET_ID] = target_id;
}
}
}
}
}
}
// print more debug
return next_global_target_id;
}
public double getFps(int nser) {
double fps = (CuasMotion.getCorrInc(clt_parameters) * (scene_titles[nser].length - 1.0))/(QuadCLT.getTimeStamp(scene_titles[nser][scene_titles[nser].length-1]) -
QuadCLT.getTimeStamp(scene_titles[nser][0]));
return fps;
}
private void removeConflictPairs(
ArrayList<Point> pair_list, // in each pair, .x is earlier than .y
int nser0, // corresponds to .x, may be the same as nser1 (for local merging)
int nser1, // corresponds to .y, may be the same as nser0 (for local merging)
boolean shortest_gap,
int debugLevel) {
int debug_min = -2; // if >= then print
boolean debug = debugLevel>= debug_min;
boolean conflict = true;
while (conflict) {
conflict= false;
check_for_conflicts: {
for (int npair0 = 0; npair0< (pair_list.size()); npair0++) {
Point p0 = pair_list.get(npair0); // here: .x - local target index in the previous series (prev_ser), .y - in this one (nSer)
for (int npair1 = npair0 +1; npair1< (pair_list.size()); npair1++) {
Point p1 = pair_list.get(npair1);
if (p1.x == p0.x) {
if (shortest_gap) {
int p0_start1 = targets_start_end[nser1][p0.y][0]; // start of the second segment
int p1_start1 = targets_start_end[nser1][p1.y][0];
if (p0_start1 < p1_start1) {
if (debug) System.out.println("1 nser "+nser0+":"+nser1+" removing pair ["+p1.x+","+p1.y+"] as its gap is longer than ["+p0.x+","+p0.y+"]");
pair_list.remove(npair1);
} else {
if (debug) System.out.println("2 nser "+nser0+":"+nser1+" removing pair ["+p0.x+","+p0.y+"] as its gap is longer than ["+p1.x+","+p1.y+"]");
pair_list.remove(npair0);
}
} else {
int p0_end = targets_start_end[nser1][p0.y][1];
int p1_end = targets_start_end[nser1][p1.y][1];
if (p0_end > p1_end) {
if (debug) System.out.println("3 nser "+nser0+":"+nser1+" removing pair ["+p1.x+","+p1.y+"] as it is shorter than ["+p0.x+","+p0.y+"]");
pair_list.remove(npair1);
} else {
if (debug) System.out.println("4 nser "+nser0+":"+nser1+" removing pair ["+p0.x+","+p0.y+"] as it is shorter than ["+p1.x+","+p1.y+"]");
pair_list.remove(npair0);
}
}
conflict = true;
break check_for_conflicts;
}
if (p1.y == p0.y) {
if (shortest_gap) {
int p0_end0 = targets_start_end[nser0][p0.x][1]; // end of the first segment
int p1_end0 = targets_start_end[nser0][p1.x][1];
if (p0_end0 > p1_end0) {
if (debug) System.out.println("removing pair ["+p1.x+","+p1.y+"] as its gap is longer than ["+p0.x+","+p0.y+"]");
pair_list.remove(npair1);
} else {
if (debug) System.out.println("removing pair ["+p0.x+","+p0.y+"] as its gap is longer than ["+p1.x+","+p1.y+"]");
pair_list.remove(npair0);
}
} else {
int p0_start0 = targets_start_end[nser0][p0.x][0];
int p1_start0 = targets_start_end[nser0][p1.x][0];
if (p0_start0 < p1_start0) {
if (debug) System.out.println("removing pair ["+p1.x+","+p1.y+"] as it is shorter than ["+p0.x+","+p0.y+"]");
pair_list.remove(npair1);
} else {
if (debug) System.out.println("removing pair ["+p0.x+","+p0.y+"] as it is shorter than ["+p1.x+","+p1.y+"]");
pair_list.remove(npair0);
}
}
conflict = true;
break check_for_conflicts;
}
}
}
}
}
return;
}
/**
* Find the "middle" keyframe that contanis disparity/range for the specified local target index (0-based)
* @param nser series number containing specified local target
* @param local_target local
* @return target array containing the longest averaged disparity and range for the specified target
*/
private double [] getMiddleTarget(
int nser,
int local_target) {
int [][] lt = linked_targets_multi[nser][local_target];
int len_middle = -1;
int nseq_middle = -1;
int ntile_middle = -1;
for (int nseq = 0; nseq < lt.length; nseq++) {
if (lt[nseq] != null) {
int ntile = lt[nseq][0]; // null pointer
double [] target = targets_multi_series[nser][nseq][ntile];
if (target != null) {
double dlength = target[CuasMotionLMA.RSLT_GLENGTH];
if (!Double.isNaN(dlength)) {
int ilength = (int) dlength;
if (ilength > len_middle) {
len_middle = ilength;
nseq_middle = nseq;
ntile_middle = ntile;
}
}
}
}
}
if (len_middle >= 0) {
return targets_multi_series[nser][nseq_middle][ntile_middle];
} else {
return null;
}
}
private double getMispatch2(
CLTParameters clt_parameters,
double [] target0,
double [] target1,
String sts0,
String sts1,
int ntile0,
int ntile1,
int tilesX,
int tileSize,
double fps) {
// multiply Vx, VY to get pixel shift in one frame (@60Hz)
double velocity_scale = CuasMotion.getFrameVelocityScale(clt_parameters);
double ts0 = QuadCLT.getTimeStamp(sts0);
double ts1 = QuadCLT.getTimeStamp(sts1);
double dscenes = fps * (ts1 - ts0); // number of scene between
int tileX0 = ntile0 % tilesX;
int tileY0 = ntile0 / tilesX;
int tileX1 = ntile1 % tilesX;
int tileY1 = ntile1 / tilesX;
double px0 = tileSize * tileX0 + tileSize/2 + target0[CuasMotionLMA.RSLT_X];
double py0 = tileSize * tileY0 + tileSize/2 + target0[CuasMotionLMA.RSLT_Y];
double px1 = tileSize * tileX1 + tileSize/2 + target1[CuasMotionLMA.RSLT_X];
double py1 = tileSize * tileY1 + tileSize/2 + target1[CuasMotionLMA.RSLT_Y];
double vx = 0.5*(target0[CuasMotionLMA.RSLT_VX] + target1[CuasMotionLMA.RSLT_VX]);
double vy = 0.5*(target0[CuasMotionLMA.RSLT_VY] + target1[CuasMotionLMA.RSLT_VY]);
double dpx = px1 - px0;
double dpy = py1 - py0;
dpx -= vx * velocity_scale * dscenes;
dpy -= vy * velocity_scale * dscenes;
double err2 = dpx*dpx + dpy * dpy;
return err2;
}
/**
* Get lateral velocity in m/s
* @param clt_parameters
* @param target0
* @param target1
* @param fps
* @return
*/
private double getLateralVelocity (
CLTParameters clt_parameters,
double [] target0, // should contain RSLT_VX, RSLT_VX, RSLT_GRANGE,
double [] target1, // should contain RSLT_VX, RSLT_VX, RSLT_GRANGE,
double fps){ // velocity_scale times fps
// TODO: Improve to use actual geometry
double ifov = clt_parameters.imp.cuas_ifov; // 0.05; // degree per pixel
double ifov_rad = ifov / 180 * Math.PI;
double velocity_scale = CuasMotion.getFrameVelocityScale(clt_parameters); // == 1.0/clt_parameters.imp.cuas_corr_offset;
double range = target0[CuasMotionLMA.RSLT_GRANGE]; // meters
double vpx = 0.5*(target0[CuasMotionLMA.RSLT_VX] + target1[CuasMotionLMA.RSLT_VX]) * velocity_scale * fps;
double vpy = 0.5*(target0[CuasMotionLMA.RSLT_VY] + target1[CuasMotionLMA.RSLT_VY]) * velocity_scale * fps;
double vxm = vpx * ifov_rad * range;
double vym = vpy * ifov_rad * range;
double vm = Math.sqrt(vxm*vxm+vym*vym);
return vm;
}
public void setupGlobalTargets(
) {
double known_err= clt_parameters.imp.cuas_known_err;
double tmtch_frac = clt_parameters.imp.cuas_tmtch_frac;
int tmtch_ends = clt_parameters.imp.cuas_tmtch_ends;
double tmtch_pix = clt_parameters.imp.cuas_tmtch_pix;
double tmtch_axv = clt_parameters.imp.cuas_tmtch_axv;
double tmtch_axv_k = clt_parameters.imp.cuas_tmtch_axv_k;
double tmtch_disp = clt_parameters.imp.cuas_tmtch_disp;
}
}
...@@ -27,6 +27,7 @@ public class CuasRanging { ...@@ -27,6 +27,7 @@ public class CuasRanging {
public static final String TARGET_RANGING_LOGS_SUFFIX = "-TARGET_RANGING.log"; public static final String TARGET_RANGING_LOGS_SUFFIX = "-TARGET_RANGING.log";
public static final String TARGET_RANGING_LOGS_FULL_SUFFIX = "-TARGET_RANGING_FULL.log"; public static final String TARGET_RANGING_LOGS_FULL_SUFFIX = "-TARGET_RANGING_FULL.log";
public static final String TARGET_DISPARITIES_SUFFIX = "-TARGET_DISPARITIES"; public static final String TARGET_DISPARITIES_SUFFIX = "-TARGET_DISPARITIES";
public static final String TARGET_GLOBALS_SUFFIX = "-TARGET_GLOBALS";
public static final String TARGET_STATS_SUFFIX = "-TARGETS"; // *.csv public static final String TARGET_STATS_SUFFIX = "-TARGETS"; // *.csv
......
...@@ -821,7 +821,6 @@ min_str_neib_fpn 0.35 ...@@ -821,7 +821,6 @@ min_str_neib_fpn 0.35
public int cuas_target_type = 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe public int cuas_target_type = 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
public int cuas_known_type = 2; // 0 - unknown, 1 - known, 2 - friend, 3 - foe public int cuas_known_type = 2; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
public double cuas_known_err = 20; // pix, mark as "identified" when closer to the flight log position
public double cuas_input_range = 5; public double cuas_input_range = 5;
public boolean cuas_scale2x = true; public boolean cuas_scale2x = true;
...@@ -901,7 +900,7 @@ min_str_neib_fpn 0.35 ...@@ -901,7 +900,7 @@ min_str_neib_fpn 0.35
public double cuas_initial_disparity = 1.0; // Start correlation with this disparity (in addition to infinity) after reset public double cuas_initial_disparity = 1.0; // Start correlation with this disparity (in addition to infinity) after reset
public double cuas_infinity = 0.65; // disparity at infinity for targets public double cuas_infinity = 0.65; // disparity at infinity for targets
public boolean cuas_rng_img = false; // Generate/save per-sensor target images public boolean cuas_rng_img = false; // Generate/save per-sensor target images
public boolean cuas_rng_glob= true; // Generate/save integrated target disparities (one per target) TODO: add first/second half public boolean cuas_rng_glob= true; // Generate/save integrated target disparities (one per target) TODO: add first/second half
public int cuas_glob_ends = 0; // 0 - same as internal, 1 - cosine extended ends, 2 - rectangular extended ends // make a parameter public int cuas_glob_ends = 0; // 0 - same as internal, 1 - cosine extended ends, 2 - rectangular extended ends // make a parameter
public boolean cuas_rng_disp= true; // Generate/save target disparities public boolean cuas_rng_disp= true; // Generate/save target disparities
...@@ -915,6 +914,19 @@ min_str_neib_fpn 0.35 ...@@ -915,6 +914,19 @@ min_str_neib_fpn 0.35
public int cuas_flw_len = 10; // Minimal number of key frames in each segment after division; public int cuas_flw_len = 10; // Minimal number of key frames in each segment after division;
public double cuas_flw_diff = 0.03; // (pix) Minimal difference between halves to use "tilted" non-constant disparity public double cuas_flw_diff = 0.03; // (pix) Minimal difference between halves to use "tilted" non-constant disparity
// targets matching parameters
public double cuas_known_err = 20; // pix, mark as "identified" when closer to the flight log position
public double cuas_tmtch_frac = 0.8; // target should match flight log in theis fraction of keyframes
public int cuas_tmtch_ends = 2; // maximal number of undetected first/last keyframes to compare to previous/next sequence
public int cuas_tmtch_gaps = 4; // maximal number of consecutive undetected keyframes of the same target
public double cuas_tmtch_pix = 10.0; // maximal pixel mismatch for UAS target
public double cuas_tmtch_apix = 10.0; // maximal absolute pixel mismatch for the same target extrapolated with the average of the before/after lateral speeds
public double cuas_tmtch_rpix = 1.0; // maximal pixel/s mismatch for the same target extrapolated with the average of the before/after lateral speeds
public double cuas_tmtch_axv = 20.0; // m/s maximal axial (range) velocity in m/s
public double cuas_tmtch_axv_k = 3.0; // maximal axial (range) velocity to lateral velocity ratio (take max)
public double cuas_tmtch_disp = 0.1; // minimal disparity difference to estimate lateral velocity (smaller - consider matching)
public boolean cuas_tmtch_short = true; // when multiple conflicting matches, prefer shortest gap (false - longest combo pair length)
// debug parameters // debug parameters
public boolean cuas_debug = false; // save debug images (and show them if not in batch mode) public boolean cuas_debug = false; // save debug images (and show them if not in batch mode)
public int cuas_dbg_rng_seq = -1; // Debug single sequence ranging (-1 - process all) public int cuas_dbg_rng_seq = -1; // Debug single sequence ranging (-1 - process all)
...@@ -2556,8 +2568,6 @@ min_str_neib_fpn 0.35 ...@@ -2556,8 +2568,6 @@ min_str_neib_fpn 0.35
"0 - unknown (dashed square), 1 - known (square), 2 - friend (circle), 3 - foe (diamond)."); "0 - unknown (dashed square), 1 - known (square), 2 - friend (circle), 3 - foe (diamond).");
gd.addNumericField("Identified Targets icon type", this.cuas_known_type, 0,3,"", gd.addNumericField("Identified Targets icon type", this.cuas_known_type, 0,3,"",
"0 - unknown (dashed square), 1 - known (square), 2 - friend (circle), 3 - foe (diamond)."); "0 - unknown (dashed square), 1 - known (square), 2 - friend (circle), 3 - foe (diamond).");
gd.addNumericField("Maximal distance from log position", this.cuas_known_err, 5,8,"pix",
"Maximal distance between the detected target and UAS log position (in raw image pixels).");
gd.addNumericField("Image range", this.cuas_input_range, 5,8,"10mK", gd.addNumericField("Image range", this.cuas_input_range, 5,8,"10mK",
"Dispaly pixel values range (1.0 ~= 10 mK)."); "Dispaly pixel values range (1.0 ~= 10 mK).");
...@@ -2735,6 +2745,30 @@ min_str_neib_fpn 0.35 ...@@ -2735,6 +2745,30 @@ min_str_neib_fpn 0.35
gd.addNumericField("Disparity halves disparity difference", this.cuas_flw_diff, 5,8,"pix", gd.addNumericField("Disparity halves disparity difference", this.cuas_flw_diff, 5,8,"pix",
"Minimal difference between halves to use \"tilted\" (non-constant) disparity."); "Minimal difference between halves to use \"tilted\" (non-constant) disparity.");
gd.addMessage("=== Targets matching between scene sequences ===");
gd.addNumericField("Maximal distance from log position", this.cuas_known_err, 5,8,"pix",
"Maximal distance between the detected target and UAS log position (in raw image pixels). Also used for annotations.");
gd.addNumericField("Match flight log fraction", this.cuas_tmtch_frac, 5,8,"x",
"Target should match flight log in this fraction of keyframes to be identified as UAS.");
gd.addNumericField("Maximal undetected first/last", this.cuas_tmtch_ends, 0,3,"keyframes",
"Maximal number of undetected first/last keyframes to compare to previous/next sequence.");
gd.addNumericField("Maxiaml undetected gaps in the same sequence",this.cuas_tmtch_gaps, 0,3,"keyframes",
"Maxiaml undetected target gaps in the same sequence.");
gd.addNumericField("Maximal pixel mismatch for the UAS target", this.cuas_tmtch_pix, 5,8,"pix",
"Maximal pixel mismatch for the UAS target extrapolated with the average of the before/after lateral speeds.");
gd.addNumericField("Maximal lateral mismatch, same sequence", this.cuas_tmtch_apix, 5,8,"pix",
"Maximal pixel mismatch for the same non-UAS target extrapolated with the average of the before/after lateral speeds.");
gd.addNumericField("Maximal lateral mismatch, per second", this.cuas_tmtch_rpix, 5,8,"pix/s",
"Maximal pixel mismatch for the same target extrapolated with the average of the before/after lateral speeds.");
gd.addNumericField("Maximal axial velocity", this.cuas_tmtch_axv, 5,8,"m/s",
"Maximal axial (range) velocity in m/s.");
gd.addNumericField("Maximal axial to lateral ratio", this.cuas_tmtch_axv_k, 5,8,"pix",
"Maximal axial (range) velocity to lateral velocity ratio (take max axial velocity).");
gd.addNumericField("Minimal disparity difference", this.cuas_tmtch_disp, 5,8,"pix",
"Minimal disparity difference to estimate lateral velocity (smaller - consider matching).");
gd.addCheckbox ("Prefer shortest gap", this.cuas_tmtch_short,
"When multiple conflicting matches, prefer shortest gap (false - longest combo pair length).");
gd.addMessage("=== Debug ==="); gd.addMessage("=== Debug ===");
gd.addCheckbox ("Save/show debug images", this.cuas_debug, gd.addCheckbox ("Save/show debug images", this.cuas_debug,
"Save CUAS-related debug images and show them in non-batch mode."); "Save CUAS-related debug images and show them in non-batch mode.");
...@@ -3826,7 +3860,6 @@ min_str_neib_fpn 0.35 ...@@ -3826,7 +3860,6 @@ min_str_neib_fpn 0.35
this.cuas_mask_round = gd.getNextBoolean(); this.cuas_mask_round = gd.getNextBoolean();
this.cuas_target_type= (int) gd.getNextNumber(); this.cuas_target_type= (int) gd.getNextNumber();
this.cuas_known_type= (int) gd.getNextNumber(); this.cuas_known_type= (int) gd.getNextNumber();
this.cuas_known_err= gd.getNextNumber();
this.cuas_input_range = gd.getNextNumber(); this.cuas_input_range = gd.getNextNumber();
this.cuas_scale2x = gd.getNextBoolean(); this.cuas_scale2x = gd.getNextBoolean();
...@@ -3935,9 +3968,21 @@ min_str_neib_fpn 0.35 ...@@ -3935,9 +3968,21 @@ min_str_neib_fpn 0.35
this.cuas_rng_niterate = (int) gd.getNextNumber(); this.cuas_rng_niterate = (int) gd.getNextNumber();
this.cuas_rng_diff = gd.getNextNumber(); this.cuas_rng_diff = gd.getNextNumber();
this.cuas_flw_levels = (int) gd.getNextNumber(); this.cuas_flw_levels = (int) gd.getNextNumber();
this.cuas_flw_len = (int) gd.getNextNumber(); this.cuas_flw_len = (int) gd.getNextNumber();
this.cuas_flw_diff = gd.getNextNumber(); this.cuas_flw_diff = gd.getNextNumber();
this.cuas_known_err= gd.getNextNumber();
this.cuas_tmtch_frac= gd.getNextNumber();
this.cuas_tmtch_ends= (int) gd.getNextNumber();
this.cuas_tmtch_gaps= (int) gd.getNextNumber();
this.cuas_tmtch_pix= gd.getNextNumber();
this.cuas_tmtch_apix= gd.getNextNumber();
this.cuas_tmtch_rpix= gd.getNextNumber();
this.cuas_tmtch_axv= gd.getNextNumber();
this.cuas_tmtch_axv_k= gd.getNextNumber();
this.cuas_tmtch_disp= gd.getNextNumber();
this.cuas_tmtch_short = gd.getNextBoolean();
this.cuas_debug = gd.getNextBoolean(); this.cuas_debug = gd.getNextBoolean();
this.cuas_dbg_rng_seq = (int) gd.getNextNumber(); this.cuas_dbg_rng_seq = (int) gd.getNextNumber();
...@@ -4936,7 +4981,6 @@ min_str_neib_fpn 0.35 ...@@ -4936,7 +4981,6 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_mask_round", this.cuas_mask_round+""); // boolean properties.setProperty(prefix+"cuas_mask_round", this.cuas_mask_round+""); // boolean
properties.setProperty(prefix+"cuas_target_type", this.cuas_target_type+""); // int properties.setProperty(prefix+"cuas_target_type", this.cuas_target_type+""); // int
properties.setProperty(prefix+"cuas_known_type", this.cuas_known_type+""); // int properties.setProperty(prefix+"cuas_known_type", this.cuas_known_type+""); // int
properties.setProperty(prefix+"cuas_known_err", this.cuas_known_err+""); // double
properties.setProperty(prefix+"cuas_input_range", this.cuas_input_range+""); // double properties.setProperty(prefix+"cuas_input_range", this.cuas_input_range+""); // double
properties.setProperty(prefix+"cuas_scale2x", this.cuas_scale2x+""); // boolean properties.setProperty(prefix+"cuas_scale2x", this.cuas_scale2x+""); // boolean
...@@ -5032,6 +5076,18 @@ min_str_neib_fpn 0.35 ...@@ -5032,6 +5076,18 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_flw_levels", this.cuas_flw_levels+""); // int properties.setProperty(prefix+"cuas_flw_levels", this.cuas_flw_levels+""); // int
properties.setProperty(prefix+"cuas_flw_len", this.cuas_flw_len+""); // int properties.setProperty(prefix+"cuas_flw_len", this.cuas_flw_len+""); // int
properties.setProperty(prefix+"cuas_flw_diff", this.cuas_flw_diff+""); // double properties.setProperty(prefix+"cuas_flw_diff", this.cuas_flw_diff+""); // double
properties.setProperty(prefix+"cuas_known_err", this.cuas_known_err+""); // double
properties.setProperty(prefix+"cuas_tmtch_frac", this.cuas_tmtch_frac+""); // double
properties.setProperty(prefix+"cuas_tmtch_ends", this.cuas_tmtch_ends+""); // int
properties.setProperty(prefix+"cuas_tmtch_gaps", this.cuas_tmtch_gaps+""); // int
properties.setProperty(prefix+"cuas_tmtch_pix", this.cuas_tmtch_pix+""); // double
properties.setProperty(prefix+"cuas_tmtch_apix", this.cuas_tmtch_apix+""); // double
properties.setProperty(prefix+"cuas_tmtch_rpix", this.cuas_tmtch_rpix+""); // double
properties.setProperty(prefix+"cuas_tmtch_axv", this.cuas_tmtch_axv+""); // double
properties.setProperty(prefix+"cuas_tmtch_axv_k", this.cuas_tmtch_axv_k+""); // double
properties.setProperty(prefix+"cuas_tmtch_disp", this.cuas_tmtch_disp+""); // double
properties.setProperty(prefix+"cuas_tmtch_short", this.cuas_tmtch_short+""); // boolean
properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean
properties.setProperty(prefix+"cuas_dbg_rng_seq", this.cuas_dbg_rng_seq+""); // int properties.setProperty(prefix+"cuas_dbg_rng_seq", this.cuas_dbg_rng_seq+""); // int
...@@ -6005,7 +6061,6 @@ min_str_neib_fpn 0.35 ...@@ -6005,7 +6061,6 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_mask_round")!=null) this.cuas_mask_round=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_mask_round")); if (properties.getProperty(prefix+"cuas_mask_round")!=null) this.cuas_mask_round=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_mask_round"));
if (properties.getProperty(prefix+"cuas_target_type")!=null) this.cuas_target_type=Integer.parseInt(properties.getProperty(prefix+"cuas_target_type")); if (properties.getProperty(prefix+"cuas_target_type")!=null) this.cuas_target_type=Integer.parseInt(properties.getProperty(prefix+"cuas_target_type"));
if (properties.getProperty(prefix+"cuas_known_type")!=null) this.cuas_known_type=Integer.parseInt(properties.getProperty(prefix+"cuas_known_type")); if (properties.getProperty(prefix+"cuas_known_type")!=null) this.cuas_known_type=Integer.parseInt(properties.getProperty(prefix+"cuas_known_type"));
if (properties.getProperty(prefix+"cuas_known_err")!=null) this.cuas_known_err=Double.parseDouble(properties.getProperty(prefix+"cuas_known_err"));
if (properties.getProperty(prefix+"cuas_input_range")!=null) this.cuas_input_range=Double.parseDouble(properties.getProperty(prefix+"cuas_input_range")); if (properties.getProperty(prefix+"cuas_input_range")!=null) this.cuas_input_range=Double.parseDouble(properties.getProperty(prefix+"cuas_input_range"));
if (properties.getProperty(prefix+"cuas_scale2x")!=null) this.cuas_scale2x=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_scale2x")); if (properties.getProperty(prefix+"cuas_scale2x")!=null) this.cuas_scale2x=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_scale2x"));
...@@ -6103,6 +6158,18 @@ min_str_neib_fpn 0.35 ...@@ -6103,6 +6158,18 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_flw_len")!=null) this.cuas_flw_len=Integer.parseInt(properties.getProperty(prefix+"cuas_flw_len")); if (properties.getProperty(prefix+"cuas_flw_len")!=null) this.cuas_flw_len=Integer.parseInt(properties.getProperty(prefix+"cuas_flw_len"));
if (properties.getProperty(prefix+"cuas_flw_diff")!=null) this.cuas_flw_diff=Double.parseDouble(properties.getProperty(prefix+"cuas_flw_diff")); if (properties.getProperty(prefix+"cuas_flw_diff")!=null) this.cuas_flw_diff=Double.parseDouble(properties.getProperty(prefix+"cuas_flw_diff"));
if (properties.getProperty(prefix+"cuas_known_err")!=null) this.cuas_known_err=Double.parseDouble(properties.getProperty(prefix+"cuas_known_err"));
if (properties.getProperty(prefix+"cuas_tmtch_frac")!=null) this.cuas_tmtch_frac=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_frac"));
if (properties.getProperty(prefix+"cuas_tmtch_ends")!=null) this.cuas_tmtch_ends=Integer.parseInt(properties.getProperty(prefix+"cuas_tmtch_ends"));
if (properties.getProperty(prefix+"cuas_tmtch_gaps")!=null) this.cuas_tmtch_gaps=Integer.parseInt(properties.getProperty(prefix+"cuas_tmtch_gaps"));
if (properties.getProperty(prefix+"cuas_tmtch_pix")!=null) this.cuas_tmtch_pix=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_pix"));
if (properties.getProperty(prefix+"cuas_tmtch_apix")!=null) this.cuas_tmtch_apix=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_apix"));
if (properties.getProperty(prefix+"cuas_tmtch_rpix")!=null) this.cuas_tmtch_rpix=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_rpix"));
if (properties.getProperty(prefix+"cuas_tmtch_axv")!=null) this.cuas_tmtch_axv=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_axv"));
if (properties.getProperty(prefix+"cuas_tmtch_axv_k")!=null) this.cuas_tmtch_axv_k=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_axv_k"));
if (properties.getProperty(prefix+"cuas_tmtch_disp")!=null) this.cuas_tmtch_disp=Double.parseDouble(properties.getProperty(prefix+"cuas_tmtch_disp"));
if (properties.getProperty(prefix+"cuas_tmtch_short")!=null) this.cuas_tmtch_short=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_tmtch_short"));
if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug")); if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug"));
if (properties.getProperty(prefix+"cuas_dbg_rng_seq")!=null) this.cuas_dbg_rng_seq=Integer.parseInt(properties.getProperty(prefix+"cuas_dbg_rng_seq")); if (properties.getProperty(prefix+"cuas_dbg_rng_seq")!=null) this.cuas_dbg_rng_seq=Integer.parseInt(properties.getProperty(prefix+"cuas_dbg_rng_seq"));
if (properties.getProperty(prefix+"cuas_dbg_rng_tgt")!=null) this.cuas_dbg_rng_tgt=Integer.parseInt(properties.getProperty(prefix+"cuas_dbg_rng_tgt")); if (properties.getProperty(prefix+"cuas_dbg_rng_tgt")!=null) this.cuas_dbg_rng_tgt=Integer.parseInt(properties.getProperty(prefix+"cuas_dbg_rng_tgt"));
...@@ -7074,7 +7141,6 @@ min_str_neib_fpn 0.35 ...@@ -7074,7 +7141,6 @@ min_str_neib_fpn 0.35
imp.cuas_mask_round = this.cuas_mask_round; imp.cuas_mask_round = this.cuas_mask_round;
imp.cuas_target_type= this.cuas_target_type; imp.cuas_target_type= this.cuas_target_type;
imp.cuas_known_type= this.cuas_known_type; imp.cuas_known_type= this.cuas_known_type;
imp.cuas_known_err= this.cuas_known_err;
imp.cuas_input_range = this.cuas_input_range; imp.cuas_input_range = this.cuas_input_range;
imp.cuas_scale2x = this.cuas_scale2x; imp.cuas_scale2x = this.cuas_scale2x;
...@@ -7161,6 +7227,18 @@ min_str_neib_fpn 0.35 ...@@ -7161,6 +7227,18 @@ min_str_neib_fpn 0.35
imp.cuas_flw_len = this.cuas_flw_len; imp.cuas_flw_len = this.cuas_flw_len;
imp.cuas_flw_diff = this.cuas_flw_diff; imp.cuas_flw_diff = this.cuas_flw_diff;
imp.cuas_known_err= this.cuas_known_err;
imp.cuas_tmtch_frac = this.cuas_tmtch_frac;
imp.cuas_tmtch_ends = this.cuas_tmtch_ends;
imp.cuas_tmtch_gaps = this.cuas_tmtch_gaps;
imp.cuas_tmtch_pix = this.cuas_tmtch_pix;
imp.cuas_tmtch_apix = this.cuas_tmtch_apix;
imp.cuas_tmtch_rpix = this.cuas_tmtch_rpix;
imp.cuas_tmtch_axv = this.cuas_tmtch_axv;
imp.cuas_tmtch_axv_k = this.cuas_tmtch_axv_k;
imp.cuas_tmtch_disp = this.cuas_tmtch_disp;
imp.cuas_tmtch_short = this.cuas_tmtch_short;
imp.cuas_debug = this.cuas_debug; imp.cuas_debug = this.cuas_debug;
imp.cuas_dbg_rng_seq = this.cuas_dbg_rng_seq; imp.cuas_dbg_rng_seq = this.cuas_dbg_rng_seq;
imp.cuas_dbg_rng_tgt = this.cuas_dbg_rng_tgt; imp.cuas_dbg_rng_tgt = this.cuas_dbg_rng_tgt;
......
...@@ -72,6 +72,7 @@ import com.elphel.imagej.correction.Eyesis_Correction; ...@@ -72,6 +72,7 @@ import com.elphel.imagej.correction.Eyesis_Correction;
import com.elphel.imagej.cuas.CorrectionFPN; import com.elphel.imagej.cuas.CorrectionFPN;
import com.elphel.imagej.cuas.Cuas; import com.elphel.imagej.cuas.Cuas;
import com.elphel.imagej.cuas.CuasData; import com.elphel.imagej.cuas.CuasData;
import com.elphel.imagej.gpu.GPUTileProcessor;
import com.elphel.imagej.gpu.GpuQuad; import com.elphel.imagej.gpu.GpuQuad;
import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.ims.Did_gps_pos; import com.elphel.imagej.ims.Did_gps_pos;
...@@ -3125,13 +3126,30 @@ public class QuadCLTCPU { ...@@ -3125,13 +3126,30 @@ public class QuadCLTCPU {
*/ */
public int getTileSize() { public int getTileSize() {
if (tp == null) {
return GPUTileProcessor.DTT_SIZE;
}
return tp.getTileSize(); return tp.getTileSize();
} }
public int getTilesX() { public int getTilesX() {
if (tp == null) {
// if (geometryCorrection == null) {
// if QuadCLT use gpuQuad
// } else {
return geometryCorrection.getSensorWH()[0]/GPUTileProcessor.DTT_SIZE;
// }
}
return tp.getTilesX(); return tp.getTilesX();
} }
public int getTilesY() { public int getTilesY() {
if (tp == null) {
// if (geometryCorrection == null) {
// if QuadCLT use gpuQuad
// } else {
return geometryCorrection.getSensorWH()[1]/GPUTileProcessor.DTT_SIZE;
// }
}
return tp.getTilesY(); return tp.getTilesY();
} }
public int getNumColors(){ public int getNumColors(){
......
...@@ -54,6 +54,7 @@ import com.elphel.imagej.common.GenericJTabbedDialog; ...@@ -54,6 +54,7 @@ import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.correction.CorrectionColorProc; import com.elphel.imagej.correction.CorrectionColorProc;
import com.elphel.imagej.correction.EyesisCorrections; import com.elphel.imagej.correction.EyesisCorrections;
import com.elphel.imagej.cuas.CuasMultiSeries;
import com.elphel.imagej.gpu.ExportForGPUDevelopment; import com.elphel.imagej.gpu.ExportForGPUDevelopment;
import com.elphel.imagej.gpu.GPUTileProcessor; import com.elphel.imagej.gpu.GPUTileProcessor;
import com.elphel.imagej.gpu.GpuQuad; import com.elphel.imagej.gpu.GpuQuad;
...@@ -8646,298 +8647,308 @@ if (debugLevel > -100) return true; // temporarily ! ...@@ -8646,298 +8647,308 @@ if (debugLevel > -100) return true; // temporarily !
cuas_centers = new String [] {quadCLT_main.correctionsParameters.getCuasDir(),""}; cuas_centers = new String [] {quadCLT_main.correctionsParameters.getCuasDir(),""};
} }
*/ */
switch (cuas_proc_mode) {
String uas_sky_mask_path = quadCLT_main.correctionsParameters.getUasSkyMask(); case 0 :
String uas_sky_mask_path = quadCLT_main.correctionsParameters.getUasSkyMask();
for (int nseq = 0; nseq < num_seq; nseq++) { for (int nseq = 0; nseq < num_seq; nseq++) {
long start_time_seq = System.nanoTime(); long start_time_seq = System.nanoTime();
System.out.println("\nSTARTED PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+")\n"); System.out.println("\nSTARTED PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+")\n");
if (pathFirstLast != null) { if (pathFirstLast != null) {
File [] scene_dirs = (new File(pathFirstLast[nseq].path)).listFiles(); // may contain non-directories, will be filtered by filterScenes File [] scene_dirs = (new File(pathFirstLast[nseq].path)).listFiles(); // may contain non-directories, will be filtered by filterScenes
quadCLT_main.correctionsParameters.filterScenes( quadCLT_main.correctionsParameters.filterScenes(
scene_dirs, // File [] scene_dirs, scene_dirs, // File [] scene_dirs,
pathFirstLast[nseq].first, // int scene_first, // first scene to process pathFirstLast[nseq].first, // int scene_first, // first scene to process
pathFirstLast[nseq].last); // int scene_last); // last scene to process (negative - add length pathFirstLast[nseq].last); // int scene_last); // last scene to process (negative - add length
if (pathFirstLast[nseq].movement_size < 0) { if (pathFirstLast[nseq].movement_size < 0) {
clt_parameters.imp.mov_en = false; clt_parameters.imp.mov_en = false;
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("Disabling movement detection for this scene."); System.out.println("Disabling movement detection for this scene.");
}
} else {
clt_parameters.imp.mov_en = true;
clt_parameters.imp.mov_max_len = pathFirstLast[nseq].movement_size;
if (debugLevel > -4) {
System.out.println("Enabling movement detection for this scene with maximum cluster linear size of "+
clt_parameters.imp.mov_max_len+" tiles.");
}
} }
} else { clt_parameters.imp.cuas_sky_path = uas_sky_mask_path;
clt_parameters.imp.mov_en = true; if (clt_parameters.imp.cuas_sky_path != null) {
clt_parameters.imp.mov_max_len = pathFirstLast[nseq].movement_size; clt_parameters.imp.cuas_sky_offset = new double[] {pathFirstLast[nseq].mask_x,pathFirstLast[nseq].mask_y};
if (debugLevel > -4) {
System.out.println("Enabling movement detection for this scene with maximum cluster linear size of "+
clt_parameters.imp.mov_max_len+" tiles.");
} }
} }
clt_parameters.imp.cuas_sky_path = uas_sky_mask_path;
if (clt_parameters.imp.cuas_sky_path != null) {
clt_parameters.imp.cuas_sky_offset = new double[] {pathFirstLast[nseq].mask_x,pathFirstLast[nseq].mask_y};
}
}
String [][] video_list = new String[1][];
int [][] widths_list = new int [1][];
int ref_index = -1; // -1 - last
int [] start_ref_pointers = new int[2]; //{earlist, reference} - reference may be center
boolean first_in_series = true;
// Process UAS logs
UasLogReader uasLogReader = null;
String uas_log_path = quadCLT_main.correctionsParameters.getUasLogsPath();
System.out.println("Using UAS log file: "+uas_log_path);
if ((uas_log_path != null) && (uas_log_path.length() > 0)) {
uasLogReader = new UasLogReader(uas_log_path, quadCLT_main.correctionsParameters.cuasUasTimeStamp, null, quadCLT_main);
uasLogReader.setCameraATR(quadCLT_main.correctionsParameters.cuasCameraATR);
uasLogReader.setUASHomeNed(quadCLT_main.correctionsParameters.cuasSetHome? quadCLT_main.correctionsParameters.cuasUASHome : null);
}
if (debugLevel > -4) {
System.out.println("cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
}
while ((ref_index < 0) || ((ref_index + 1) >= min_num_scenes)) {
String model_directory = opticalFlow.buildSeries(
(pathFirstLast != null), //boolean batch_mode,
first_in_series, // boolean first_in_series,
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
ref_index, // int ref_index, // -1 - last
clt_parameters, // CLTParameters clt_parameters,
debayerParameters, // EyesisCorrectionParameters.DebayerParameters debayerParameters,
colorProcParameters, // ColorProcParameters colorProcParameters,
channelGainParameters, // CorrectionColorProc.ColorGainsParameters channelGainParameters,
rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters,
equirectangularParameters, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
properties, // Properties properties,
reset_from_extrinsics, // boolean reset_from_extrinsics,
video_list, // String [][] video_list, // null or list of generated avi or webm paths
widths_list,
start_ref_pointers, // int [] start_ref_pointers,
cuas_centers, // String [] cuas_centers, // [0] - cumulative input, [1] - cumulative output
// processing UAS logs
uasLogReader, // UasLogReader uasLogReader,
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel+2); // final int debugLevel)
if (debugLevel > -4){
System.out.println("3. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
}
if (model_directory == null) { String [][] video_list = new String[1][];
// TODO: Save continuation after failure not to retry each run int [][] widths_list = new int [1][];
System.out.println("Failed to build sequence for series "+ref_index); int ref_index = -1; // -1 - last
if (start_ref_pointers[0] < (min_num_scenes-1)) { int [] start_ref_pointers = new int[2]; //{earlist, reference} - reference may be center
boolean first_in_series = true;
// Process UAS logs
UasLogReader uasLogReader = null;
String uas_log_path = quadCLT_main.correctionsParameters.getUasLogsPath();
System.out.println("Using UAS log file: "+uas_log_path);
if ((uas_log_path != null) && (uas_log_path.length() > 0)) {
uasLogReader = new UasLogReader(uas_log_path, quadCLT_main.correctionsParameters.cuasUasTimeStamp, null, quadCLT_main);
uasLogReader.setCameraATR(quadCLT_main.correctionsParameters.cuasCameraATR);
uasLogReader.setUASHomeNed(quadCLT_main.correctionsParameters.cuasSetHome? quadCLT_main.correctionsParameters.cuasUASHome : null);
}
if (debugLevel > -4) {
System.out.println("cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
}
while ((ref_index < 0) || ((ref_index + 1) >= min_num_scenes)) {
String model_directory = opticalFlow.buildSeries(
(pathFirstLast != null), //boolean batch_mode,
first_in_series, // boolean first_in_series,
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
ref_index, // int ref_index, // -1 - last
clt_parameters, // CLTParameters clt_parameters,
debayerParameters, // EyesisCorrectionParameters.DebayerParameters debayerParameters,
colorProcParameters, // ColorProcParameters colorProcParameters,
channelGainParameters, // CorrectionColorProc.ColorGainsParameters channelGainParameters,
rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters,
equirectangularParameters, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
properties, // Properties properties,
reset_from_extrinsics, // boolean reset_from_extrinsics,
video_list, // String [][] video_list, // null or list of generated avi or webm paths
widths_list,
start_ref_pointers, // int [] start_ref_pointers,
cuas_centers, // String [] cuas_centers, // [0] - cumulative input, [1] - cumulative output
// processing UAS logs
uasLogReader, // UasLogReader uasLogReader,
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel+2); // final int debugLevel)
if (debugLevel > -4){
System.out.println("3. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
}
if (model_directory == null) {
// TODO: Save continuation after failure not to retry each run
System.out.println("Failed to build sequence for series "+ref_index);
if (start_ref_pointers[0] < (min_num_scenes-1)) {
break;
}
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
}
if ((start_ref_pointers[0]==0) && (start_ref_pointers[1]==0)) { // bail out for debug
System.out.println("\n ----- PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+") ABORTED in "+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_seq),3)+" sec ("+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec from the overall start\n");
break; break;
} }
ref_index = start_ref_pointers[0]; // continue from the same attached to the previous reference first_in_series = false; // at least once success in this series
System.out.println("Continue from index "+ref_index); System.out.println("adding to video_sets_list start="+start_ref_pointers[0]+", end="+ref_index); // start_ref_pointers[1]);
continue; // and go to the to next scene sequence from the list // if ((video_list != null) && (video_list.length>0) && (video_list[0] == null)) {
} // video_list[0]= new String[0];
if ((start_ref_pointers[0]==0) && (start_ref_pointers[1]==0)) { // bail out for debug // }
System.out.println("\n ----- PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+") ABORTED in "+ for (int i= 0; i < video_list[0].length; i++) {
System.out.println(i+": "+video_list[0][i]+", "+widths_list[0][i]);
}
video_sets_list.add(new VideoSet(
video_list[0], // String [] paths,
widths_list[0], // int [] stereo_widths,
start_ref_pointers[0], // int earliest_scene,
ref_index)); // start_ref_pointers[1])); // int reference_scene);
String series_action = (start_ref_pointers[0] < (min_num_scenes-1))?"is FINISHED ":("will continue down from scene "+(start_ref_pointers[0]));
System.out.println("\n ----- PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+") "+series_action+" in "+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_seq),3)+" sec ("+ IJ.d2s(0.000000001*(System.nanoTime()-start_time_seq),3)+" sec ("+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec from the overall start\n"); IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec from the overall start\n");
break;
}
first_in_series = false; // at least once success in this series
System.out.println("adding to video_sets_list start="+start_ref_pointers[0]+", end="+ref_index); // start_ref_pointers[1]);
// if ((video_list != null) && (video_list.length>0) && (video_list[0] == null)) {
// video_list[0]= new String[0];
// }
for (int i= 0; i < video_list[0].length; i++) {
System.out.println(i+": "+video_list[0][i]+", "+widths_list[0][i]);
}
video_sets_list.add(new VideoSet(
video_list[0], // String [] paths,
widths_list[0], // int [] stereo_widths,
start_ref_pointers[0], // int earliest_scene,
ref_index)); // start_ref_pointers[1])); // int reference_scene);
String series_action = (start_ref_pointers[0] < (min_num_scenes-1))?"is FINISHED ":("will continue down from scene "+(start_ref_pointers[0]));
System.out.println("\n ----- PROCESSING SCENE SEQUENCE "+nseq+" (last is "+(num_seq-1)+") "+series_action+" in "+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_seq),3)+" sec ("+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec from the overall start\n");
// will open dialog if does not exist
String linkedModelsDirectory = quadCLT_main.correctionsParameters.selectLinkedModelsDirectory(true,true);
if ((linkedModelsDirectory != null) && (linkedModelsDirectory.length() > 0)) {
Path pathAbsolute = Paths.get(model_directory);
Path pathBase = Paths.get(linkedModelsDirectory);
Path pathRelative = pathBase.relativize(pathAbsolute);
File linkDir = new File(linkedModelsDirectory);
linkDir.mkdirs();
File link = new File(linkDir, pathAbsolute.getFileName().toString());
if (link.exists()) {
link.delete();
}
Files.createSymbolicLink(link.toPath(), pathRelative);
}
if ((cuas_centers != null) && (cuas_centers[1] != null) && (cuas_centers[1].length()>0)) {
String parent_dir = cuas_centers[1];
if (parent_dir.endsWith(Prefs.getFileSeparator())) {
parent_dir = parent_dir.substring(0, parent_dir.length()-1);
}
int ver_sep = parent_dir.lastIndexOf(Prefs.getFileSeparator());
String parent_top_dir = parent_dir.substring(0,ver_sep);
// will open dialog if does not exist // will open dialog if does not exist
String linkedCentersDirectory = quadCLT_main.correctionsParameters.selectLinkedCentersDirectory(true,true); String linkedModelsDirectory = quadCLT_main.correctionsParameters.selectLinkedModelsDirectory(true,true);
if ((linkedCentersDirectory != null) && (linkedCentersDirectory.length() > 0)) { if ((linkedModelsDirectory != null) && (linkedModelsDirectory.length() > 0)) {
// Path pathAbsolute = Paths.get(model_directory); Path pathAbsolute = Paths.get(model_directory);
Path pathAbsolute = Paths.get(parent_top_dir); // cuas_centers[1]); Path pathBase = Paths.get(linkedModelsDirectory);
Path pathBase = Paths.get(linkedCentersDirectory);
Path pathRelative = pathBase.relativize(pathAbsolute); Path pathRelative = pathBase.relativize(pathAbsolute);
File linkDir = new File(linkedCentersDirectory); File linkDir = new File(linkedModelsDirectory);
linkDir.mkdirs(); linkDir.mkdirs();
File link = new File(linkDir, pathAbsolute.getFileName().toString()); File link = new File(linkDir, pathAbsolute.getFileName().toString());
if (link.exists()) { if (link.exists()) {
link.delete(); link.delete();
} }
Files.createSymbolicLink(link.toPath(), pathRelative); Files.createSymbolicLink(link.toPath(), pathRelative);
if (debugLevel > -4){ }
System.out.println("createSymbolicLink "+link.toPath()+" -> "+pathRelative); if ((cuas_centers != null) && (cuas_centers[1] != null) && (cuas_centers[1].length()>0)) {
String parent_dir = cuas_centers[1];
if (parent_dir.endsWith(Prefs.getFileSeparator())) {
parent_dir = parent_dir.substring(0, parent_dir.length()-1);
} }
int ver_sep = parent_dir.lastIndexOf(Prefs.getFileSeparator());
String parent_top_dir = parent_dir.substring(0,ver_sep);
// will open dialog if does not exist
String linkedCentersDirectory = quadCLT_main.correctionsParameters.selectLinkedCentersDirectory(true,true);
if ((linkedCentersDirectory != null) && (linkedCentersDirectory.length() > 0)) {
// Path pathAbsolute = Paths.get(model_directory);
Path pathAbsolute = Paths.get(parent_top_dir); // cuas_centers[1]);
Path pathBase = Paths.get(linkedCentersDirectory);
Path pathRelative = pathBase.relativize(pathAbsolute);
File linkDir = new File(linkedCentersDirectory);
linkDir.mkdirs();
File link = new File(linkDir, pathAbsolute.getFileName().toString());
if (link.exists()) {
link.delete();
}
Files.createSymbolicLink(link.toPath(), pathRelative);
if (debugLevel > -4){
System.out.println("createSymbolicLink "+link.toPath()+" -> "+pathRelative);
}
}
// cuas_centers[0] = cuas_centers[1];
// cuas_centers[1] = "";
} }
// cuas_centers[0] = cuas_centers[1];
// cuas_centers[1] = "";
} if (start_ref_pointers[0] < (min_num_scenes-1)) {
break;
}
if (start_ref_pointers[0] < (min_num_scenes-1)) { ref_index = start_ref_pointers[overlap_sequences? 1 : 0]; // continue from the same attached to the previous reference
break; } // while ((ref_index < 0) || ((ref_index + 1) >= min_num_scenes)) {
if ((cuas_centers != null) && (cuas_centers[1] != null) && (cuas_centers[1].length()>0)) {
cuas_centers[0] = cuas_centers[1];
cuas_centers[1] = "";
if (debugLevel > -4){
System.out.println("4. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null"));
}
} }
ref_index = start_ref_pointers[overlap_sequences? 1 : 0]; // continue from the same attached to the previous reference
} // while ((ref_index < 0) || ((ref_index + 1) >= min_num_scenes)) {
if ((cuas_centers != null) && (cuas_centers[1] != null) && (cuas_centers[1].length()>0)) {
cuas_centers[0] = cuas_centers[1];
cuas_centers[1] = "";
if (debugLevel > -4){ if (debugLevel > -4){
System.out.println("4. 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"));
} }
} // for (int nseq = 0; nseq < num_seq; nseq++) {
} // combine videos if generated
if (debugLevel > -4){ if ((video_sets_list.size() > 1) &&
System.out.println("5. cuas_centers="+((cuas_centers != null)?("[\""+cuas_centers[0]+"\",\""+cuas_centers[1]+"\"]"):"null")); (video_sets_list.get(0).getVideoPaths() != null) &&
} (video_sets_list.get(0).getVideoPaths().length > 0)) {
} // for (int nseq = 0; nseq < num_seq; nseq++) { // need to sort first video_sets_list!
// combine videos if generated Collections.sort(video_sets_list, new Comparator<VideoSet>() {
if ((video_sets_list.size() > 1) && @Override
(video_sets_list.get(0).getVideoPaths() != null) && public int compare(VideoSet lhs, VideoSet rhs) {
(video_sets_list.get(0).getVideoPaths().length > 0)) { // -1 - less than, 1 - greater than, 0 - equal, not inverted for ascending disparity
// need to sort first video_sets_list! return lhs.getVideoPaths()[0].compareTo(rhs.getVideoPaths()[0]);
}
Collections.sort(video_sets_list, new Comparator<VideoSet>() { });
@Override // if ((video_lists.length > 1) && (video_lists[0] != null) && (video_lists[0].length > 1)) { // do not combine if single sequence or no videos
public int compare(VideoSet lhs, VideoSet rhs) { concat_videos: {
// -1 - less than, 1 - greater than, 0 - equal, not inverted for ascending disparity System.out.println("Generating "+(video_sets_list.get(0).getVideoPaths().length)+" combined video files.");
return lhs.getVideoPaths()[0].compareTo(rhs.getVideoPaths()[0]); String videoDirectory = quadCLT_main.correctionsParameters.selectVideoDirectory(true,true);
} if (videoDirectory == null) {
}); break concat_videos;
// if ((video_lists.length > 1) && (video_lists[0] != null) && (video_lists[0].length > 1)) { // do not combine if single sequence or no videos }
concat_videos: { File video_dir = new File (videoDirectory);
System.out.println("Generating "+(video_sets_list.get(0).getVideoPaths().length)+" combined video files."); video_dir.mkdirs(); // Should already exist actually
String videoDirectory = quadCLT_main.correctionsParameters.selectVideoDirectory(true,true); for (int nvideo = 0; nvideo < video_sets_list.get(0).getVideoPaths().length; nvideo++) {
if (videoDirectory == null) { // get name with <ts_sec_first>-<ts_sec_last>
break concat_videos; // String spath0 = video_lists[0][nvideo];
} String name0 = Paths.get(video_sets_list.get(0).getVideoPaths()[nvideo]).getFileName().toString();
File video_dir = new File (videoDirectory); String name1 = Paths.get(video_sets_list.get(video_sets_list.size()-1).getVideoPaths()[nvideo]).getFileName().toString();
video_dir.mkdirs(); // Should already exist actually System.out.println("name0= "+name0);
for (int nvideo = 0; nvideo < video_sets_list.get(0).getVideoPaths().length; nvideo++) { System.out.println(" name1="+name1);
// get name with <ts_sec_first>-<ts_sec_last> String ts_sec0=name0.substring(0,name0.indexOf("_")); // seconds of the first timestamp
// String spath0 = video_lists[0][nvideo]; String ts_sec1=name1.substring(0,name1.indexOf("_")); // seconds of the last timestamp
String name0 = Paths.get(video_sets_list.get(0).getVideoPaths()[nvideo]).getFileName().toString(); String suffix0 = name0.substring(name0.indexOf("-")); // Skip timestamp
String name1 = Paths.get(video_sets_list.get(video_sets_list.size()-1).getVideoPaths()[nvideo]).getFileName().toString(); String combo_video_name = ts_sec0+"-"+ts_sec1+suffix0;
System.out.println("name0= "+name0); String concat_list_name = combo_video_name.substring(0, combo_video_name.lastIndexOf("."))+".list";
System.out.println(" name1="+name1); File list_to_concat = new File (video_dir,concat_list_name);
String ts_sec0=name0.substring(0,name0.indexOf("_")); // seconds of the first timestamp // delete if exists
String ts_sec1=name1.substring(0,name1.indexOf("_")); // seconds of the last timestamp if (list_to_concat.exists()) {
String suffix0 = name0.substring(name0.indexOf("-")); // Skip timestamp list_to_concat.delete();
String combo_video_name = ts_sec0+"-"+ts_sec1+suffix0; }
String concat_list_name = combo_video_name.substring(0, combo_video_name.lastIndexOf("."))+".list";
File list_to_concat = new File (video_dir,concat_list_name); PrintWriter writer = new PrintWriter(list_to_concat, "UTF-8");
// delete if exists int this_stereo_width = 0;
if (list_to_concat.exists()) { int num_segments=0;
list_to_concat.delete(); for (int i = 0; i <video_sets_list.size(); i++) {
} if (video_sets_list.size() >= nvideo) {
if ((new File(video_sets_list.get(i).getVideoPaths()[nvideo])).exists()) {
PrintWriter writer = new PrintWriter(list_to_concat, "UTF-8"); writer.println("file '"+video_sets_list.get(i).getVideoPaths()[nvideo]+"'");
int this_stereo_width = 0; if (stereo_pad) {
int num_segments=0; this_stereo_width = video_sets_list.get(i).getStereoWidths()[nvideo];
for (int i = 0; i <video_sets_list.size(); i++) { }
if (video_sets_list.size() >= nvideo) { num_segments++;
if ((new File(video_sets_list.get(i).getVideoPaths()[nvideo])).exists()) { } else {
writer.println("file '"+video_sets_list.get(i).getVideoPaths()[nvideo]+"'"); System.out.println("Missing video segment: "+video_sets_list.get(i).getVideoPaths()[nvideo]);
if (stereo_pad) { }
this_stereo_width = video_sets_list.get(i).getStereoWidths()[nvideo]; } else {
} System.out.println("Specific video segment "+i+":"+nvideo+" is missing, skipping");
num_segments++; }
} else { }
System.out.println("Missing video segment: "+video_sets_list.get(i).getVideoPaths()[nvideo]); writer.close();
} if (num_segments == 0) {
} else { System.out.println("No segments found for "+combo_video_name);
System.out.println("Specific video segment "+i+":"+nvideo+" is missing, skipping"); continue;
} }
}
writer.close(); if (this_stereo_width > 0) {
if (num_segments == 0) { String combo_base = combo_video_name.substring(0,combo_video_name.lastIndexOf(".")) ;
System.out.println("No segments found for "+combo_video_name); String combo_ext = combo_video_name.substring(combo_video_name.lastIndexOf(".")) ;
continue; combo_video_name = combo_base+"-"+stereo_phone_width+"mm"+combo_ext;
} }
File video_out = new File (video_dir,combo_video_name);
if (this_stereo_width > 0) { if (video_out.exists()) {
String combo_base = combo_video_name.substring(0,combo_video_name.lastIndexOf(".")) ; video_out.delete();
String combo_ext = combo_video_name.substring(combo_video_name.lastIndexOf(".")) ; }
combo_video_name = combo_base+"-"+stereo_phone_width+"mm"+combo_ext; double pts_scale = clt_parameters.imp.video_fps/clt_parameters.imp.sensor_fps;
} String shellCommand;
File video_out = new File (video_dir,combo_video_name); //ffmpeg -i input_file.mkv -c copy -metadata:s:v:0 stereo_mode=1 output_file.mkv
if (video_out.exists()) { //https://ffmpeg.org/ffmpeg-formats.html
video_out.delete(); //ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
} //anaglyph_cyan_red
double pts_scale = clt_parameters.imp.video_fps/clt_parameters.imp.sensor_fps; if (this_stereo_width > 0) {// add padding to stereo video
String shellCommand; int padded_width= 16* ( (int) Math.round((this_stereo_width + stereo_gap) * stereo_phone_width/stereo_intereye/32));
//ffmpeg -i input_file.mkv -c copy -metadata:s:v:0 stereo_mode=1 output_file.mkv shellCommand = String.format(
//https://ffmpeg.org/ffmpeg-formats.html "ffmpeg -y -f concat -safe 0 -i %s -r 60 -vf pad=width=%d:height=0:x=-1:y=-1:color=black,setpts=%f*PTS -b:v %fM -crf %d -c %s %s",
//ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm list_to_concat.toString(), padded_width, pts_scale, video_bitrate_m, video_crf_combo, video_codec_combo, video_out.toString());
//anaglyph_cyan_red } else {
if (this_stereo_width > 0) {// add padding to stereo video shellCommand = String.format("ffmpeg -y -f concat -safe 0 -i %s -r 60 -vf setpts=%f*PTS -b:v %fM -crf %d -c %s %s",
int padded_width= 16* ( (int) Math.round((this_stereo_width + stereo_gap) * stereo_phone_width/stereo_intereye/32)); list_to_concat.toString(), pts_scale, video_bitrate_m, video_crf_combo, video_codec_combo, video_out.toString());
shellCommand = String.format( }
"ffmpeg -y -f concat -safe 0 -i %s -r 60 -vf pad=width=%d:height=0:x=-1:y=-1:color=black,setpts=%f*PTS -b:v %fM -crf %d -c %s %s",
list_to_concat.toString(), padded_width, pts_scale, video_bitrate_m, video_crf_combo, video_codec_combo, video_out.toString()); Process p = null;
} else { int exit_code = -1;
shellCommand = String.format("ffmpeg -y -f concat -safe 0 -i %s -r 60 -vf setpts=%f*PTS -b:v %fM -crf %d -c %s %s", System.out.println("Will run shell command: \""+shellCommand+"\"");
list_to_concat.toString(), pts_scale, video_bitrate_m, video_crf_combo, video_codec_combo, video_out.toString()); System.out.println("This may take a while, please wait ...");
} try {
p = Runtime.getRuntime().exec(
Process p = null; shellCommand,
int exit_code = -1; null, // env
System.out.println("Will run shell command: \""+shellCommand+"\""); video_dir // working dir - needed if "-report" is added to ffmpeg command
System.out.println("This may take a while, please wait ..."); );
try { } catch (IOException e) {
p = Runtime.getRuntime().exec( System.out.println("Failed shell command: \""+shellCommand+"\"");
shellCommand, }
null, // env
video_dir // working dir - needed if "-report" is added to ffmpeg command if (p != null) {
); p.waitFor();
} catch (IOException e) { exit_code = p.exitValue();
System.out.println("Failed shell command: \""+shellCommand+"\""); }
}
System.out.println("Ran shell command: \""+shellCommand+"\" -> ");
if (p != null) { if ((exit_code != 0) || !video_out.exists()) {
p.waitFor(); System.out.println("Failed to create : \""+video_out.toString()+"\"");
exit_code = p.exitValue(); }
} }
System.out.println("Ran shell command: \""+shellCommand+"\" -> ");
if ((exit_code != 0) || !video_out.exists()) {
System.out.println("Failed to create : \""+video_out.toString()+"\"");
}
} }
} else {
System.out.println("No combined videos are generated (<2 videos).");
} }
} else { break; // case 0 :
System.out.println("No combined videos are generated (<2 videos)."); case 1:
} CuasMultiSeries cuasMultiSeries = new CuasMultiSeries(
clt_parameters, // CLTParameters clt_parameters,
quadCLT_main, // QuadCLT quadCLT_main,
quadCLT_main.correctionsParameters.linkedCenters,
quadCLT_main.correctionsParameters.x3dModelVersion);
// CuasMultiSeries (String path)
cuasMultiSeries.processGlobals();
break;
} // switch (cuas_proc_mode) {
System.out.println("\n\n\nPROCESSING OF "+num_seq+" SCENE SEQUENCES is FINISHED in "+ System.out.println("\n\n\nPROCESSING OF "+num_seq+" SCENE SEQUENCES is FINISHED in "+
IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec."); IJ.d2s(0.000000001*(System.nanoTime()-start_time_all),3)+" sec.");
......
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