Commit 90e3e80a authored by Andrey Filippov's avatar Andrey Filippov

Refactoring

parent 5db80b77
......@@ -167,13 +167,22 @@ import ij.process.ImageProcessor;
String [] frame_titles, // frame titles or null
boolean show) {
int num_frames = pixels.length;
int num_slices = pixels[0].length;
int num_slices = 0; // pixels[0].length;
for (int i=0; i < num_frames; i++) {
if (pixels[i] != null) {
num_slices = pixels[i].length;
break;
}
}
if (num_slices == 0) {
return null;
}
double [][] dpixels = new double [num_frames*num_slices][];
for (int f = 0; f < num_frames; f++) {
for (int s = 0; s < num_slices; s ++) {
int indx = s + f * num_slices;
dpixels[indx] = pixels[f][s];
dpixels[indx] = (pixels[f] != null) ? pixels[f][s] : null;
}
}
String [] combo_titles;
......@@ -211,7 +220,7 @@ import ij.process.ImageProcessor;
dpixels, // double[][] pixels,
width, // int width,
height, // int height,
pixels[0].length, // int slices,
num_slices, // int slices,
title, // String title,
combo_titles, // String [] titles);
show); // boolean show
......
This source diff could not be displayed because it is too large. You can view the blob instead.
package com.elphel.imagej.cuas;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.tileprocessor.ImageDtt;
......@@ -35,32 +36,75 @@ public class CuasMotionLMA {
public static final int INDX_LEN = INDX_Y0+1;
// result vector indices
public static final int RSLT_X = 0;
public static final int RSLT_Y = 1;
public static final int RSLT_A = 2;
public static final int RSLT_R0 = 3;
public static final int RSLT_R1 = 4;
public static final int RSLT_K = 5;
public static final int RSLT_C = 6;
public static final int RSLT_RMS = 7;
public static final int RSLT_RMS_A = 8;
public static final int RSLT_MAX2A = 9;
public static final int RSLT_ITERS =10;
public static final int RSLT_FAIL = 11;
public static final int RSLT_X = 0;
public static final int RSLT_Y = 1;
public static final int RSLT_A = 2;
public static final int RSLT_R0 = 3;
public static final int RSLT_R1 = 4;
public static final int RSLT_K = 5;
public static final int RSLT_C = 6;
public static final int RSLT_RMS = 7;
public static final int RSLT_RMS_A = 8;
public static final int RSLT_MAX2A = 9;
public static final int RSLT_ITERS = 10;
public static final int RSLT_CENT_X = 11;
public static final int RSLT_CENT_Y = 12;
public static final int RSLT_CENT_MX= 13;
public static final int RSLT_CENT_F = 14;
public static final int RSLT_VX = 15;
public static final int RSLT_VY = 16;
public static final int RSLT_VSTR = 17;
public static final int RSLT_VFRAC = 18;
public static final int RSLT_BX = 19;
public static final int RSLT_BY = 20; // RSLT_BX+1;
public static final int RSLT_AX = 21; // RSLT_BX+2;
public static final int RSLT_AY = 22; // RSLT_BX+3;
public static final int RSLT_MISMATCH_BEFORE = 23;
public static final int RSLT_MISMATCH_AFTER = 24; // RSLT_MISMATCH_BEFORE+1;
public static final int RSLT_MISMATCH_DIRS= 25;
public static final int RSLT_MSCORE = 26;
public static final int RSLT_QA = 27;
public static final int RSLT_QRMS = 28;
public static final int RSLT_QRMS_A = 29;
public static final int RSLT_QMATCH = 30;
public static final int RSLT_QCENTER = 31;
public static final int RSLT_QSCORE = 32;
public static final int RSLT_WHEN = 33;
public static final int RSLT_FAIL = 34;
public static final int RSLT_LEN = RSLT_FAIL+1;
public static final String [] LMA_TITLES = {"X-OFFS","Y-OFFS", "AMPLITUDE","RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS","FAILURE"};
public static final String [] LMA_TITLES =
{"X-OFFS","Y-OFFS", "AMPLITUDE", "RADIUS","RAD_POS", "OVERSHOOT","OFFSET","RMSE","RMSE/A","MAX2A","ITERATIONS",
"Centr-X","Centr-Y","Centr-max","Centr-frac",
"Vx", "Vy", "V-conf","V-frac", // from motion vectors
"X-before", "Y-before","X-after","Y-after", // from getHalfBeforeAfterPixXY()
"ERR-BEFORE", "ERR-AFTER", "BA-DIRS", // before dir + 16*after dir
"*MOTION-SCORE",
"*Q-AMPL","*Q-RMSE","*Q-RMSE/A","*Q-MATCH","*Q-CENTER","*Q-SCORE",
"WHEN", "FAILURE"};
public static final int FAIL_NONE = 0;
public static final int FAIL_A_LOW = 1; // amplitude is too low
public static final int FAIL_ACENT = 2; // ratio of maximal pixel to amplitude is too low
public static final int FAIL_RMSE = 3; // RMSE is too high
public static final int FAIL_RMSE_R = 4; // BOTH RMSE is not sufficient and RMSE/A is too high
public static final int FAIL_R0_HIGH = 5; // Full radius (including negative overshoot) is too high
public static final int FAIL_R1_LOW = 6; // Inner (positive) peak radius is too low
public static final int FAIL_K_LOW = 7; // Overshoot is too low (not used, it can be down to 0)
public static final int FAIL_K_HIGH = 8; // Overshoot is too high
public static final int FAIL_FAR = 9; // Peak is too far from the center
public static final int FAIL_HORIZON = 10; // Peak is below horizon
public static final int FAIL_CENT_STR = 1; // centroid amplitude is too low
public static final int FAIL_CENT_FRAC = 2; // Centroid fraction (energy in the peak fraction of all) is too low
public static final int FAIL_LMA = 3; // LMA fail to converge
public static final int FAIL_A_LOW = 4; // amplitude is too low
public static final int FAIL_ACENT = 5; // ratio of maximal pixel to amplitude is too low
public static final int FAIL_RMSE = 6; // RMSE is too high
public static final int FAIL_RMSE_R = 7; // BOTH RMSE is not sufficient and RMSE/A is too high
public static final int FAIL_R0_HIGH = 8; // Full radius (including negative overshoot) is too high
public static final int FAIL_R1_LOW = 9; // Inner (positive) peak radius is too low
public static final int FAIL_K_LOW = 10; // Overshoot is too low (not used, it can be down to 0)
public static final int FAIL_K_HIGH = 11; // Overshoot is too high
public static final int FAIL_FAR = 12; // Peak is too far from the center
public static final int FAIL_HORIZON = 13; // Peak is below horizon
public static final int FAIL_MISMATCH = 14; // Mismatch on both ends is too high
private int width;
private double [][] window;
......@@ -194,21 +238,42 @@ public class CuasMotionLMA {
return initial_rms[0];
}
public double [] getResult() {
public static double [] getEmpty() {
double rslt[] = new double [RSLT_LEN];
rslt[RSLT_X] = getCenter()[0];
rslt[RSLT_Y] = getCenter()[1];
rslt[RSLT_A] = getA();
rslt[RSLT_R0] = getR0();
rslt[RSLT_R1] = getR0() / ((getK()>1) ? getK() : 1.0);
rslt[RSLT_K] = getK();
rslt[RSLT_C] = getC();
rslt[RSLT_RMS] = getRMS();
rslt[RSLT_RMS_A] = getRMS()/getA();
rslt[RSLT_MAX2A] = max_val/getA(); // ratio of maximal value to LMA amplitude
rslt[RSLT_ITERS] = getIters();
Arrays.fill(rslt, Double.NaN);
return rslt;
}
public double [] getResult() {
double rslt[] = getEmpty();
setResult(rslt);
return rslt;
}
public void setResult(double [] rslt) {
rslt[RSLT_X] = getCenter()[0];
rslt[RSLT_Y] = getCenter()[1];
rslt[RSLT_A] = getA();
rslt[RSLT_R0] = getR0();
rslt[RSLT_R1] = getR0() / ((getK()>1) ? getK() : 1.0);
rslt[RSLT_K] = getK();
rslt[RSLT_C] = getC();
rslt[RSLT_RMS] = getRMS();
rslt[RSLT_RMS_A] = getRMS()/getA();
rslt[RSLT_MAX2A] = max_val/getA(); // ratio of maximal value to LMA amplitude
rslt[RSLT_ITERS] = getIters();
return;
}
public static void copyMotion(
double [] dst,
double [] src) {
dst[RSLT_VX] = src[RSLT_VX];
dst[RSLT_VY] = src[RSLT_VY];
dst[RSLT_VSTR] = src[RSLT_VSTR];
dst[RSLT_VFRAC] = src[RSLT_VFRAC];
}
public double [] getCenter(){
return new double [] {full_vector[INDX_X0] - width/2, full_vector[INDX_Y0]-width/2};
......
......@@ -4723,20 +4723,22 @@ public class GpuQuad{ // quad camera description
* and temporal distance from the middle frame. Accumulation uses the feature developed for the
* thermal camera motion blur correction that allows accumulation in the transform domain. It only
* works with the negative scales, so the result will be a negative image in the TD.
* @param vector_field sparse array of motion vectors (may be longer, only Vx and Vy used). Null elements
* @param targets_array sparse array of motion vectors (may be longer, only Vx and Vy used). Null elements
* are allowed, they will be skipped, resultin in null TpTask elements.
* @param offset_scale multiply all vectors by this value when calculating pixel offsets
* @param magnitude_scale Scale data for accumulation (here positive, will be negated). If 0 - will use scale=1.0 (no accumulation)
* @param index_vx - index of vx in the targets_array[tile] array
* @param image_width image width in tiles (80 for 640-wide images).
* @return condensed array of TpTask
*/
public static TpTask [] setRectilinearMovingTasks(
final double [][] vector_field,
final double [][] targets_array,
final double offset_scale,
final double magnitude_scale,
final int index_vx,
final int tilesX) {
final float fmagnitude_scale = (magnitude_scale==0)? 1.0f : ((float) -magnitude_scale);
final int tiles = vector_field.length;
final int tiles = targets_array.length;
final TpTask [] tp_tasks_full = new TpTask [tiles];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(00);
......@@ -4747,11 +4749,11 @@ public class GpuQuad{ // quad camera description
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (vector_field[nTile] != null){
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (targets_array[nTile] != null){
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;;
double dx = vector_field[nTile][0]*offset_scale;
double dy = vector_field[nTile][1]*offset_scale;
double dx = targets_array[nTile][index_vx + 0]*offset_scale;
double dy = targets_array[nTile][index_vx + 1]*offset_scale;
double [] cxy0 = { // uniform coordinates for the center scene
(tileX + 0.5) * GPUTileProcessor.DTT_SIZE,
(tileY + 0.5) * GPUTileProcessor.DTT_SIZE};
......
......@@ -717,7 +717,7 @@ min_str_neib_fpn 0.35
public boolean cuas_half_step = true; // half step (=cuas_corr_offset/2) when scanning for motion
public int cuas_max_range = 2; // how far to extend local max: 1 3x3 neighbors, 2 - 5x5 neighbs
public int cuas_num_cycles = 10; // number of cycles of testing and removing bad targets
public int cuas_num_cycles = 25; // number of cycles of testing and removing bad targets // will get out earlier
// boosting weight of moving targets
public double cuas_speed_min = 0.0; // minimal pixels per range (per cuas_corr_offset)
......@@ -767,10 +767,12 @@ min_str_neib_fpn 0.35
public double cuas_score_lma = 0.0; // minimal score for the target LMA
public double cuas_factor_lim = 5.0; // limit each individual score factor
public double cuas_factor_pow = 1.0; // raise score factor to this power before combining
public double [] cuas_score_coeff = {1.0, 0.5, 1.0}; //weights of amplitude, RMSE and RMSE/amplitude
public double [] cuas_score_coeff = {1.0, 0.2, 1.0, 1.0, 1.0}; //weights of amplitude, RMSE and RMSE/amplitude
public boolean cuas_isolated = true; // remove targets that do not have neighbors before/after
public boolean cuas_remove_2seq = true; // Remove short target sequences consisting of 2 consecutive key frames
public double cuas_max_mismatch = 2.0; // maximal position error between consecutive scene sequences
public boolean cuas_fail_mismatch = false; // fail high mismatch early
public boolean cuas_ignore_mismatch = false; // calculate mismatch but do not remove
public boolean cuas_by_horizon = true; // remove targets that are below horizon
......@@ -813,6 +815,7 @@ min_str_neib_fpn 0.35
public boolean cuas_debug = true; // save debug images (and show them if not in batch mode)
public boolean cuas_step_debug = true; // save debug images during per-step cuas recalculation (and show them if not in batch mode)
public boolean cuas_save_stats = true; // Save target statistics data to find out which test failed and when (or when tile was found good)
public boolean cuas_target_debug = false; // save debug images during per-step cuas recalculation (and show them if not in batch mode)
public boolean cuas_overwrite = false; // overwrite num_orient and num_accum
public int cuas_num_orient = 2; // initial value for num_orient
......@@ -2344,21 +2347,21 @@ min_str_neib_fpn 0.35
gd.addNumericField("Raise score factor to this power", this.cuas_factor_pow, 5,8,"",
"Raise each score factor to this power before combining them.");
gd.addStringField ("Score factors weights", IntersceneMatchParameters.doublesToString(cuas_score_coeff), 80,
"Relative importance of LMA amplitude, RMSE and RMSE/ampitude.");
"Relative importance of LMA amplitude, RMSE and RMSE/ampitude, before/after, far-from-edges.");
gd.addMessage("=== Post-processing targets filtering ===");
gd.addCheckbox ("Remove single-frame targets", this.cuas_isolated,
"Remove targets that do not have neighbors before/afte.");
gd.addCheckbox ("Remove pairs too", this.cuas_remove_2seq,
"Remove short target sequences consisting of 2 consecutive key frames.");
gd.addNumericField("Remove by mismatch", this.cuas_max_mismatch, 5,8,"pix",
"Maximal position error between consecutive scene sequences.");
gd.addCheckbox ("Fail mismatch early", this.cuas_fail_mismatch,
"Fail after score calculation if there is not match both before and after.");
gd.addCheckbox ("Ignore mismatch", this.cuas_ignore_mismatch,
"Calculate mismatch, but keep targets for debugging (see cuas_target_debug).");
gd.addCheckbox ("Filter by horizon", this.cuas_by_horizon,
"Remove targets that are below the horizon.");
gd.addNumericField("Pixel Y of the horizon", this.cuas_horizon, 5,8,"pix",
......@@ -2435,6 +2438,8 @@ min_str_neib_fpn 0.35
"Save CUAS-related debug images and show them in non-batch mode.");
gd.addCheckbox ("Save/show debug images for each tuning step",this.cuas_step_debug,
"Save CUAS-related debug images during per-step cuas recalculation and show them in non-batch mode.");
gd.addCheckbox ("Save target statistics", this.cuas_save_stats,
" Save target statistics data to find out which test failed and when (or when tile was found good).");
gd.addCheckbox ("Add debug to the target text", this.cuas_target_debug,
"Add additional debug text to the .");
......@@ -3444,10 +3449,12 @@ min_str_neib_fpn 0.35
this.cuas_score_lma = gd.getNextNumber();
this.cuas_factor_lim = gd.getNextNumber();
this.cuas_factor_pow = gd.getNextNumber();
this.cuas_score_coeff = IntersceneMatchParameters. StringToDoubles(gd.getNextString(), CuasMotion.IMPORTANCE_LENGTH);
this.cuas_score_coeff = IntersceneMatchParameters.StringToDoubles(gd.getNextString(), cuas_score_coeff);
this.cuas_isolated = gd.getNextBoolean();
this.cuas_remove_2seq = gd.getNextBoolean();
this.cuas_max_mismatch= gd.getNextNumber();
this.cuas_fail_mismatch = gd.getNextBoolean();
this.cuas_ignore_mismatch = gd.getNextBoolean();
this.cuas_by_horizon = gd.getNextBoolean();
......@@ -3493,6 +3500,7 @@ min_str_neib_fpn 0.35
this.cuas_debug = gd.getNextBoolean();
this.cuas_step_debug = gd.getNextBoolean();
this.cuas_save_stats = gd.getNextBoolean();
this.cuas_target_debug = gd.getNextBoolean();
this.cuas_overwrite = gd.getNextBoolean();
......@@ -4432,7 +4440,9 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_isolated", this.cuas_isolated+""); // boolean
properties.setProperty(prefix+"cuas_remove_2seq", this.cuas_remove_2seq+""); // boolean
properties.setProperty(prefix+"cuas_max_mismatch", this.cuas_max_mismatch+""); // double
properties.setProperty(prefix+"cuas_fail_mismatch", this.cuas_fail_mismatch+""); // boolean
properties.setProperty(prefix+"cuas_ignore_mismatch", this.cuas_ignore_mismatch+"");// boolean
properties.setProperty(prefix+"cuas_by_horizon", this.cuas_by_horizon+""); // boolean
properties.setProperty(prefix+"cuas_horizon", this.cuas_horizon+""); // double
......@@ -4472,6 +4482,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean
properties.setProperty(prefix+"cuas_step_debug", this.cuas_step_debug+""); // boolean
properties.setProperty(prefix+"cuas_save_stats", this.cuas_save_stats+""); // boolean
properties.setProperty(prefix+"cuas_target_debug", this.cuas_target_debug+""); // boolean
properties.setProperty(prefix+"cuas_overwrite", this.cuas_overwrite+""); // boolean
......@@ -5380,10 +5391,12 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_score_lma")!=null) this.cuas_score_lma=Double.parseDouble(properties.getProperty(prefix+"cuas_score_lma"));
if (properties.getProperty(prefix+"cuas_factor_lim")!=null) this.cuas_factor_lim=Double.parseDouble(properties.getProperty(prefix+"cuas_factor_lim"));
if (properties.getProperty(prefix+"cuas_factor_pow")!=null) this.cuas_factor_pow=Double.parseDouble(properties.getProperty(prefix+"cuas_factor_pow"));
if (properties.getProperty(prefix+"cuas_score_coeff")!=null) this.cuas_score_coeff= IntersceneMatchParameters.StringToDoubles(properties.getProperty(prefix+"cuas_score_coeff"),3);
if (properties.getProperty(prefix+"cuas_score_coeff")!=null) this.cuas_score_coeff= IntersceneMatchParameters.StringToDoubles(properties.getProperty(prefix+"cuas_score_coeff"),this.cuas_score_coeff);
if (properties.getProperty(prefix+"cuas_isolated")!=null) this.cuas_isolated=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_isolated"));
if (properties.getProperty(prefix+"cuas_remove_2seq")!=null) this.cuas_remove_2seq=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_remove_2seq"));
if (properties.getProperty(prefix+"cuas_max_mismatch")!=null) this.cuas_max_mismatch=Double.parseDouble(properties.getProperty(prefix+"cuas_max_mismatch"));
if (properties.getProperty(prefix+"cuas_fail_mismatch")!=null) this.cuas_fail_mismatch=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_fail_mismatch"));
if (properties.getProperty(prefix+"cuas_ignore_mismatch")!=null) this.cuas_ignore_mismatch=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_ignore_mismatch"));
if (properties.getProperty(prefix+"cuas_by_horizon")!=null) this.cuas_by_horizon=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_by_horizon"));
......@@ -5424,6 +5437,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug"));
if (properties.getProperty(prefix+"cuas_step_debug")!=null) this.cuas_step_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_step_debug"));
if (properties.getProperty(prefix+"cuas_save_stats")!=null) this.cuas_save_stats=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_save_stats"));
if (properties.getProperty(prefix+"cuas_target_debug")!=null) this.cuas_target_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_target_debug"));
if (properties.getProperty(prefix+"cuas_overwrite")!=null) this.cuas_overwrite=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_overwrite"));
......@@ -6335,7 +6349,9 @@ min_str_neib_fpn 0.35
imp.cuas_score_coeff = this.cuas_score_coeff.clone();
imp.cuas_isolated = this.cuas_isolated;
imp.cuas_remove_2seq = this.cuas_remove_2seq;
imp.cuas_max_mismatch = this.cuas_max_mismatch;
imp.cuas_fail_mismatch = this.cuas_fail_mismatch;
imp.cuas_ignore_mismatch = this.cuas_ignore_mismatch;
imp.cuas_by_horizon = this.cuas_by_horizon;
imp.cuas_horizon = this.cuas_horizon;
......@@ -6373,6 +6389,7 @@ min_str_neib_fpn 0.35
imp.cuas_debug = this.cuas_debug;
imp.cuas_step_debug = this.cuas_step_debug;
imp.cuas_save_stats = this.cuas_save_stats;
imp.cuas_target_debug = this.cuas_target_debug;
imp.cuas_overwrite = this.cuas_overwrite;
......@@ -6878,6 +6895,31 @@ min_str_neib_fpn 0.35
return s;
}
public static double [] StringToDoubles(String s, double [] default_data) {
int len = default_data.length;
StringTokenizer st = new StringTokenizer(s, " \t\n\r\f,");
if (st.countTokens() == 0) {
return null;
}
if (len <= 0) {
len = st.countTokens();
}
double [] data = default_data.clone(); // new double [len];
int i = 0;
while (st.hasMoreTokens() && (i < len)) {
double d = 0;
try {
d = Double.parseDouble(st.nextToken());
} catch(NumberFormatException e){
d = 0;
}
data[i++] = d;
}
return data;
}
public static double [] StringToDoubles(String s, int len) {
StringTokenizer st = new StringTokenizer(s, " \t\n\r\f,");
if (st.countTokens() == 0) {
......@@ -6895,7 +6937,6 @@ min_str_neib_fpn 0.35
} catch(NumberFormatException e){
d = 0;
}
data[i++] = d;
}
return data;
......
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