Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
6dd7be11
Commit
6dd7be11
authored
Aug 02, 2025
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented LMA-based filtering of the moving targets
parent
4342fd2a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1933 additions
and
182 deletions
+1933
-182
ShowDoubleFloatArrays.java
.../java/com/elphel/imagej/common/ShowDoubleFloatArrays.java
+1
-1
CuasMotion.java
src/main/java/com/elphel/imagej/cuas/CuasMotion.java
+1053
-176
CuasMotionLMA.java
src/main/java/com/elphel/imagej/cuas/CuasMotionLMA.java
+691
-0
Correlation2d.java
...n/java/com/elphel/imagej/tileprocessor/Correlation2d.java
+13
-1
IntersceneMatchParameters.java
...lphel/imagej/tileprocessor/IntersceneMatchParameters.java
+175
-4
No files found.
src/main/java/com/elphel/imagej/common/ShowDoubleFloatArrays.java
View file @
6dd7be11
...
...
@@ -1067,7 +1067,7 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
if
(
pslice_titles
!=
null
)
{
pslice_titles
[
0
]
=
slice_l
;
}
double
[][]
file_data
=
ShowDoubleFloatArrays
.
readDoubleArray
(
double
[][]
file_data
=
readDoubleArray
(
imp
,
// ImagePlus imp,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh); // int [] wh)
...
...
src/main/java/com/elphel/imagej/cuas/CuasMotion.java
View file @
6dd7be11
...
...
@@ -95,15 +95,11 @@ public class CuasMotion {
int
framecent
=
180
;
int
corr_offset
=
clt_parameters
.
imp
.
cuas_corr_offset
;
int
corr_pairs
=
clt_parameters
.
imp
.
cuas_corr_pairs
;
// int frame0cent = 210;
// int frame1cent = frame0cent + clt_parameters.imp.cuas_corr_offset;
// int frame_len = clt_parameters.imp.cuas_corr_pairs; // 40;
double
cuas_fat_zero
=
clt_parameters
.
imp
.
cuas_fat_zero
;
double
cuas_cent_radius
=
clt_parameters
.
imp
.
cuas_cent_radius
;
int
cuas_n_recenter
=
clt_parameters
.
imp
.
cuas_n_recenter
;
double
cuas_rstr
=
clt_parameters
.
imp
.
cuas_rstr
;
// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
boolean
smooth
=
clt_parameters
.
imp
.
cuas_smooth
;
// true;
// double rln_neib_rstr = clt_parameters.imp.rln_neib_rstr;
GenericJTabbedDialog
gd
=
new
GenericJTabbedDialog
(
"Motion detect parameters"
);
gd
.
addNumericField
(
"Center frame"
,
framecent
,
0
,
5
,
"frame"
,
"Center frame"
);
...
...
@@ -230,22 +226,47 @@ public class CuasMotion {
CLTParameters
clt_parameters
,
QuadCLT
parentCLT
,
int
debugLevel
)
{
int
corr_offset
=
clt_parameters
.
imp
.
cuas_corr_offset
;
int
corr_pairs
=
clt_parameters
.
imp
.
cuas_corr_pairs
;
double
fat_zero
=
clt_parameters
.
imp
.
cuas_fat_zero
;
double
cent_radius
=
clt_parameters
.
imp
.
cuas_cent_radius
;
int
n_recenter
=
clt_parameters
.
imp
.
cuas_n_recenter
;
double
rstr
=
clt_parameters
.
imp
.
cuas_rstr
;
// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
double
speed_min
=
clt_parameters
.
imp
.
cuas_speed_min
;
double
speed_pref
=
clt_parameters
.
imp
.
cuas_speed_pref
;
double
speed_boost
=
clt_parameters
.
imp
.
cuas_speed_boost
;
boolean
smooth
=
clt_parameters
.
imp
.
cuas_smooth
;
// true;
boolean
half_step
=
clt_parameters
.
imp
.
cuas_half_step
;
// true;
int
max_range
=
clt_parameters
.
imp
.
cuas_max_range
;
int
corr_offset
=
clt_parameters
.
imp
.
cuas_corr_offset
;
int
corr_pairs
=
clt_parameters
.
imp
.
cuas_corr_pairs
;
double
fat_zero
=
clt_parameters
.
imp
.
cuas_fat_zero
;
double
cent_radius
=
clt_parameters
.
imp
.
cuas_cent_radius
;
int
n_recenter
=
clt_parameters
.
imp
.
cuas_n_recenter
;
double
rstr
=
clt_parameters
.
imp
.
cuas_rstr
;
// 0.003; // clt_parameters.imp.rln_sngl_rstr; // FIXME: ADD
double
speed_min
=
clt_parameters
.
imp
.
cuas_speed_min
;
double
speed_pref
=
clt_parameters
.
imp
.
cuas_speed_pref
;
double
speed_boost
=
clt_parameters
.
imp
.
cuas_speed_boost
;
boolean
smooth
=
clt_parameters
.
imp
.
cuas_smooth
;
// true;
boolean
half_step
=
clt_parameters
.
imp
.
cuas_half_step
;
// true;
int
max_range
=
clt_parameters
.
imp
.
cuas_max_range
;
double
target_radius
=
clt_parameters
.
imp
.
cuas_target_radius
;
double
target_strength
=
clt_parameters
.
imp
.
cuas_target_strength
;
double
[][]
target_frac
=
new
double
[
clt_parameters
.
imp
.
cuas_target_frac
.
length
][
2
];
boolean
no_border
=
clt_parameters
.
imp
.
cuas_no_border
;
// true;
// Moving target LMA
double
lma_sigma
=
clt_parameters
.
imp
.
cuas_lma_sigma
;
// = 3.0;
double
lma_r0
=
clt_parameters
.
imp
.
cuas_lma_r0
;
// = 3.0; //maximum with with overshoot
double
lma_ovrsht
=
clt_parameters
.
imp
.
cuas_lma_ovrsht
;
// = 2.0;
// CUAS Motion LMA parameters
boolean
lma_fit_xy
=
clt_parameters
.
imp
.
cuas_lma_fit_xy
;
// true;
boolean
lma_fit_a
=
clt_parameters
.
imp
.
cuas_lma_fit_a
;
// true;
boolean
lma_fit_c
=
clt_parameters
.
imp
.
cuas_lma_fit_c
;
// true;
boolean
lma_fit_r
=
clt_parameters
.
imp
.
cuas_lma_fit_r
;
// true;
boolean
lma_fit_k
=
clt_parameters
.
imp
.
cuas_lma_fit_k
;
// true;
double
lambda
=
clt_parameters
.
imp
.
cuas_lambda
;
// = 0.1;
double
lambda_good
=
clt_parameters
.
imp
.
cuas_lambda_good
;
// = 0.5;
double
lambda_bad
=
clt_parameters
.
imp
.
cuas_lambda_bad
;
// = 8;
double
lambda_max
=
clt_parameters
.
imp
.
cuas_lambda_max
;
// = 100;
double
rms_diff
=
clt_parameters
.
imp
.
cuas_rms_diff
;
// = 0.001; // relative RMS improvement
int
num_iter
=
clt_parameters
.
imp
.
cuas_num_iter
;
// = 20;
// CUAS Motion LMA filter parameters
double
lma_rms
=
clt_parameters
.
imp
.
cuas_lma_rms
;
// = 1.5; // Maximal RMS, regardless of amplitude
double
lma_arms
=
clt_parameters
.
imp
.
cuas_lma_arms
;
// = 0.06; // Maximal absolute RMS, sufficient for any amplitude
double
lma_rrms
=
clt_parameters
.
imp
.
cuas_lma_rrms
;
// = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
double
lma_mina
=
clt_parameters
.
imp
.
cuas_lma_mina
;
// = 1.0; // Minimal A (amplitude)
double
lma_maxr
=
clt_parameters
.
imp
.
cuas_lma_maxr
;
// = 5.0; // Maximal radius (>3.8)
double
lma_mink
=
clt_parameters
.
imp
.
cuas_lma_mink
;
// = 0.0; // Minimal K (overshoot) <0.007
double
lma_maxk
=
clt_parameters
.
imp
.
cuas_lma_maxk
;
// = 5.0; // Minimal K (overshoot) > 3.8
for
(
int
i
=
0
;
i
<
target_frac
.
length
;
i
++)
{
if
(
clt_parameters
.
imp
.
cuas_target_frac
[
i
].
length
>=
2
)
{
target_frac
[
i
][
0
]
=
clt_parameters
.
imp
.
cuas_target_frac
[
i
][
0
];
...
...
@@ -262,6 +283,8 @@ public class CuasMotion {
// srt_path = gd.getNextString();
boolean
save_params
=
true
;
boolean
test_lma
=
false
;
while
(
true
)
{
GenericJTabbedDialog
gd
=
new
GenericJTabbedDialog
(
"Motion scan parameters"
);
// gd.addNumericField("Center frame", framecent, 0, 5, "frame", "Center frame");
...
...
@@ -283,10 +306,57 @@ public class CuasMotion {
gd
.
addNumericField
(
"Minimal target strength"
,
target_strength
,
5
,
8
,
""
,
"Minimal value of the target image."
);
gd
.
addStringField
(
"Fraction for strengths"
,
IntersceneMatchParameters
.
double2dToString
(
target_frac
),
100
,
"Variable number of (strength, fraction) pairs separated by \":\". Each pair of strength, minimal fraction is separated by \",\"."
);
gd
.
addCheckbox
(
"Target not on the tile edge"
,
no_border
,
"Exclude targets with centers on the edge of 16x16 tiles."
);
gd
.
addMessage
(
"=== Moving target LMA ==="
);
gd
.
addNumericField
(
"Weight Gaussian sigma"
,
lma_sigma
,
5
,
8
,
"pix"
,
"Weights to emphasize maximum center area when fitting."
);
gd
.
addNumericField
(
"Target typical radius"
,
lma_r0
,
5
,
8
,
"pix"
,
"Typical target radius including negative overshoot (caused by UM filter)."
);
gd
.
addNumericField
(
"Target maximum overshoot"
,
lma_ovrsht
,
5
,
8
,
""
,
"Hos much smaller is the first zero than total maximum with overshoot (2.0 - first zero radius 1/2 of the full."
);
gd
.
addMessage
(
"--- Moving target LMA fitting parameters ---"
);
gd
.
addCheckbox
(
"LMA fit X,Y"
,
lma_fit_xy
,
"Fit target center position."
);
gd
.
addCheckbox
(
"LMA fit amplitude (strength)"
,
lma_fit_a
,
"Fit maximum amplitude."
);
gd
.
addCheckbox
(
"LMA fit offset"
,
lma_fit_c
,
"Fit out-of-maximum level (offset)."
);
gd
.
addCheckbox
(
"LMA fit radius"
,
lma_fit_r
,
"Fit target total radius - includes negative overshoot caused by UM filter."
);
gd
.
addCheckbox
(
"LMA fit overshoot"
,
lma_fit_k
,
"Fit target overshoot (2.0 - first zero crossing at half radius."
);
gd
.
addNumericField
(
"LMA lambda"
,
lambda
,
5
,
8
,
""
,
"LMA initial lambda."
);
gd
.
addNumericField
(
"Scale lambda after success"
,
lambda_good
,
5
,
8
,
""
,
"Multiply lambda if RMS decreaed."
);
gd
.
addNumericField
(
"Scale lambda after failure"
,
lambda_bad
,
5
,
8
,
""
,
"Multiply lambda if RMS increaed."
);
gd
.
addNumericField
(
"Maximal lambda"
,
lambda_max
,
5
,
8
,
""
,
"Give up if lambda gets higher value."
);
gd
.
addNumericField
(
"Relative RMS improvement"
,
rms_diff
,
5
,
8
,
""
,
"Finish fitting when the relative RMS improvement drops below this value."
);
gd
.
addNumericField
(
"LMA iterations"
,
num_iter
,
0
,
3
,
""
,
"Maximal number of the LMA iterations."
);
gd
.
addMessage
(
"--- Moving target discrimination parameters theresholds ---"
);
gd
.
addNumericField
(
"Maximal RMS"
,
lma_rms
,
5
,
8
,
""
,
"Maximal RMS for target that should match always, regardless of the amplitude."
);
gd
.
addNumericField
(
"Maximal sufficient RMS"
,
lma_arms
,
5
,
8
,
""
,
"Maximal sufficient RMS for target. Satisfying any of the sufficient or relative is enough"
);
gd
.
addNumericField
(
"Maximal relative RMS"
,
lma_rrms
,
5
,
8
,
""
,
"Maximal relative (to amplitude) RMS for target. Satisfying any of the absolute and relative is sufficient"
);
gd
.
addNumericField
(
"Minimal target amplitude"
,
lma_mina
,
5
,
8
,
""
,
"Filter out weak targets."
);
gd
.
addNumericField
(
"Maximal radius"
,
lma_maxr
,
5
,
8
,
""
,
"Maximal target radius including negative overshoot."
);
gd
.
addNumericField
(
"Minimal overshoot ratio"
,
lma_mink
,
5
,
8
,
""
,
"Minimal ratio of the overshoot radius to the first 0 radius (typical 1.0)."
);
gd
.
addNumericField
(
"Maximal overshoot ratio"
,
lma_maxk
,
5
,
8
,
""
,
"Maximal ratio of the overshoot radius to the first 0 radius (typical 3.0)."
);
gd
.
addStringField
(
"Data directory"
,
data_dir
,
100
,
"Intermediate results directory (to bypass first stages during debugging)."
);
gd
.
addCheckbox
(
"Save_params"
,
save_params
,
"Save edited parameters"
);
gd
.
addCheckbox
(
"Test LMA"
,
test_lma
,
"Test LMA from known files instead of normal operation."
);
gd
.
showDialog
();
if
(
gd
.
wasCanceled
())
{
...
...
@@ -310,9 +380,32 @@ public class CuasMotion {
target_radius
=
gd
.
getNextNumber
();
target_strength
=
gd
.
getNextNumber
();
target_frac
=
IntersceneMatchParameters
.
stringToDouble2d
(
gd
.
getNextString
());
no_border
=
gd
.
getNextBoolean
();
lma_sigma
=
gd
.
getNextNumber
();
lma_r0
=
gd
.
getNextNumber
();
lma_ovrsht
=
gd
.
getNextNumber
();
lma_fit_xy
=
gd
.
getNextBoolean
();
lma_fit_a
=
gd
.
getNextBoolean
();
lma_fit_c
=
gd
.
getNextBoolean
();
lma_fit_r
=
gd
.
getNextBoolean
();
lma_fit_k
=
gd
.
getNextBoolean
();
lambda
=
gd
.
getNextNumber
();
lambda_good
=
gd
.
getNextNumber
();
lambda_bad
=
gd
.
getNextNumber
();
lambda_max
=
gd
.
getNextNumber
();
rms_diff
=
gd
.
getNextNumber
();
num_iter
=
(
int
)
gd
.
getNextNumber
();
lma_rms
=
gd
.
getNextNumber
();
lma_arms
=
gd
.
getNextNumber
();
lma_rrms
=
gd
.
getNextNumber
();
lma_mina
=
gd
.
getNextNumber
();
lma_maxr
=
gd
.
getNextNumber
();
lma_mink
=
gd
.
getNextNumber
();
lma_maxk
=
gd
.
getNextNumber
();
data_dir
=
gd
.
getNextString
();
save_params
=
gd
.
getNextBoolean
();
test_lma
=
gd
.
getNextBoolean
();
if
(
save_params
)
{
clt_parameters
.
imp
.
cuas_corr_offset
=
corr_offset
;
...
...
@@ -339,6 +432,28 @@ public class CuasMotion {
System
.
out
.
println
(
"testCuasScanMotion(): 2.wrong format for a pair of strength, fraction values."
);
}
}
clt_parameters
.
imp
.
cuas_no_border
=
no_border
;
clt_parameters
.
imp
.
cuas_lma_sigma
=
lma_sigma
;
clt_parameters
.
imp
.
cuas_lma_r0
=
lma_r0
;
clt_parameters
.
imp
.
cuas_lma_fit_xy
=
lma_fit_xy
;
clt_parameters
.
imp
.
cuas_lma_fit_a
=
lma_fit_a
;
clt_parameters
.
imp
.
cuas_lma_fit_c
=
lma_fit_c
;
clt_parameters
.
imp
.
cuas_lma_fit_r
=
lma_fit_r
;
clt_parameters
.
imp
.
cuas_lma_fit_k
=
lma_fit_k
;
clt_parameters
.
imp
.
cuas_lma_ovrsht
=
lma_ovrsht
;
clt_parameters
.
imp
.
cuas_lambda
=
lambda
;
clt_parameters
.
imp
.
cuas_lambda_good
=
lambda_good
;
clt_parameters
.
imp
.
cuas_lambda_bad
=
lambda_bad
;
clt_parameters
.
imp
.
cuas_lambda_max
=
lambda_max
;
clt_parameters
.
imp
.
cuas_rms_diff
=
rms_diff
;
clt_parameters
.
imp
.
cuas_num_iter
=
num_iter
;
clt_parameters
.
imp
.
cuas_lma_rms
=
lma_rms
;
clt_parameters
.
imp
.
cuas_lma_arms
=
lma_arms
;
clt_parameters
.
imp
.
cuas_lma_rrms
=
lma_rrms
;
clt_parameters
.
imp
.
cuas_lma_mina
=
lma_mina
;
clt_parameters
.
imp
.
cuas_lma_maxr
=
lma_maxr
;
clt_parameters
.
imp
.
cuas_lma_mink
=
lma_mink
;
clt_parameters
.
imp
.
cuas_lma_maxk
=
lma_maxk
;
}
int
start_frame
=
0
;
...
...
@@ -370,6 +485,28 @@ public class CuasMotion {
System
.
out
.
println
(
"target_radius= "
+
target_radius
);
System
.
out
.
println
(
"target_strength= "
+
target_strength
);
System
.
out
.
println
(
"target_frac= "
+
IntersceneMatchParameters
.
double2dToString
(
target_frac
));
System
.
out
.
println
(
"no_border= "
+
no_border
);
System
.
out
.
println
(
"lma_sigma= "
+
lma_sigma
);
System
.
out
.
println
(
"lma_r0= "
+
lma_r0
);
System
.
out
.
println
(
"lma_ovrsht= "
+
lma_ovrsht
);
System
.
out
.
println
(
"lma_fit_xy= "
+
lma_fit_xy
);
System
.
out
.
println
(
"lma_fit_a= "
+
lma_fit_a
);
System
.
out
.
println
(
"lma_fit_c= "
+
lma_fit_c
);
System
.
out
.
println
(
"lma_fit_r= "
+
lma_fit_r
);
System
.
out
.
println
(
"lma_fit_k= "
+
lma_fit_k
);
System
.
out
.
println
(
"lambda= "
+
lambda
);
System
.
out
.
println
(
"lambda_good= "
+
lambda_good
);
System
.
out
.
println
(
"lambda_bad= "
+
lambda_bad
);
System
.
out
.
println
(
"lambda_max= "
+
lambda_max
);
System
.
out
.
println
(
"rms_diff= "
+
rms_diff
);
System
.
out
.
println
(
"num_iter= "
+
num_iter
);
System
.
out
.
println
(
"lma_rms= "
+
lma_rms
);
System
.
out
.
println
(
"lma_arms= "
+
lma_arms
);
System
.
out
.
println
(
"lma_rrms= "
+
lma_rrms
);
System
.
out
.
println
(
"lma_mina= "
+
lma_mina
);
System
.
out
.
println
(
"lma_maxr= "
+
lma_maxr
);
System
.
out
.
println
(
"lma_mink= "
+
lma_mink
);
System
.
out
.
println
(
"lma_maxk= "
+
lma_maxk
);
}
float
[][]
fpixels
=
new
float
[
num_scenes
][];
String
[]
scene_titles
=
new
String
[
num_scenes
];
...
...
@@ -383,6 +520,7 @@ public class CuasMotion {
slice_titles
[
nscan
]
=
imp_sel
.
getStack
().
getSliceLabel
(
frame_cent
+
1
);
}
CuasMotion
cuasMotion
=
new
CuasMotion
(
clt_parameters
,
// CLTParameters clt_parameters,
parentCLT
,
// QuadCLT parentCLT,
...
...
@@ -404,6 +542,13 @@ public class CuasMotion {
String
title_accumulated
=
imp_name
+
"-accumulated"
+
suffix_param
;
String
title_rendered_hyper
=
imp_name
+
"-rendered_hyper"
+
suffix_param
;
//
String
title_acc_targets
=
imp_name
+
"-accumulated_targets"
+
suffix_param
;
String
title_vf_good
=
imp_name
+
"-vector_field_good"
+
suffix_param
;
//
String
title_extended_good
=
imp_name
+
"-vector_field_extended_good"
+
suffix_param
;
//
String
title_targets_good
=
imp_name
+
"-targets_good"
+
suffix_param
;
//
final
int
frame0
=
start_frame
+
seq_length
/
2
;
final
int
half_accum_range
=
corr_pairs
/
2
;
final
boolean
smooth_accum
=
true
;
double
[][][]
corr2d
=
null
;
// to read it if bypassing calculations
double
[][][]
motion_scan
=
null
;
...
...
@@ -413,8 +558,169 @@ public class CuasMotion {
int
[]
remain
=
new
int
[
num_corr_samples
];
data_dir
=
trimSuffix
(
data_dir
,
"/"
);
// String vf_extended_path = data_dir + "/" + vf_extended+".tiff";
String
vf_filtered_path
=
data_dir
+
"/"
+
title_vf_filtered
+
".tiff"
;
motion_scan_filtered
=
getVectorFieldHyper
(
vf_filtered_path
);
// String path)
// String vf_filtered_path = data_dir + "/" + title_vf_filtered+".tiff";
String
vf_path
=
data_dir
+
"/"
+
title_vf
+
".tiff"
;
// motion_scan_filtered = getVectorFieldHyper(vf_filtered_path); // String path)
if
(
test_lma
)
{
String
path_vf
=
"/media/elphel/NVME/lwir16-proc/eagle_mountain/linked/movement/selected/25_r1.5/I-1747803449_165687-vector_field_good-offs20-pairs50-rstr0.01-fz300.0-cr3.0-mr1-ms0.0-sp0.0-sb1.0-tr2.0-ts0.8-tf0.0,0.12:2.5,0.15:5.0,0.25.tiff"
;
String
path_acc
=
"/media/elphel/NVME/lwir16-proc/eagle_mountain/linked/movement/selected/25_r1.5/I-1747803449_165687-accumulated-offs20-pairs50-rstr0.01-fz300.0-cr3.0-mr1-ms0.0-sp0.0-sb1.0-tr2.0-ts0.8-tf0.0,0.12:2.5,0.15:5.0,0.25-n20.tiff"
;
double
[][][]
vf_sequence
=
getVectorFieldHyper
(
path_vf
);
// String path)
if
(
vf_sequence
==
null
)
{
System
.
out
.
println
(
"Failed to motion vectors from "
+
path_vf
);
continue
;
}
ImagePlus
imp_accum
=
new
ImagePlus
(
path_acc
);
if
(
imp_accum
.
getWidth
()==
0
)
{
System
.
out
.
println
(
"Failed to read accum data from "
+
path_acc
);
continue
;
}
int
[]
wh
=
new
int
[
2
];
float
[][]
accum
=
ShowDoubleFloatArrays
.
readFloatArray
(
imp_accum
,
// ImagePlus imp,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh)
double
[][][][]
coord_data2
=
getAccumulatedCoordinates
(
vf_sequence
,
// final double [][][] vector_fields, // centers
accum
,
// final double [][] accum_data, // should be around 0, no low-freq
target_radius
,
// final double centroid_radius,
n_recenter
,
// final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
cuasMotion
.
tilesX
,
// final int tilesX){
no_border
,
// final boolean no_border,
// Moving target LMA
lma_sigma
,
// final double lma_sigma,
lma_r0
,
// final double lma_r0,
lma_ovrsht
,
// final double lma_ovrsht,
// CUAS Motion LMA parameters
lma_fit_xy
,
// final boolean lma_fit_xy,
lma_fit_a
,
// final boolean lma_fit_a,
lma_fit_c
,
// final boolean lma_fit_c,
lma_fit_r
,
// final boolean lma_fit_r,
lma_fit_k
,
// final boolean lma_fit_k,
lambda
,
// final double lambda,
lambda_good
,
// final double lambda_good,
lambda_bad
,
// final double lambda_bad,
lambda_max
,
// final double lambda_max,
rms_diff
,
// final double rms_diff,
num_iter
,
// final int num_iter,
debugLevel
);
// final int debugLevel);
double
[][][]
coord_data
=
coord_data2
[
0
];
double
[][][]
coord_lma
=
coord_data2
[
1
];
showVectorFieldsSequence
(
coord_data
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-VF-TEST"
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequenceLMA
(
coord_lma
,
// double [][][] target_scene_sequence, // rename
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-LMA-TEST"
,
// String title,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
// int [] targets_remain = new int [coord_data.length];
int
[]
targets_remain
=
new
int
[
coord_data
.
length
];
double
[][][]
coord_data_filtered
=
filterAndShowTargets
(
coord_data
,
// double [][][] coord_data,
target_strength
,
// double target_strength,
target_frac
,
// double [][] target_frac,
slice_titles
,
// String [] slice_titles, //
title_targets_filt
+
"-VF-TEST-FILTERED"
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
,
// int tilesX)
true
);
// show_vector_field); // boolean show)
int
remained_total
=
printRemain
(
targets_remain
,
"Total good targets"
,
true
);
double
[][][]
coord_data_filtered_lma
=
filterAndShowTargetsLMA
(
coord_lma
,
// double [][][] coord_data,
lma_rms
,
// double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
lma_arms
,
// double lma_arms, // = 0.03; // Maximal absolutre RMS
lma_rrms
,
// double lma_rrms, // = 0.03; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
lma_mina
,
// double lma_mina, // = 1.0; // Minimal A (amplitude)
lma_maxr
,
// double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
lma_mink
,
// double lma_mink, // = 1.0; // Minimal K (overshoot) = 1.0
lma_maxk
,
// double lma_maxk, // = 1.0; // Minimal K (overshoot) = 3.0
slice_titles
,
// String [] slice_titles, //
title_targets_filt
+
"-LMA-TEST-FILTERED"
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
,
// int tilesX)
true
);
// show_vector_field); // boolean show)
remained_total
=
printRemain
(
targets_remain
,
"coord_data_filtered_lma: Total new targets LMA"
,
true
);
// remove tiles that did not pass old vf filter
double
[][][]
targets_lma_combo
=
filterMotionScans
(
// should keep LMA coordinates
coord_data_filtered_lma
,
// double [][][] scan0,
coord_data_filtered
,
// double [][][] scan1)
remain
);
// create vector field sequence by masking after the last filter
double
[][][]
targets_vf_combo
=
filterMotionScans
(
// should keep LMA coordinates
vf_sequence
,
// double [][][] scan0,
targets_lma_combo
,
// double [][][] scan1)
remain
);
printRemain
(
remain
,
"targets_lma_combo"
,
true
);
showVectorFieldsSequenceLMA
(
targets_lma_combo
,
// double [][][] target_scene_sequence,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_good
+
"-LMA-TEST-COMBO"
,
// String title,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
// create larger, 5x5 vector field for accumulation
double
[][][]
extended_vf_sequence
=
extendMotionScan
(
targets_vf_combo
,
// final double [][][] motion_scan,
null
,
// filter5, // final boolean [][] filtered, // centers, should be non-overlapped
cuasMotion
.
tilesX
,
// final int tilesX)
2
,
// final int range, // 1 or 2
remain
);
// final int [] remain)
printRemain
(
remain
,
"extended5x5_vf_sequence"
,
true
);
float
[][]
fpixels_accumulated5x5
=
cuasMotion
.
shiftAndRenderAccumulate
(
clt_parameters
,
// CLTParameters clt_parameters,
true
,
// final boolean fill_zeros,
fpixels
,
// final float [][] fpixels,
extended_vf_sequence
,
// final double [][][] vector_field,
frame0
,
// final int frame0, // for vector_field[0]
corr_step
,
// final int frame_step,
half_accum_range
,
// final int half_range,
smooth_accum
,
// final boolean smooth,
corr_offset
,
// final int corr_offset, // interframe distance for correlation
true
);
// final boolean batch_mode) {
// zero-fill undefined tiles
ShowDoubleFloatArrays
.
showArrays
(
fpixels_accumulated5x5
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_accumulated
+
"-TARGETS5x5"
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
scene_titles
);
// titles_accum);
/*
float [][] fpixels_accumulated_filtered = getTargetImages(
targets_lma_combo, // final double [][][] vector_fields, // centers , just null/not null
accum, // final float [][] accum_data, // should be around 0, no low-freq
cuasMotion.tilesX); // final int tilesX)
ShowDoubleFloatArrays.showArrays(
fpixels_accumulated_filtered,
cuasMotion.gpu_max_width,
cuasMotion.gpu_max_height,
true,
title_acc_targets+"-LMA-TEST-COMBO", // "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
scene_titles); // titles_accum);
*/
continue
;
}
motion_scan
=
getVectorFieldHyper
(
vf_path
);
// title_vf); // String path)
/*
if (motion_scan_filtered != null) {
extended_scan = extendMotionScan(
motion_scan_filtered, // final double [][][] motion_scan,
...
...
@@ -423,13 +729,15 @@ public class CuasMotion {
1, // final int range, // 1 or 2
remain); // final int [] remain)
}
*/
// extended_scan = getVectorFieldHyper(vf_extended_path); // String path)
if
(
extended_scan
==
null
)
{
// if (extended_scan == null) {
boolean
show_vector_field
=
false
;
//true;
boolean
show_2d_correlations
=
false
;
//true;
boolean
show_full_images
=
false
;
//true;
if
(
motion_scan
==
null
)
{
System
.
out
.
println
(
"testCuasScanMotion(): Failed to read Vector Field from file, calculating"
);
// readVectorField(String path)
boolean
show_vector_field
=
true
;
boolean
show_2d_correlations
=
true
;
String
dbg_title
=
imp_name
;
// double [][][]
...
...
@@ -451,6 +759,46 @@ public class CuasMotion {
dbg_title
,
// String title,
corr2d
,
// double [][][] corr2d, // null or [(fpixels.length - seq_length - start_frame) / corr_step)[][]
debugLevel
);
// int debugLevel) {
if
(
show_2d_correlations
)
{
// may be read to re-process with vector field
int
corr_size
=
2
*
GPUTileProcessor
.
DTT_SIZE
-
1
;
double
[][]
dbg_2d_corrs
=
ImageDtt
.
corr_partial_dbg
(
// not used in lwir
corr2d
,
// final double [][][] corr_data, // [layer][tile][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
cuasMotion
.
tilesX
,
// final int tilesX,
corr_size
,
//final int corr_size, // 15
clt_parameters
.
corr_border_contrast
,
// final double border_contrast,
debugLevel
);
// final int globalDebugLevel)
ShowDoubleFloatArrays
.
showArrays
(
dbg_2d_corrs
,
cuasMotion
.
tilesX
*
(
corr_size
+
1
),
cuasMotion
.
tilesY
*
(
corr_size
+
1
),
true
,
title_cor2d
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
slice_titles
);
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"scan DONE"
);
}
}
// starting from the motion_scan[][][] - calculated or read from file. corr2d is curently unused, maybe we'll have to save restore
double
[][][]
motion_scan_original
=
cloneMotionScan
(
motion_scan
,
remain
);
printRemain
(
remain
,
"motion_scan_original"
,
true
);
int
niter
;
int
max_iter
=
20
;
// 100;
double
[][][]
targets_good
=
new
double
[
motion_scan
.
length
][
motion_scan
[
0
].
length
][];
// will combine good targets
double
[][][]
targets_bad
=
new
double
[
motion_scan
.
length
][
motion_scan
[
0
].
length
][];
// will combine good targets
for
(
niter
=
0
;
niter
<
max_iter
;
niter
++)
{
// remove known bad targets. TODO: maybe will need to modify corr2d and recalculate, if the same tile is shared by a target and background
motion_scan
=
subtractMotionScans
(
motion_scan
,
// double [][][] scan0, // all tried for targets
targets_bad
,
// double [][][] scan1) // good targets
remain
);
printRemain
(
remain
,
"motion_scan wo bad"
,
true
);
// filter remaining (no known bad ones)
filter5
=
filterMotionScan
(
motion_scan
,
// final double [][][] motion_scan,
cuasMotion
.
tilesX
,
// final int tilesX)
...
...
@@ -460,41 +808,35 @@ public class CuasMotion {
speed_min
,
// double speed_min,
speed_pref
,
// double speed_pref,
speed_boost
);
// double speed_boost);
printRemain
(
remain
,
"filter5"
,
true
);
motion_scan_filtered
=
applyFilter
(
motion_scan
,
// double [][][] motion_scan,
filter5
);
// boolean [][] filter5)
// double [][][]
// remove know good (already processed)
motion_scan_filtered
=
subtractMotionScans
(
motion_scan_filtered
,
// double [][][] scan0, // all tried for targets
targets_good
,
// double [][][] scan1) // good targets
remain
);
printRemain
(
remain
,
"filtered wo good"
,
true
);
// Anything remains? we'll see agter extension
extended_scan
=
extendMotionScan
(
motion_scan
,
// final double [][][] motion_scan,
filter5
,
// final boolean [][] filtered, // centers, should be non-overlapped
cuasMotion
.
tilesX
,
// final int tilesX)
1
,
// final int range, // 1 or 2
remain
);
// final int [] remain)
if
((
debugLevel
>-
4
)
&&
(
remain
!=
null
))
{
motion_scan_filtered
,
// final double [][][] motion_scan,
null
,
// filter5, // final boolean [][] filtered, // centers, should be non-overlapped
cuasMotion
.
tilesX
,
// final int tilesX)
1
,
// final int range, // 1 or 2
remain
);
// final int [] remain)
int
remained_total
=
printRemain
(
remain
,
"extended_scan"
,
true
);
if
((
debugLevel
>-
4
)
&&
(
remain
!=
null
))
{
System
.
out
.
println
(
"testCuasScanMotion() Total new tiles to process for "
+
remain
.
length
+
" scene sequences is "
+
remained_total
);
for
(
int
nscan
=
0
;
nscan
<
remain
.
length
;
nscan
++)
{
System
.
out
.
print
(
nscan
+
":"
+
remain
[
nscan
]+
", "
);
}
System
.
out
.
println
();
}
if
(
show_2d_correlations
)
{
// may be read to re-process with vector field
int
corr_size
=
2
*
GPUTileProcessor
.
DTT_SIZE
-
1
;
double
[][]
dbg_2d_corrs
=
ImageDtt
.
corr_partial_dbg
(
// not used in lwir
corr2d
,
// final double [][][] corr_data, // [layer][tile][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
cuasMotion
.
tilesX
,
// final int tilesX,
corr_size
,
//final int corr_size, // 15
clt_parameters
.
corr_border_contrast
,
// final double border_contrast,
debugLevel
);
// final int globalDebugLevel)
ShowDoubleFloatArrays
.
showArrays
(
dbg_2d_corrs
,
cuasMotion
.
tilesX
*
(
corr_size
+
1
),
cuasMotion
.
tilesY
*
(
corr_size
+
1
),
true
,
title_cor2d
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
slice_titles
);
if
(
remained_total
==
0
)
{
break
;
}
// there are some tiles left to try
if
(
show_vector_field
)
{
//title_vf_all
...
...
@@ -504,7 +846,7 @@ public class CuasMotion {
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_vf_all
,
// String title,
title_vf_all
+
"-n"
+
niter
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
...
...
@@ -514,8 +856,8 @@ public class CuasMotion {
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_vf
,
// String title,
true
,
// boolean nan_effective_strength,
title_vf
+
"-n"
+
niter
,
// String title,
true
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequence
(
...
...
@@ -524,7 +866,7 @@ public class CuasMotion {
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_vf_filtered
,
// String title,
title_vf_filtered
+
"-n"
+
niter
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
...
...
@@ -534,22 +876,251 @@ public class CuasMotion {
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_vf_extended
,
// String title,
title_vf_extended
+
"-n"
+
niter
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
// show good and bad accumulated here too?
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"
scan DONE"
);
System
.
out
.
println
(
"
Starting render, iteration = "
+
niter
);
}
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Starting render"
);
}
float
[][]
fpixels_rendered
=
cuasMotion
.
shiftAndRenderTest
(
clt_parameters
,
// CLTParameters clt_parameters,
fpixels
,
// final float [][] fpixels,
extended_scan
,
// final double [][][] vector_field,
frame0
,
// final int frame0, // for vector_field[0]
corr_step
,
// final int frame_step,
corr_offset
,
// final int corr_offset, // interframe distance for correlation
true
);
// final boolean batch_mode) {
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Render DONE"
);
}
float
[][]
fpixels_accumulated
=
cuasMotion
.
shiftAndRenderAccumulate
(
clt_parameters
,
// CLTParameters clt_parameters,
false
,
// final boolean fill_zeros,
fpixels
,
// final float [][] fpixels,
extended_scan
,
// final double [][][] vector_field,
frame0
,
// final int frame0, // for vector_field[0]
corr_step
,
// final int frame_step,
half_accum_range
,
// final int half_range,
smooth_accum
,
// final boolean smooth,
corr_offset
,
// final int corr_offset, // interframe distance for correlation
true
);
// final boolean batch_mode) {
// show just fpixels_accumulated
// move outside? compare to slice_titles known
if
(
show_full_images
)
{
ShowDoubleFloatArrays
.
showArrays
(
fpixels_accumulated
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_accumulated
+
"-n"
+
niter
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
scene_titles
);
// titles_accum);
}
// replace center frames with the accumulated ones
for
(
int
nseq
=
0
;
nseq
<
fpixels_accumulated
.
length
;
nseq
++){
fpixels_rendered
[
frame0
+
nseq
*
corr_step
]
=
fpixels_accumulated
[
nseq
];
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Accumulation DONE"
);
}
float
[][][]
fpixels_hyper
=
{
fpixels
,
fpixels_rendered
};
String
[]
hyper_titles_top
=
{
"Source"
,
"Rendered"
};
if
(
show_full_images
)
{
ImagePlus
imp_hyper
=
ShowDoubleFloatArrays
.
showArraysHyperstack
(
fpixels_hyper
,
// float[][][] pixels,
cuasMotion
.
gpu_max_width
,
// int width,
title_rendered_hyper
+
"-n"
+
niter
,
// String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
scene_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
hyper_titles_top
,
// String [] frame_titles, // frame titles or null
true
);
// boolean show)
}
// double target_radius = cent_radius; // for now - make separate
// target_max
double
[][][][]
coord_data2
=
getAccumulatedCoordinates
(
motion_scan_filtered
,
// final double [][][] vector_fields, // centers
fpixels_accumulated
,
// final double [][] accum_data, // should be around 0, no low-freq
target_radius
,
// final double centroid_radius,
n_recenter
,
// final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
cuasMotion
.
tilesX
,
// final int tilesX){
no_border
,
// final boolean no_border,
// Moving target LMA
lma_sigma
,
// final double lma_sigma,
lma_r0
,
// final double lma_r0,
lma_ovrsht
,
// final double lma_ovrsht,
// CUAS Motion LMA parameters
lma_fit_xy
,
// final boolean lma_fit_xy,
lma_fit_a
,
// final boolean lma_fit_a,
lma_fit_c
,
// final boolean lma_fit_c,
lma_fit_r
,
// final boolean lma_fit_r,
lma_fit_k
,
// final boolean lma_fit_k,
lambda
,
// final double lambda,
lambda_good
,
// final double lambda_good,
lambda_bad
,
// final double lambda_bad,
lambda_max
,
// final double lambda_max,
rms_diff
,
// final double rms_diff,
num_iter
,
// final int num_iter,
debugLevel
);
// final int debugLevel);
double
[][][]
coord_data
=
coord_data2
[
0
];
double
[][][]
coord_lma
=
coord_data2
[
1
];
if
(
show_vector_field
)
{
showVectorFieldsSequence
(
coord_data
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-n"
+
niter
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequenceLMA
(
coord_lma
,
// double [][][] target_scene_sequence, // rename
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-LMA-n"
+
niter
,
// String title,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
}
int
[]
targets_remain
=
new
int
[
coord_data
.
length
];
double
[][][]
coord_data_filtered
=
filterAndShowTargets
(
coord_data
,
// double [][][] coord_data,
target_strength
,
// double target_strength,
target_frac
,
// double [][] target_frac,
slice_titles
,
// String [] slice_titles, //
title_targets_filt
+
"-n"
+
niter
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
,
// int tilesX)
show_vector_field
);
// boolean show)
remained_total
=
printRemain
(
targets_remain
,
"coord_data_filtered: Total new targets"
,
true
);
if
(
remained_total
==
0
)
{
break
;
}
double
[][][]
coord_data_filtered_lma
=
filterAndShowTargetsLMA
(
coord_lma
,
// double [][][] coord_data,
lma_rms
,
// double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
lma_arms
,
// double lma_arms, // = 0.03; // Maximal absolutre RMS
lma_rrms
,
// double lma_rrms, // = 0.03; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
lma_mina
,
// double lma_mina, // = 1.0; // Minimal A (amplitude)
lma_maxr
,
// double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
lma_mink
,
// double lma_mink, // = 1.0; // Minimal K (overshoot) = 1.0
lma_maxk
,
// double lma_maxk, // = 1.0; // Minimal K (overshoot) = 3.0
slice_titles
,
// String [] slice_titles, //
title_targets_filt
+
"-n"
+
niter
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
,
// int tilesX)
show_vector_field
);
// boolean show)
remained_total
=
printRemain
(
targets_remain
,
"coord_data_filtered: Total new targets"
,
true
);
// add good targets to targets_good
targets_good
=
combineMotionScans
(
targets_good
,
// double [][][] scan0,
coord_data_filtered
,
// double [][][] scan1)
remain
);
printRemain
(
remain
,
"targets_good"
,
true
);
if
(
show_vector_field
)
{
showVectorFieldsSequence
(
targets_good
,
// double [][][] vector_fields_sequence,
speed_min
,
// double speed_min,
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_good
+
"-n"
+
niter
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
}
double
[][][]
targets_bad_last
=
subtractMotionScans
(
motion_scan_filtered
,
// double [][][] scan0, // all tried for targets
coord_data_filtered
,
// double [][][] scan1) // good targets
remain
);
printRemain
(
remain
,
"targets_bad_last"
,
true
);
// add bad targets to targets_bad
targets_bad
=
combineMotionScans
(
targets_bad
,
// double [][][] scan0,
targets_bad_last
,
// double [][][] scan1)
remain
);
//
printRemain
(
remain
,
"targets_bad"
,
true
);
float
[][]
fpixels_accumulated_filtered
=
getTargetImages
(
coord_data_filtered
,
// final double [][][] vector_fields, // centers , just null/not null
fpixels_accumulated
,
// final float [][] accum_data, // should be around 0, no low-freq
cuasMotion
.
tilesX
);
// final int tilesX)
if
(
show_full_images
)
{
ShowDoubleFloatArrays
.
showArrays
(
fpixels_accumulated_filtered
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_acc_targets
+
"-n"
+
niter
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
scene_titles
);
// titles_accum);
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Iteration "
+
niter
+
" DONE."
);
}
}
//for (niter=0; niter < max_iter; niter++)
show_vector_field
=
true
;
show_full_images
=
true
;
// make good motion vectors from good targets
double
[][][]
motion_good
=
filterMotionScans
(
motion_scan_original
,
// double [][][] scan1 // or just use motion_scan - it has only bad removed
targets_good
,
// double [][][] scan1){ // keep scan0 that is in scan1
remain
);
printRemain
(
remain
,
"All done: motion_good"
,
true
);
int
frame0
=
start_frame
+
seq_length
/
2
;
// make extended from all good
extended_scan
=
extendMotionScan
(
motion_good
,
// motion_scan_filtered, // final double [][][] motion_scan,
null
,
// filter5, // final boolean [][] filtered, // centers, should be non-overlapped
cuasMotion
.
tilesX
,
// final int tilesX)
1
,
// final int range, // 1 or 2
remain
);
// final int [] remain)
printRemain
(
remain
,
"targets_good"
,
true
);
if
(
show_vector_field
)
{
showVectorFieldsSequence
(
motion_good
,
// double [][][] vector_fields_sequence,
speed_min
,
// double speed_min,
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_vf_good
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequence
(
targets_good
,
// double [][][] vector_fields_sequence,
speed_min
,
// double speed_min,
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_good
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequence
(
extended_scan
,
// double [][][] vector_fields_sequence,
speed_min
,
// double speed_min,
speed_pref
,
// double speed_pref,
speed_boost
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_extended_good
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
}
// Render for all good
float
[][]
fpixels_rendered
=
cuasMotion
.
shiftAndRenderTest
(
clt_parameters
,
// CLTParameters clt_parameters,
fpixels
,
// final float [][] fpixels,
...
...
@@ -558,15 +1129,12 @@ public class CuasMotion {
corr_step
,
// final int frame_step,
corr_offset
,
// final int corr_offset, // interframe distance for correlation
true
);
// final boolean batch_mode) {
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Render DONE"
);
System
.
out
.
println
(
"Render
all good
DONE"
);
}
final
int
half_accum_range
=
corr_pairs
/
2
;
final
boolean
smooth_accum
=
true
;
float
[][]
fpixels_accumulated
=
cuasMotion
.
shiftAndRenderAccumulate
(
clt_parameters
,
// CLTParameters clt_parameters,
false
,
// final boolean fill_zeros,
fpixels
,
// final float [][] fpixels,
extended_scan
,
// final double [][][] vector_field,
frame0
,
// final int frame0, // for vector_field[0]
...
...
@@ -575,105 +1143,214 @@ public class CuasMotion {
smooth_accum
,
// final boolean smooth,
corr_offset
,
// final int corr_offset, // interframe distance for correlation
true
);
// final boolean batch_mode) {
// show just fpixels_accumulated
String
[]
titles_accum
=
new
String
[
fpixels_accumulated
.
length
];
//scene_titles
for
(
int
nseq
=
0
;
nseq
<
fpixels_accumulated
.
length
;
nseq
++){
titles_accum
[
nseq
]
=
scene_titles
[
frame0
+
nseq
*
corr_step
];
if
(
show_full_images
)
{
ShowDoubleFloatArrays
.
showArrays
(
// good
fpixels_accumulated
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_accumulated
+
"-n"
+
niter
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
scene_titles
);
// titles_accum);
}
ShowDoubleFloatArrays
.
showArrays
(
fpixels_accumulated
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_accumulated
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
titles_accum
);
// replace center frames with the accumulated ones
for
(
int
nseq
=
0
;
nseq
<
fpixels_accumulated
.
length
;
nseq
++){
fpixels_rendered
[
frame0
+
nseq
*
corr_step
]
=
fpixels_accumulated
[
nseq
];
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"Accumulation DONE"
);
System
.
out
.
println
(
"Accumulation
all good
DONE"
);
}
float
[][][]
fpixels_hyper
=
{
fpixels
,
fpixels_rendered
};
String
[]
hyper_titles_top
=
{
"Source"
,
"Rendered"
};
ImagePlus
imp_hyper
=
ShowDoubleFloatArrays
.
showArraysHyperstack
(
fpixels_hyper
,
// float[][][] pixels,
cuasMotion
.
gpu_max_width
,
// int width,
title_rendered_hyper
,
// String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
scene_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
hyper_titles_top
,
// String [] frame_titles, // frame titles or null
true
);
// boolean show)
// double target_radius = cent_radius; // for now - make separate
String
[]
hyper_titles_top
=
{
"Source"
,
"Rendered"
};
if
(
show_full_images
)
{
ImagePlus
imp_hyper
=
ShowDoubleFloatArrays
.
showArraysHyperstack
(
// good
fpixels_hyper
,
// float[][][] pixels,
cuasMotion
.
gpu_max_width
,
// int width,
title_rendered_hyper
+
"-n"
+
niter
,
// String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
scene_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
hyper_titles_top
,
// String [] frame_titles, // frame titles or null
true
);
// boolean show)
}
// double target_radius = cent_radius; // for now - make separate
// target_max
double
[][][]
coord_data
=
getAccumulatedCoordinates
(
motion_scan_filtered
,
// final double [][][] vector_fields, // centers
fpixels_accumulated
,
// final double [][] accum_data, // should be around 0, no low-freq
target_radius
,
// final double centroid_radius,
n_recenter
,
// final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
cuasMotion
.
tilesX
);
// final int tilesX){
// update parameters
showVectorFieldsSequence
(
coord_data
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
double
[][][][]
coord_data2
=
getAccumulatedCoordinates
(
motion_good
,
// final double [][][] vector_fields, // centers
fpixels_accumulated
,
// final double [][] accum_data, // should be around 0, no low-freq
target_radius
,
// final double centroid_radius,
n_recenter
,
// final int n_recenter, // re-center window around new maximum. 0 -no refines (single-pass)
cuasMotion
.
tilesX
,
// final int tilesX){
no_border
,
// final boolean no_border,
// Moving target LMA
lma_sigma
,
// final double lma_sigma,
lma_r0
,
// final double lma_r0,
lma_ovrsht
,
// final double lma_ovrsht,
// CUAS Motion LMA parameters
lma_fit_xy
,
// final boolean lma_fit_xy,
lma_fit_a
,
// final boolean lma_fit_a,
lma_fit_c
,
// final boolean lma_fit_c,
lma_fit_r
,
// final boolean lma_fit_r,
lma_fit_k
,
// final boolean lma_fit_k,
lambda
,
// final double lambda,
lambda_good
,
// final double lambda_good,
lambda_bad
,
// final double lambda_bad,
lambda_max
,
// final double lambda_max,
rms_diff
,
// final double rms_diff,
num_iter
,
// final int num_iter,
debugLevel
);
// final int debugLevel);
double
[][][]
coord_data
=
coord_data2
[
0
];
double
[][][]
coord_lma
=
coord_data2
[
1
];
if
(
show_vector_field
)
{
showVectorFieldsSequence
(
coord_data
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-COMBO"
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
showVectorFieldsSequenceLMA
(
coord_lma
,
// double [][][] target_scene_sequence, // rename
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_all
+
"-LMA-COMBO"
,
// String title,
true
,
// boolean show,
cuasMotion
.
tilesX
);
// int tilesX) {
}
int
[]
targets_remain
=
new
int
[
coord_data
.
length
];
double
[][][]
coord_data_filtered
=
filterAndShowTargets
(
coord_data
,
// double [][][] coord_data,
target_strength
,
// double target_strength,
target_frac
,
// double [][] target_frac,
slice_titles
,
// String [] slice_titles, //
title_targets_filt
,
// String title_targets_filt,
title_targets_filt
+
"-n"
+
niter
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
,
// int tilesX)
show_vector_field
);
// boolean show)
int
remained_total
=
printRemain
(
targets_remain
,
"Total good targets"
,
true
);
double
[][][]
coord_data_filtered_lma
=
filterAndShowTargetsLMA
(
coord_lma
,
// double [][][] coord_data,
lma_rms
,
// double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
lma_arms
,
// double lma_arms, // = 0.03; // Maximal absolutre RMS
lma_rrms
,
// double lma_rrms, // = 0.03; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
lma_mina
,
// double lma_mina, // = 1.0; // Minimal A (amplitude)
lma_maxr
,
// double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
lma_mink
,
// double lma_mink, // = 1.0; // Minimal K (overshoot) = 1.0
lma_maxk
,
// double lma_maxk, // = 1.0; // Minimal K (overshoot) = 3.0
slice_titles
,
// String [] slice_titles, //
title_targets_filt
+
"-n"
+
niter
,
// String title_targets_filt,
targets_remain
,
// int [] targets_remain,
cuasMotion
.
tilesX
);
// int tilesX)
cuasMotion
.
tilesX
,
// int tilesX)
show_vector_field
);
// boolean show)
remained_total
=
printRemain
(
targets_remain
,
"coord_data_filtered: Total new targets LMA"
,
true
);
float
[][]
fpixels_accumulated_filtered
=
getTargetImages
(
coord_data_filtered
,
// final double [][][] vector_fields, // centers , just null/not null
fpixels_accumulated
,
// final float [][] accum_data, // should be around 0, no low-freq
cuasMotion
.
tilesX
);
// final int tilesX)
ShowDoubleFloatArrays
.
showArrays
(
fpixels_accumulated_filtered
,
cuasMotion
.
gpu_max_width
,
cuasMotion
.
gpu_max_height
,
true
,
title_acc_targets
,
// "-corr2d"+"-"+frame0+"-"+frame1+"-"+corr_pairs,
titles_accum
);
/*
boolean [][] good_targets = filterTargets(
coord_data, // final double [][][] target_coords,
target_strength, // final double target_strength,
target_frac, // final double [][] target_frac, // pairs - strength, minimal fraction for that strength
cuasMotion.tilesX, // final int tilesX,
targets_remain); // final int [] remain) {
double [][][] coord_data_filtered = applyFilter(
coord_data, // double [][][] motion_scan,
good_targets); // boolean [][] filter5)
showVectorFieldsSequence(
coord_data_filtered, // double [][][] vector_fields_sequence,
0.0, // double speed_min,
0.0, // double speed_pref,
1.0, // double speed_boost,
slice_titles, // String [] titles, // all slices*frames titles or just slice titles or null
title_targets_filt, // String title,
true, // boolean show,
cuasMotion.tilesX); // int tilesX) {
*/
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"testCuasScanMotion() Total good targets for "
+
targets_remain
.
length
+
" scene sequences is "
+
remained_total
);
}
if
(
debugLevel
>
-
4
)
{
System
.
out
.
println
(
"All DONE"
);
}
}
// while (true) {
}
public
static
int
printRemain
(
int
[]
remain
,
String
s
,
boolean
all
)
{
int
remained_total
=
0
;
for
(
int
nseq
=
0
;
nseq
<
remain
.
length
;
nseq
++)
{
remained_total
+=
remain
[
nseq
];
}
System
.
out
.
println
(
s
+
": total tiles for "
+
remain
.
length
+
" scene sequences is "
+
remained_total
);
if
(
all
)
{
for
(
int
nscan
=
0
;
nscan
<
remain
.
length
;
nscan
++)
{
System
.
out
.
print
(
nscan
+
":"
+
remain
[
nscan
]+
", "
);
}
System
.
out
.
println
();
}
return
remained_total
;
}
public
static
double
[][][]
cloneMotionScan
(
double
[][][]
motionScan
,
int
[]
remain
){
double
[][][]
cloned
=
new
double
[
motionScan
.
length
][
motionScan
[
0
].
length
][];
for
(
int
nseq
=
0
;
nseq
<
cloned
.
length
;
nseq
++)
{
int
n
=
0
;
for
(
int
ntile
=
0
;
ntile
<
cloned
[
nseq
].
length
;
ntile
++)
{
if
(
motionScan
[
nseq
][
ntile
]
!=
null
)
{
cloned
[
nseq
][
ntile
]
=
motionScan
[
nseq
][
ntile
].
clone
();
n
++;
}
}
if
(
remain
!=
null
)
remain
[
nseq
]
=
n
;
}
return
cloned
;
}
public
static
double
[][][]
combineMotionScans
(
double
[][][]
scan0
,
double
[][][]
scan1
,
int
[]
remain
){
// preference
double
[][][]
comboScan
=
new
double
[
scan0
.
length
][
scan0
[
0
].
length
][];
for
(
int
nseq
=
0
;
nseq
<
comboScan
.
length
;
nseq
++)
{
int
n
=
0
;
for
(
int
ntile
=
0
;
ntile
<
comboScan
[
nseq
].
length
;
ntile
++)
{
if
(
scan1
[
nseq
][
ntile
]
!=
null
)
{
comboScan
[
nseq
][
ntile
]
=
scan1
[
nseq
][
ntile
].
clone
();
n
++;
}
else
if
(
scan0
[
nseq
][
ntile
]
!=
null
)
{
comboScan
[
nseq
][
ntile
]
=
scan0
[
nseq
][
ntile
].
clone
();
n
++;
}
}
if
(
remain
!=
null
)
remain
[
nseq
]
=
n
;
}
return
comboScan
;
}
public
static
double
[][][]
subtractMotionScans
(
double
[][][]
scan0
,
double
[][][]
scan1
,
int
[]
remain
){
// keep scan0 that is not in scan1
double
[][][]
comboScan
=
new
double
[
scan0
.
length
][
scan0
[
0
].
length
][];
for
(
int
nseq
=
0
;
nseq
<
comboScan
.
length
;
nseq
++)
{
int
n
=
0
;
for
(
int
ntile
=
0
;
ntile
<
comboScan
[
nseq
].
length
;
ntile
++)
{
if
((
scan0
[
nseq
][
ntile
]
!=
null
)
&&
(
scan1
[
nseq
][
ntile
]
==
null
))
{
comboScan
[
nseq
][
ntile
]
=
scan0
[
nseq
][
ntile
].
clone
();
n
++;
}
}
if
(
remain
!=
null
)
remain
[
nseq
]
=
n
;
}
return
comboScan
;
}
public
static
double
[][][]
filterMotionScans
(
double
[][][]
scan0
,
double
[][][]
scan1
,
int
[]
remain
){
// keep scan0 that is in scan1
double
[][][]
comboScan
=
new
double
[
scan0
.
length
][
scan0
[
0
].
length
][];
for
(
int
nseq
=
0
;
nseq
<
comboScan
.
length
;
nseq
++)
{
int
n
=
0
;
for
(
int
ntile
=
0
;
ntile
<
comboScan
[
nseq
].
length
;
ntile
++)
{
if
((
scan0
[
nseq
][
ntile
]
!=
null
)
&&
(
scan1
[
nseq
][
ntile
]
!=
null
))
{
comboScan
[
nseq
][
ntile
]
=
scan0
[
nseq
][
ntile
].
clone
();
n
++;
}
}
if
(
remain
!=
null
)
remain
[
nseq
]
=
n
;
}
return
comboScan
;
}
public
static
double
[][][]
filterAndShowTargets
(
double
[][][]
coord_data
,
double
target_strength
,
...
...
@@ -681,38 +1358,78 @@ public class CuasMotion {
String
[]
slice_titles
,
//
String
title_targets_filt
,
int
[]
targets_remain
,
int
tilesX
)
{
// int [] targets_remain = new int [coord_data.length];
int
tilesX
,
boolean
show
)
{
boolean
[][]
good_targets
=
filterTargets
(
coord_data
,
// final double [][][] target_coords,
target_strength
,
// final double target_strength,
target_frac
,
// final double [][] target_frac, // pairs - strength, minimal fraction for that strength
tilesX
,
// final int tilesX,
targets_remain
);
// final int [] remain) {
if
(
targets_remain
!=
null
)
{
for
(
int
nscan
=
0
;
nscan
<
targets_remain
.
length
;
nscan
++)
{
System
.
out
.
print
(
nscan
+
":"
+
targets_remain
[
nscan
]+
", "
);
}
System
.
out
.
println
();
double
[][][]
coord_data_filtered
=
applyFilter
(
coord_data
,
// double [][][] motion_scan,
good_targets
);
// boolean [][] filter5)
if
(
show
)
{
///ImagePlus imp =
showVectorFieldsSequence
(
coord_data_filtered
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_filt
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
tilesX
);
// int tilesX) {
}
return
coord_data_filtered
;
// manually restart with different parameters
}
public
static
double
[][][]
filterAndShowTargetsLMA
(
double
[][][]
coord_data
,
double
lma_rms
,
// = 1.5; // Maximal RMS (should always match, regardless if A)
double
lma_arms
,
// = 0.06; // Maximal absolute RMS (should match one of cuas_lma_arms OR cuas_lma_rrms (0.484)
double
lma_rrms
,
// = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
double
lma_mina
,
// = 1.0; // Minimal A (amplitude)
double
lma_maxr
,
// = 5.0; // Minimal K (overshoot) = 3.0
double
lma_mink
,
// = 0.0; // Minimal K (overshoot) = 1.0
double
lma_maxk
,
// = 5.0; // Minimal K (overshoot) = 3.0
String
[]
slice_titles
,
//
String
title_targets_filt
,
int
[]
targets_remain
,
int
tilesX
,
boolean
show
)
{
double
lma_minxy
=
0.8
;
boolean
[][]
good_targets
=
filterTargetsLMA
(
coord_data
,
// final double [][][] target_coords,
lma_rms
,
// double lma_rms, // = 1.5; // Maximal RMS (should always match, regardless if A)
lma_arms
,
// double lma_arms, // = 0.03; // Maximal absolutre RMS
lma_rrms
,
// double lma_rrms, // = 0.03; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
lma_mina
,
// double lma_mina, // = 1.0; // Minimal A (amplitude)
lma_maxr
,
// double lma_maxr, // = 5.0; // Minimal K (overshoot) = 3.0
lma_mink
,
// double lma_mink, // = 1.0; // Minimal K (overshoot) = 1.0
lma_maxk
,
// double lma_maxk, // = 1.0; // Minimal K (overshoot) = 3.0
lma_minxy
,
// final double lma_minxy, // 0.8
tilesX
,
// final int tilesX,
targets_remain
);
// final int [] remain) {
double
[][][]
coord_data_filtered
=
applyFilter
(
coord_data
,
// double [][][] motion_scan,
good_targets
);
// boolean [][] filter5)
if
(
show
)
{
///ImagePlus imp =
showVectorFieldsSequence
(
coord_data_filtered
,
// double [][][] vector_fields_sequence,
0.0
,
// double speed_min,
0.0
,
// double speed_pref,
1.0
,
// double speed_boost,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_filt
,
// String title,
false
,
// boolean nan_effective_strength,
true
,
// boolean show,
tilesX
);
// int tilesX) {
return
coord_data_filtered
;
// manually restart with different parameters
showVectorFieldsSequenceLMA
(
coord_data_filtered
,
// double [][][] target_scene_sequence,
slice_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
title_targets_filt
,
// String title,
true
,
// boolean show,
tilesX
);
// int tilesX) {
}
return
coord_data_filtered
;
// manually restart with different parameters
}
...
...
@@ -773,12 +1490,30 @@ public class CuasMotion {
return
acc_coord
;
}
public
static
double
[][][]
getAccumulatedCoordinates
(
public
static
double
[][][]
[]
getAccumulatedCoordinates
(
final
double
[][][]
vector_fields
,
// centers
final
float
[][]
accum_data
,
// should be around 0, no low-freq
final
float
[][]
accum_data
,
// should be around 0, no low-freq
final
double
centroid_radius
,
final
int
n_recenter
,
// re-center window around new maximum. 0 -no refines (single-pass)
final
int
tilesX
){
final
int
n_recenter
,
// re-center window around new maximum. 0 -no refines (single-pass)
final
int
tilesX
,
final
boolean
no_border
,
// Moving target LMA
final
double
lma_sigma
,
final
double
lma_r0
,
final
double
lma_ovrsht
,
// CUAS Motion LMA parameters
final
boolean
lma_fit_xy
,
final
boolean
lma_fit_a
,
final
boolean
lma_fit_c
,
final
boolean
lma_fit_r
,
final
boolean
lma_fit_k
,
final
double
lambda
,
final
double
lambda_good
,
final
double
lambda_bad
,
final
double
lambda_max
,
final
double
rms_diff
,
final
int
num_iter
,
final
int
debugLevel
){
final
int
tile2
=
2
*
GPUTileProcessor
.
DTT_SIZE
;
final
int
num_seq
=
vector_fields
.
length
;
// same as accum_data.length
final
int
num_tiles
=
vector_fields
[
0
].
length
;
...
...
@@ -787,12 +1522,26 @@ public class CuasMotion {
final
int
width
=
GPUTileProcessor
.
DTT_SIZE
*
tilesX
;
// final int height = num_pix/width;
final
double
[][][]
acc_coord
=
new
double
[
num_seq
][
num_tiles
][];
final
double
[][][]
lma_coord
=
new
double
[
num_seq
][
num_tiles
][];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
boolean
[]
param_select
=
new
boolean
[
CuasMotionLMA
.
INDX_LEN
];
param_select
[
CuasMotionLMA
.
INDX_X0
]
=
lma_fit_xy
;
param_select
[
CuasMotionLMA
.
INDX_Y0
]
=
lma_fit_xy
;
param_select
[
CuasMotionLMA
.
INDX_A
]
=
lma_fit_a
;
param_select
[
CuasMotionLMA
.
INDX_C
]
=
lma_fit_c
;
param_select
[
CuasMotionLMA
.
INDX_RR0
]
=
lma_fit_r
;
param_select
[
CuasMotionLMA
.
INDX_K
]
=
lma_fit_k
;
final
boolean
[]
fpn_mask
=
no_border
?
(
new
boolean
[
0
])
:
null
;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
double
[]
pix_tile
=
new
double
[
tile2
*
tile2
];
CuasMotionLMA
cuasMotionLMA
=
new
CuasMotionLMA
(
tile2
,
// int width,
lma_sigma
);
// double sigma);
// may be faster if process only where vector_field[nseq][ntile] is not null
for
(
int
nSeq
=
ai
.
getAndIncrement
();
nSeq
<
num_seq
;
nSeq
=
ai
.
getAndIncrement
())
{
for
(
int
ntile
=
0
;
ntile
<
num_tiles
;
ntile
++)
{
...
...
@@ -815,10 +1564,31 @@ public class CuasMotion {
-
tile2
,
// int data_width, // = 2 * transform_size - 1; // negative - will return center fraction
centroid_radius
,
// double radius, // 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
n_recenter
,
// int refine, // re-center window around new maximum. 0 -no refines (single-pass)
null
,
// boolean [] fpn_mask,
fpn_mask
,
// boolean [] fpn_mask,
false
,
// boolean ignore_border, // only if fpn_mask != null - ignore tile if maximum touches fpn_mask
false
);
// boolean debug)
acc_coord
[
nSeq
][
ntile
]
=
mv
;
// no filtering here
if
(
mv
!=
null
)
{
cuasMotionLMA
.
prepareLMA
(
param_select
,
// boolean [] param_select,
pix_tile
,
// double [] tile_data,
mv
[
0
],
// double xc, // relative to center =width/2
mv
[
1
],
// double yc, // relative to center =width/2
lma_r0
,
// double r0,
lma_ovrsht
,
// double k,
debugLevel
);
// int debugLevel)
int
rslt
=
cuasMotionLMA
.
runLma
(
// <0 - failed, >=0 iteration number (1 - immediately)
lambda
,
// double lambda, // 0.1
lambda_good
,
// double lambda_scale_good,// 0.5
lambda_bad
,
// double lambda_scale_bad, // 8.0
lambda_max
,
// double lambda_max, // 100
rms_diff
,
// double rms_diff, // 0.001
num_iter
,
// int num_iter, // 20
debugLevel
);
// int debug_level)
if
(
rslt
>=
0
)
{
lma_coord
[
nSeq
][
ntile
]
=
cuasMotionLMA
.
getResult
();
}
}
}
}
}
...
...
@@ -826,7 +1596,7 @@ public class CuasMotion {
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
acc_coord
;
return
new
double
[][][][]
{
acc_coord
,
lma_coord
}
;
}
public
static
float
[][]
getTargetImages
(
...
...
@@ -935,9 +1705,43 @@ public class CuasMotion {
VF_TOP_TITLES
,
// String [] frame_titles, // frame titles or null
show
);
// boolean show)
return
imp
;
}
public
static
ImagePlus
showVectorFieldsSequenceLMA
(
double
[][][]
target_scene_sequence
,
// rename
String
[]
titles
,
// all slices*frames titles or just slice titles or null
String
title
,
boolean
show
,
int
tilesX
)
{
int
num_fileds
=
CuasMotionLMA
.
LMA_TITLES
.
length
;
int
num_scenes
=
target_scene_sequence
.
length
;
int
num_tiles
=
target_scene_sequence
[
0
].
length
;
double
[][][]
img_data
=
new
double
[
num_fileds
][
num_scenes
][
num_tiles
];
for
(
int
nscene
=
0
;
nscene
<
num_scenes
;
nscene
++)
{
for
(
int
nfiled
=
0
;
nfiled
<
num_fileds
;
nfiled
++)
{
Arrays
.
fill
(
img_data
[
nfiled
][
nscene
],
Double
.
NaN
);
}
for
(
int
ntile
=
0
;
ntile
<
target_scene_sequence
[
nscene
].
length
;
ntile
++)
{
if
(
target_scene_sequence
[
nscene
][
ntile
]
!=
null
)
{
for
(
int
nfield
=
0
;
nfield
<
CuasMotionLMA
.
RSLT_LEN
;
nfield
++)
{
img_data
[
nfield
][
nscene
][
ntile
]
=
target_scene_sequence
[
nscene
][
ntile
][
nfield
];
}
}
}
}
ImagePlus
imp
=
ShowDoubleFloatArrays
.
showArraysHyperstack
(
img_data
,
// double[][][] pixels,
tilesX
,
// int width,
title
,
// String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
CuasMotionLMA
.
LMA_TITLES
,
// String [] frame_titles, // frame titles or null
show
);
// boolean show)
return
imp
;
}
public
static
double
[][][]
getVectorFieldHyper
(
String
path
){
int
[]
wh
=
new
int
[
2
];
...
...
@@ -1025,6 +1829,83 @@ public class CuasMotion {
ImageDtt
.
startAndJoin
(
threads
);
return
filter_target
;
}
public
static
boolean
[][]
filterTargetsLMA
(
final
double
[][][]
target_coords
,
double
lma_rms
,
// = 1.5; // Maximal RMS (should always match, regardless if A)
double
lma_arms
,
// = 0.06; // Maximal absolute RMS (should match one of cuas_lma_arms OR cuas_lma_rrms (0.484)
double
lma_rrms
,
// = 0.15; // Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
double
lma_mina
,
// = 1.0; // Minimal A (amplitude)
double
lma_maxr
,
// = 5.0; // Minimal K (overshoot) = 3.0
double
lma_mink
,
// = 0.0; // Minimal K (overshoot) = 1.0
double
lma_maxk
,
// = 5.0; // Minimal K (overshoot) = 3.0
final
double
lma_minxy
,
// 0.8
final
int
tilesX
,
final
int
[]
remain
)
{
final
int
num_seq
=
target_coords
.
length
;
final
int
num_tiles
=
target_coords
[
0
].
length
;
final
int
tilesY
=
num_tiles
/
tilesX
;
final
boolean
[][]
filter_target
=
new
boolean
[
num_seq
][
num_tiles
];
final
double
maxxy
=
GPUTileProcessor
.
DTT_SIZE
-
1
-
lma_minxy
;
// lma_minxy=1 - prevent bottom row/righth column
final
double
minxy
=
-
GPUTileProcessor
.
DTT_SIZE
+
lma_minxy
;
// lma_minxy=1 - prevent top row/left column
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
nSeq
=
ai
.
getAndIncrement
();
nSeq
<
num_seq
;
nSeq
=
ai
.
getAndIncrement
())
{
int
num
=
0
;
for
(
int
tileY
=
0
;
tileY
<
tilesY
;
tileY
++)
{
for
(
int
tileX
=
0
;
tileX
<
tilesX
;
tileX
++)
{
int
ntile
=
tileX
+
tilesX
*
tileY
;
double
[]
lma_rslts
=
target_coords
[
nSeq
][
ntile
];
if
(
lma_rslts
!=
null
)
{
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_ITERS
]
<
0
)
{
// fitting has not failed
continue
;
// LMA failed
}
double
A
=
lma_rslts
[
CuasMotionLMA
.
RSLT_A
];
if
(
A
<
lma_mina
)
{
continue
;
// too weak
}
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_RMS
]
>
lma_rms
)
{
continue
;
// too high RMSE regardless of A
}
double
max_RMS
=
Math
.
max
(
lma_arms
,
A
*
lma_rrms
);
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_RMS
]
>
max_RMS
)
{
continue
;
// too high RMSE
}
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_R0
]
>
lma_maxr
)
{
continue
;
// Radius is too high
}
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_K
]
<
lma_mink
)
{
continue
;
// K is too low
}
if
(
lma_rslts
[
CuasMotionLMA
.
RSLT_K
]
>
lma_maxk
)
{
continue
;
// K is too high
}
double
x
=
lma_rslts
[
CuasMotionLMA
.
RSLT_X
];
double
y
=
lma_rslts
[
CuasMotionLMA
.
RSLT_Y
];
if
((
x
<
minxy
)
||
(
y
<
minxy
)
||
(
x
>
maxxy
)
||
(
y
>
maxxy
))
{
continue
;
// center outside of allowed range (on the very edges)
}
filter_target
[
nSeq
][
ntile
]
=
true
;
num
++;
}
}
}
if
(
remain
!=
null
)
{
remain
[
nSeq
]
=
num
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
filter_target
;
}
public
static
boolean
[][]
filterMotionScan
(
final
double
[][][]
motion_scan
,
...
...
@@ -1137,7 +2018,7 @@ public class CuasMotion {
final
boolean
[][]
filtered
,
// centers, should be non-overlapped . May be [motion_scan.length][] - will be calculated and returned
final
int
tilesX
,
final
int
range
,
// 1 or 2
final
int
[]
remain
){
final
int
[]
remain
){
// number of center tiles (3x3 groups in the output)
final
int
num_seq
=
motion_scan
.
length
;
final
int
num_tiles
=
motion_scan
[
0
].
length
;
final
int
tilesY
=
num_tiles
/
tilesX
;
...
...
@@ -1522,6 +2403,7 @@ public class CuasMotion {
public
float
[][]
shiftAndRenderAccumulate
(
CLTParameters
clt_parameters
,
final
boolean
zero_fill
,
final
float
[][]
fpixels
,
final
double
[][][]
vector_field
,
final
int
frame0
,
// for vector_field[0]
...
...
@@ -1530,15 +2412,7 @@ public class CuasMotion {
final
boolean
smooth
,
final
int
corr_offset
,
// interframe distance for correlation
final
boolean
batch_mode
)
{
// double magnitude_scale = -1.0; // /(2 * half_step); // here just 1.0 - will use cosine window when accumulating
float
[]
nan_frame
=
new
float
[
fpixels
[
0
].
length
];
// float [][] result_frames = new float [fpixels.length][];
float
[][]
frames_accum
=
new
float
[
vector_field
.
length
][];
Arrays
.
fill
(
nan_frame
,
Float
.
NaN
);
// Arrays.fill(result_frames, nan_frame);
Arrays
.
fill
(
frames_accum
,
nan_frame
);
// int half_step = frame_step/2;
final
double
[]
window_full
=
new
double
[
2
*
half_range
+
1
];
double
s0
=
1.0
;
window_full
[
half_range
]
=
1.0
;
...
...
@@ -1625,6 +2499,9 @@ public class CuasMotion {
for
(
int
nSeq
=
ai
.
getAndIncrement
();
nSeq
<
frames_accum
.
length
;
nSeq
=
ai
.
getAndIncrement
())
{
for
(
int
i
=
0
;
i
<
frames_accum
[
nSeq
].
length
;
i
++)
{
frames_accum
[
nSeq
][
i
]
*=-
1
;
if
(
zero_fill
&&
Double
.
isNaN
(
frames_accum
[
nSeq
][
i
])){
frames_accum
[
nSeq
][
i
]
=
0
f
;
}
}
}
}
...
...
src/main/java/com/elphel/imagej/cuas/CuasMotionLMA.java
0 → 100644
View file @
6dd7be11
package
com
.
elphel
.
imagej
.
cuas
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
com.elphel.imagej.tileprocessor.ImageDtt
;
import
com.elphel.imagej.tileprocessor.QuadCLT
;
import
Jama.Matrix
;
/*
* Use fixed-position relative to initial max gaussian window weight
* fx = A*cos2(r/R0*pi/2)*cos(K*r/R0*pi/2)+C
* K<1, K~=2
* A,K,R0,C
* RR0= pi/(R0*2)
* r=sqrt((x-X0)^2+(y-Y0)^2)
*
* fx = A*cos2(r*RR0)*cos(K*RR0*r)+C
*
*
*
*
*/
public
class
CuasMotionLMA
{
private
static
final
double
R_OFFS
=
1
e
-
6
;
public
static
final
int
INDX_A
=
0
;
public
static
final
int
INDX_C
=
1
;
public
static
final
int
INDX_RR0
=
2
;
public
static
final
int
INDX_K
=
3
;
public
static
final
int
INDX_X0
=
4
;
// relative to left
public
static
final
int
INDX_Y0
=
5
;
// relative to top
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_K
=
4
;
public
static
final
int
RSLT_C
=
5
;
public
static
final
int
RSLT_RMS
=
6
;
public
static
final
int
RSLT_ITERS
=
7
;
public
static
final
int
RSLT_LEN
=
RSLT_ITERS
+
1
;
public
static
final
String
[]
LMA_TITLES
=
{
"X-OFFS"
,
"Y-OFFS"
,
"AMPLITUDE"
,
"RADIUS"
,
"OVERSHOOT"
,
"OFFSET"
,
"RMSE"
,
"ITERATIONS"
};
private
int
width
;
private
double
[][]
window
;
private
double
[]
y_vector
;
private
double
[]
weights
;
private
double
[]
full_vector
=
new
double
[
INDX_LEN
];
private
int
[]
pindx
;
// full parameter index for vector
private
int
[]
rindx
;
// vector index or -1
private
double
[]
last_rms
=
null
;
// {rms, rms_pure}, matching this.vector
private
double
[]
good_or_bad_rms
=
null
;
// just for diagnostics, to read last (failed) rms
private
double
[]
initial_rms
=
null
;
// {rms, rms_pure}, first-calcualted rms
private
double
[]
last_ymfx
=
null
;
private
double
[][]
last_jt
=
null
;
private
int
iters
=
-
2
;
// never ran
public
CuasMotionLMA
(
int
width
,
double
sigma
)
{
this
.
width
=
width
;
window
=
new
double
[
width
][
width
];
double
k
=
-
0.5
/(
sigma
*
sigma
);
for
(
int
i
=
0
;
i
<
width
;
i
++)
{
for
(
int
j
=
0
;
j
<
width
;
j
++)
{
window
[
i
][
j
]
=
Math
.
exp
(
k
*(
i
*
i
+
j
*
j
));
}
}
}
public
int
prepareLMA
(
boolean
[]
param_select
,
double
[]
tile_data
,
double
xc
,
// relative to center =width/2
double
yc
,
// relative to center =width/2
double
r0
,
double
k
,
int
debugLevel
)
{
y_vector
=
tile_data
;
double
x0
=
Math
.
min
(
Math
.
max
(
xc
+
width
/
2
,
0
),
width
-
1
);
double
y0
=
Math
.
min
(
Math
.
max
(
yc
+
width
/
2
,
0
),
width
-
1
);
int
ix0
=
(
int
)
Math
.
round
(
x0
);
int
iy0
=
(
int
)
Math
.
round
(
y0
);
full_vector
[
INDX_A
]
=
tile_data
[
ix0
+
iy0
*
width
];
full_vector
[
INDX_C
]
=
0
;
full_vector
[
INDX_RR0
]
=
Math
.
PI
/(
2
*
r0
);
full_vector
[
INDX_K
]
=
k
;
// > 1 (~2.0)
full_vector
[
INDX_X0
]
=
x0
;
full_vector
[
INDX_Y0
]
=
y0
;
weights
=
new
double
[
width
*
width
];
double
sw
=
0
;
for
(
int
y
=
0
;
y
<
width
;
y
++)
{
int
ay
=
Math
.
abs
(
y
-
iy0
);
for
(
int
x
=
0
;
x
<
width
;
x
++)
{
int
ax
=
Math
.
abs
(
x
-
ix0
);
double
w
=
window
[
ay
][
ax
];
// window to the nearest integer x,y
weights
[
x
+
y
*
width
]
=
w
;
sw
+=
w
;
}
}
for
(
int
i
=
0
;
i
<
weights
.
length
;
i
++)
{
weights
[
i
]
/=
sw
;
}
int
indx
=
0
;
for
(
int
i
=
0
;
i
<
INDX_LEN
;
i
++)
if
(
param_select
[
i
]){
indx
++;
}
rindx
=
new
int
[
INDX_LEN
];
pindx
=
new
int
[
indx
];
indx
=
0
;
for
(
int
i
=
0
;
i
<
INDX_LEN
;
i
++)
{
if
(
param_select
[
i
])
{
pindx
[
indx
]
=
i
;
rindx
[
i
]
=
indx
++;
}
else
{
rindx
[
i
]
=
-
1
;
}
}
last_jt
=
new
double
[
pindx
.
length
][];
double
[]
fx
=
getFxDerivs
(
getParametersVector
(),
// double [] vector,
last_jt
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debugLevel
);
// final int debug_level)
last_rms
=
new
double
[
2
];
last_ymfx
=
getYminusFxWeighted
(
fx
,
// final double [] fx,
last_rms
);
// final double [] rms_fp // null or [2]
initial_rms
=
last_rms
.
clone
();
good_or_bad_rms
=
last_rms
.
clone
();
return
0
;
}
public
double
getRMS
()
{
return
last_rms
[
0
];
}
public
double
getInitialRMS
()
{
return
initial_rms
[
0
];
}
public
double
[]
getResult
()
{
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_K
]
=
getK
();
rslt
[
RSLT_C
]
=
getC
();
rslt
[
RSLT_RMS
]
=
getRMS
();
rslt
[
RSLT_ITERS
]
=
getIters
();
return
rslt
;
}
public
double
[]
getCenter
(){
return
new
double
[]
{
full_vector
[
INDX_X0
]
-
width
/
2
,
full_vector
[
INDX_Y0
]-
width
/
2
};
}
public
double
getRR0
()
{
return
full_vector
[
INDX_RR0
];
}
public
double
getR0
()
{
return
Math
.
PI
/(
2
*
full_vector
[
INDX_RR0
]);
}
public
double
getA
()
{
return
full_vector
[
INDX_A
];
}
public
double
getC
()
{
return
full_vector
[
INDX_C
];
}
public
double
getK
()
{
return
full_vector
[
INDX_K
];
}
public
int
getIters
()
{
return
iters
;
}
public
double
[]
getFullParametersVector
()
{
return
full_vector
;
}
public
double
[]
getParametersVector
()
{
double
[]
vector
=
new
double
[
pindx
.
length
];
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
vector
[
i
]
=
full_vector
[
pindx
[
i
]];
}
return
vector
;
}
public
void
setParametersVector
(
double
[]
vector
)
{
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
full_vector
[
pindx
[
i
]]
=
vector
[
i
];
}
}
public
int
runLma
(
// <0 - failed, >=0 iteration number (1 - immediately)
double
lambda
,
// 0.1
double
lambda_scale_good
,
// 0.5
double
lambda_scale_bad
,
// 8.0
double
lambda_max
,
// 100
double
rms_diff
,
// 0.001
int
num_iter
,
// 20
int
debug_level
)
{
boolean
last_run
=
true
;
boolean
[]
rslt
=
{
false
,
false
};
this
.
last_rms
=
null
;
// remove?
int
iter
=
0
;
for
(
iter
=
0
;
iter
<
num_iter
;
iter
++)
{
rslt
=
lmaStep
(
lambda
,
rms_diff
,
debug_level
);
if
(
rslt
==
null
)
{
iters
=
-
1
;
return
iters
;
}
if
(
debug_level
>
1
)
{
System
.
out
.
println
(
"LMA step "
+
iter
+
": {"
+
rslt
[
0
]+
","
+
rslt
[
1
]+
"} full RMS= "
+
good_or_bad_rms
[
0
]+
" ("
+
initial_rms
[
0
]+
"), pure RMS="
+
good_or_bad_rms
[
1
]+
" ("
+
initial_rms
[
1
]+
") + lambda="
+
lambda
);
}
if
(
rslt
[
1
])
{
break
;
}
if
(
rslt
[
0
])
{
// good
lambda
*=
lambda_scale_good
;
}
else
{
lambda
*=
lambda_scale_bad
;
if
(
lambda
>
lambda_max
)
{
break
;
// not used in lwir
}
}
// if (dbg_prefix != null) {
// showDebugImage(dbg_prefix+"-"+iter+(rslt[0]?"-GOOD":"-BAD"));
// }
}
if
(
rslt
[
0
])
{
// better
if
(
iter
>=
num_iter
)
{
// better, but num tries exceeded
if
(
debug_level
>
1
)
System
.
out
.
println
(
"Step "
+
iter
+
": Improved, but number of steps exceeded maximal"
);
}
else
{
if
(
debug_level
>
1
)
System
.
out
.
println
(
"Step "
+
iter
+
": LMA: Success"
);
}
}
else
{
// improved over initial ?
if
(
last_rms
[
0
]
<
initial_rms
[
0
])
{
// NaN
rslt
[
0
]
=
true
;
if
(
debug_level
>
1
)
System
.
out
.
println
(
"Step "
+
iter
+
": Failed to converge, but result improved over initial"
);
}
else
{
if
(
debug_level
>
1
)
System
.
out
.
println
(
"Step "
+
iter
+
": Failed to converge"
);
}
}
// if (dbg_prefix != null) {
// showDebugImage(dbg_prefix+"-FINAL");
// }
boolean
show_intermediate
=
true
;
if
(
show_intermediate
&&
(
debug_level
>
0
))
{
System
.
out
.
println
(
"LMA: full RMS="
+
last_rms
[
0
]+
" ("
+
initial_rms
[
0
]+
"), pure RMS="
+
last_rms
[
1
]+
" ("
+
initial_rms
[
1
]+
") + lambda="
+
lambda
);
}
if
(
debug_level
>
2
){
// String [] lines1 = printOldNew(false); // boolean allvectors)
// System.out.println("iteration="+iter);
// for (String line : lines1) {
// System.out.println(line);
// }
}
if
(
debug_level
>
0
)
{
if
((
debug_level
>
1
)
||
last_run
)
{
// (iter == 1) || last_run) {
if
(!
show_intermediate
)
{
System
.
out
.
println
(
"LMA: iter="
+
iter
+
", full RMS="
+
last_rms
[
0
]+
" ("
+
initial_rms
[
0
]+
"), pure RMS="
+
last_rms
[
1
]+
" ("
+
initial_rms
[
1
]+
") + lambda="
+
lambda
);
}
// String [] lines = printOldNew(false); // boolean allvectors)
// for (String line : lines) {
// System.out.println(line);
// }
}
}
if
((
debug_level
>
-
2
)
&&
!
rslt
[
0
])
{
// failed
if
((
debug_level
>
1
)
||
(
iter
==
1
)
||
last_run
)
{
System
.
out
.
println
(
"LMA failed on iteration = "
+
iter
);
// String [] lines = printOldNew(true); // boolean allvectors)
// for (String line : lines) {
// System.out.println(line);
// }
}
System
.
out
.
println
();
}
// No need to updateFullParameters() in this implementation - they are already updated
/*
if (rslt[0]) {
updateFullParameters();
}
*/
iters
=
rslt
[
0
]?
iter
:
-
1
;
return
iters
;
}
private
boolean
[]
lmaStep
(
double
lambda
,
double
rms_diff
,
int
debug_level
)
{
boolean
[]
rslt
=
{
false
,
false
};
double
[]
parameters_vector
=
getParametersVector
();
// maybe the following if() branch is not needed - already done in prepareLMA !
if
(
this
.
last_rms
==
null
)
{
//first time, need to calculate all (vector is valid)
last_rms
=
new
double
[
2
];
if
(
debug_level
>
1
)
{
System
.
out
.
println
(
"lmaStep(): first step"
);
}
double
[]
fx
=
getFxDerivs
(
parameters_vector
,
// parameters_vector, // double [] vector,
last_jt
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debug_level
);
// final int debug_level)
last_ymfx
=
getYminusFxWeighted
(
fx
,
// final double [] fx,
last_rms
);
// final double [] rms_fp // null or [2]
this
.
initial_rms
=
this
.
last_rms
.
clone
();
this
.
good_or_bad_rms
=
this
.
last_rms
.
clone
();
if
(
last_ymfx
==
null
)
{
return
null
;
// need to re-init/restart LMA
}
// TODO: Restore/implement
if
(
debug_level
>
3
)
{
double
delta
=
1
E
-
5
;
double
delta_err
=
compareJT
(
parameters_vector
,
// double [] vector,
delta
,
// double delta,
false
);
// last3only); // boolean last3only); // do not process samples - they are tested before
System
.
out
.
println
(
"\nMaximal error = "
+
delta_err
);
/*
dbgJacobians(
corr_vector, // GeometryCorrection.CorrVector corr_vector,
1E-5, // double delta,
true); //boolean graphic)
*/
}
}
if
(
debug_level
>
3
)
{
double
delta
=
1
E
-
5
;
double
delta_err
=
compareJT
(
parameters_vector
,
// double [] vector,
delta
,
// double delta,
false
);
// last3only); // boolean last3only); // do not process samples - they are tested before
System
.
out
.
println
(
"\nMaximal error = "
+
delta_err
);
/*
dbgJacobians(
corr_vector, // GeometryCorrection.CorrVector corr_vector,
1E-5, // double delta,
true); //boolean graphic)
*/
}
Matrix
y_minus_fx_weighted
=
new
Matrix
(
this
.
last_ymfx
,
this
.
last_ymfx
.
length
);
Matrix
wjtjlambda
=
new
Matrix
(
getWJtJlambda
(
lambda
,
// *10, // temporary
this
.
last_jt
));
// double [][] jt)
if
(
debug_level
>
2
)
{
System
.
out
.
println
(
"JtJ + lambda*diag(JtJ"
);
wjtjlambda
.
print
(
18
,
6
);
}
Matrix
jtjl_inv
=
null
;
try
{
jtjl_inv
=
wjtjlambda
.
inverse
();
// check for errors
}
catch
(
RuntimeException
e
)
{
rslt
[
1
]
=
true
;
if
(
debug_level
>
0
)
{
System
.
out
.
println
(
"Singular Matrix!"
);
}
return
rslt
;
}
if
(
debug_level
>
2
)
{
System
.
out
.
println
(
"(JtJ + lambda*diag(JtJ).inv()"
);
jtjl_inv
.
print
(
18
,
6
);
}
//last_jt has NaNs
Matrix
jty
=
(
new
Matrix
(
this
.
last_jt
)).
times
(
y_minus_fx_weighted
);
if
(
debug_level
>
2
)
{
System
.
out
.
println
(
"Jt * (y-fx)"
);
jty
.
print
(
18
,
6
);
}
Matrix
mdelta
=
jtjl_inv
.
times
(
jty
);
if
(
debug_level
>
2
)
{
System
.
out
.
println
(
"mdelta"
);
mdelta
.
print
(
18
,
10
);
}
double
scale
=
1.0
;
double
[]
delta
=
mdelta
.
getColumnPackedCopy
();
double
[]
new_vector
=
parameters_vector
.
clone
();
for
(
int
i
=
0
;
i
<
parameters_vector
.
length
;
i
++)
{
new_vector
[
i
]
+=
scale
*
delta
[
i
];
}
double
[]
fx
=
getFxDerivs
(
new_vector
,
// double [] vector,
last_jt
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debug_level
);
// final int debug_level)
double
[]
rms
=
new
double
[
2
];
last_ymfx
=
getYminusFxWeighted
(
fx
,
// final double [] fx,
rms
);
// final double [] rms_fp // null or [2]
if
(
debug_level
>
2
)
{
/*
dbgYminusFx(this.last_ymfx, "next y-fX");
dbgXY(new_vector, "XY-correction");
*/
}
if
(
last_ymfx
==
null
)
{
return
null
;
// need to re-init/restart LMA
}
this
.
good_or_bad_rms
=
rms
.
clone
();
if
(
rms
[
0
]
<
this
.
last_rms
[
0
])
{
// improved
rslt
[
0
]
=
true
;
rslt
[
1
]
=
rms
[
0
]
>=(
this
.
last_rms
[
0
]
*
(
1.0
-
rms_diff
));
this
.
last_rms
=
rms
.
clone
();
parameters_vector
=
new_vector
.
clone
();
setParametersVector
(
new_vector
);
if
(
debug_level
>
2
)
{
// print vectors in some format
/*
System.out.print("delta: "+corr_delta.toString()+"\n");
System.out.print("New vector: "+new_vector.toString()+"\n");
System.out.println();
*/
}
}
else
{
// worsened
rslt
[
0
]
=
false
;
rslt
[
1
]
=
false
;
// do not know, caller will decide
// restore state
fx
=
getFxDerivs
(
parameters_vector
,
// double [] vector,
last_jt
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debug_level
);
// final int debug_level)
last_ymfx
=
getYminusFxWeighted
(
fx
,
// final double [] fx,
this
.
last_rms
);
// final double [] rms_fp // null or [2]
if
(
last_ymfx
==
null
)
{
return
null
;
// need to re-init/restart LMA
}
if
(
debug_level
>
2
)
{
/*
dbgJacobians(
corr_vector, // GeometryCorrection.CorrVector corr_vector,
1E-5, // double delta,
true); //boolean graphic)
*/
}
}
return
rslt
;
}
private
double
[][]
getWJtJlambda
(
// USED in lwir
final
double
lambda
,
final
double
[][]
jt
)
{
final
int
num_pars
=
jt
.
length
;
final
int
nup_points
=
jt
[
0
].
length
;
final
double
[][]
wjtjl
=
new
double
[
num_pars
][
num_pars
];
for
(
int
i
=
0
;
i
<
num_pars
;
i
++)
{
for
(
int
j
=
i
;
j
<
num_pars
;
j
++)
{
double
d
=
0.0
;
for
(
int
k
=
0
;
k
<
nup_points
;
k
++)
{
// if (jt[i][k] != 0) {
// d+=0; // ???
// }
d
+=
weights
[
k
]*
jt
[
i
][
k
]*
jt
[
j
][
k
];
if
(
Double
.
isNaN
(
d
))
{
System
.
out
.
println
(
"CuasMotionLMA.getWJtJlambda(): NAN i="
+
i
+
", j="
+
j
+
", k="
+
k
);
}
}
wjtjl
[
i
][
j
]
=
d
;
if
(
i
==
j
)
{
wjtjl
[
i
][
j
]
+=
d
*
lambda
;
}
else
{
wjtjl
[
j
][
i
]
=
d
;
}
}
}
return
wjtjl
;
}
private
double
[]
getYminusFxWeighted
(
// problems. at least with eigen?
final
double
[]
fx
,
final
double
[]
rms_fp
)
{
// null or [2]
final
double
[]
wymfw
=
new
double
[
fx
.
length
];
double
s_rms
=
0.0
;
for
(
int
i
=
0
;
i
<
fx
.
length
;
i
++)
{
double
d
=
y_vector
[
i
]
-
fx
[
i
];
double
wd
=
d
*
weights
[
i
];
wymfw
[
i
]
=
wd
;
s_rms
+=
d
*
wd
;
}
double
rms
=
Math
.
sqrt
(
s_rms
);
// assuming sum_weights == 1.0; /pure_weight); they should be re-normalized after adding regularization
if
(
rms_fp
!=
null
)
{
rms_fp
[
0
]
=
rms
;
if
(
rms_fp
.
length
>
1
)
{
rms_fp
[
1
]
=
rms
;
// _pure;
}
}
return
wymfw
;
}
private
double
compareJT
(
double
[]
vector
,
double
delta
,
boolean
last3only
)
{
// do not process samples - they are tested before
double
[]
errors
=
new
double
[
vector
.
length
];
double
[][]
jt
=
new
double
[
vector
.
length
][];
System
.
out
.
print
(
"Parameters vector = ["
);
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
vector
[
i
]);
if
(
i
<
(
vector
.
length
-
1
))
System
.
out
.
print
(
", "
);
}
System
.
out
.
println
(
"]"
);
getFxDerivs
(
vector
,
jt
,
// final double [][] jt, // should be null or initialized with [vector.length][]
1
);
// debug_level);
double
[][]
jt_delta
=
getFxDerivsDelta
(
vector
,
// double [] vector,
delta
,
// final double delta,
-
1
);
// final int debug_level)
int
start_index
=
last3only
?
(
weights
.
length
-
3
)
:
0
;
for
(
int
n
=
start_index
;
n
<
weights
.
length
;
n
++)
if
(
weights
[
n
]
>
0
)
{
System
.
out
.
print
(
String
.
format
(
"%3d"
,
n
));
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
String
.
format
(
"\t%12.9f"
,
jt
[
i
][
n
]));
}
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
String
.
format
(
"\t%12.9f"
,
jt_delta
[
i
][
n
]));
}
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
String
.
format
(
"\t%12.9f"
,
jt
[
i
][
n
]-
jt_delta
[
i
][
n
]));
}
System
.
out
.
println
();
/*
System.out.println(String.format(
"%3d\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f\t%12.9f",
n, jt[0][n], jt[1][n], jt[2][n], jt[3][n],
jt_delta[0][n], jt_delta[1][n], jt_delta[2][n], jt_delta[3][n],
jt[0][n]-jt_delta[0][n],jt[1][n]-jt_delta[1][n],jt[2][n]-jt_delta[2][n],jt[3][n]-jt_delta[3][n]));
*/
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
errors
[
i
]
=
Math
.
max
(
errors
[
i
],
jt
[
i
][
n
]-
jt_delta
[
i
][
n
]);
}
}
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
"\t\t"
);
}
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
System
.
out
.
print
(
String
.
format
(
"\t%12.9f"
,
errors
[
i
]));
}
/*
System.out.println(String.format(
"-\t-\t-\t-\t-\t-\t-\t-\t-\t%12.9f\t%12.9f\t%12.9f\t%12.9f",
errors[0], errors[1], errors[2], errors[3]));
*/
double
err
=
0
;
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
err
=
Math
.
max
(
errors
[
i
],
err
);
}
return
err
;
}
private
double
[][]
getFxDerivsDelta
(
double
[]
vector
,
final
double
delta
,
final
int
debug_level
)
{
double
[][]
jt
=
new
double
[
vector
.
length
][
weights
.
length
];
for
(
int
nv
=
0
;
nv
<
vector
.
length
;
nv
++)
{
double
[]
vpm
=
vector
.
clone
();
vpm
[
nv
]+=
0.5
*
delta
;
double
[]
fx_p
=
getFxDerivs
(
vpm
,
null
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debug_level
);
vpm
[
nv
]-=
delta
;
double
[]
fx_m
=
getFxDerivs
(
vpm
,
null
,
// final double [][] jt, // should be null or initialized with [vector.length][]
debug_level
);
for
(
int
i
=
0
;
i
<
weights
.
length
;
i
++)
if
(
weights
[
i
]
>
0
)
{
jt
[
nv
][
i
]
=
(
fx_p
[
i
]-
fx_m
[
i
])/
delta
;
}
}
return
jt
;
}
private
double
[]
getFxDerivs
(
final
double
[]
vector
,
final
double
[][]
jt
,
// should be null or initialized with [vector.length][]
final
int
debug_level
)
{
int
height
=
y_vector
.
length
/
width
;
final
double
[]
fx
=
new
double
[
y_vector
.
length
];
if
(
jt
!=
null
)
{
for
(
int
i
=
0
;
i
<
jt
.
length
;
i
++)
{
jt
[
i
]
=
new
double
[
y_vector
.
length
];
// weights.length];
}
}
double
A
=
(
rindx
[
INDX_A
]
>=
0
)?
vector
[
rindx
[
INDX_A
]]
:
full_vector
[
INDX_A
]
;
double
C
=
(
rindx
[
INDX_C
]
>=
0
)?
vector
[
rindx
[
INDX_C
]]
:
full_vector
[
INDX_C
]
;
double
RR0
=
(
rindx
[
INDX_RR0
]
>=
0
)?
vector
[
rindx
[
INDX_RR0
]]
:
full_vector
[
INDX_RR0
]
;
double
K
=
(
rindx
[
INDX_K
]
>=
0
)?
vector
[
rindx
[
INDX_K
]]
:
full_vector
[
INDX_K
]
;
// >1.0
double
X0
=
(
rindx
[
INDX_X0
]
>=
0
)?
vector
[
rindx
[
INDX_X0
]]
:
full_vector
[
INDX_X0
]
;
double
Y0
=
(
rindx
[
INDX_Y0
]
>=
0
)?
vector
[
rindx
[
INDX_Y0
]]
:
full_vector
[
INDX_Y0
]
;
for
(
int
y
=
0
;
y
<
height
;
y
++)
{
double
dy
=
y
-
Y0
;
double
dy2
=
dy
*
dy
;
for
(
int
x
=
0
;
x
<
width
;
x
++)
{
int
indx
=
y
*
width
+
x
;
double
dx
=
x
-
X0
;
double
dx2
=
dx
*
dx
;
double
r2
=
dx2
+
dy2
+
R_OFFS
;
double
r
=
Math
.
sqrt
(
r2
);
if
(
r
*
RR0
>
Math
.
PI
/
2
)
{
// outside circle where function is defined
fx
[
indx
]
=
C
;
if
(
jt
!=
null
)
{
double
df_dC
=
1
;
if
(
rindx
[
INDX_C
]
>=
0
)
{
jt
[
rindx
[
INDX_C
]][
indx
]
=
df_dC
;
}
}
}
else
{
double
W1
=
Math
.
cos
(
r
*
RR0
);
double
W2
=
Math
.
cos
(
r
*
RR0
*
K
);
fx
[
indx
]
=
A
*
(
W1
*
W1
*
W2
)
+
C
;
if
(
jt
!=
null
)
{
double
dr2_dX0
=
-
2
*
dx
;
double
dr2_dY0
=
-
2
*
dy
;
double
dr_dr2
=
0.5
/
r
;
// r !=0
double
sin_rRR0
=
Math
.
sin
(
r
*
RR0
);
double
dW1_dRR0
=
-
r
*
sin_rRR0
;
//
double
dW1_dr
=
-
RR0
*
sin_rRR0
;
double
sin_rKRR0
=
Math
.
sin
(
r
*
RR0
*
K
);
double
dW2_dRR0
=
-
K
*
r
*
sin_rKRR0
;
double
dW2_dK
=
-
r
*
RR0
*
sin_rKRR0
;
double
dW2_dr
=
-
K
*
RR0
*
sin_rKRR0
;
double
df_dA
=
W1
*
W1
*
W2
;
// +
double
df_dC
=
1
;
// +
double
df_dW1
=
2
*
A
*
W1
*
W2
;
double
df_dW2
=
A
*
W1
*
W1
;
double
df_dK
=
df_dW2
*
dW2_dK
;
double
df_dRR0
=
df_dW1
*
dW1_dRR0
+
df_dW2
*
dW2_dRR0
;
double
df_dr
=
df_dW1
*
dW1_dr
+
df_dW2
*
dW2_dr
;
double
df_dr2
=
df_dr
*
dr_dr2
;
double
df_dX0
=
df_dr2
*
dr2_dX0
;
double
df_dY0
=
df_dr2
*
dr2_dY0
;
double
[]
df_dfp
=
{
df_dA
,
df_dC
,
df_dRR0
,
df_dK
,
df_dX0
,
df_dY0
};
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
{
jt
[
i
][
indx
]
=
df_dfp
[
pindx
[
i
]];
}
}
}
}
}
return
fx
;
}
}
src/main/java/com/elphel/imagej/tileprocessor/Correlation2d.java
View file @
6dd7be11
...
...
@@ -2422,12 +2422,18 @@ public class Correlation2d {
boolean
ignore_border
,
// only if fpn_mask != null - ignore tile if maximum touches fpn_mask
boolean
debug
)
{
boolean
exclude_margins
=
false
;
if
((
fpn_mask
!=
null
)
&&
(
fpn_mask
.
length
==
0
))
{
exclude_margins
=
true
;
fpn_mask
=
null
;
}
boolean
calc_fraction
=
data_width
<
0
;
if
(
calc_fraction
)
{
data_width
=
-
data_width
;
}
int
data_height
=
data
.
length
/
data_width
;
int
center_xy
=
(
data_width
-
1
)/
2
;
// = transform_size - 1;
// int center_xy = (data_width - 1)/2; // = transform_size - 1;
int
center_xy
=
data_width
/
2
;
// = transform_size - 1;
double
x0
=
center_xy
,
y0
=
center_xy
;
int
imax
=
0
;
for
(
int
i
=
1
;
i
<
data
.
length
;
i
++)
{
...
...
@@ -2438,6 +2444,12 @@ public class Correlation2d {
double
mx
=
data
[
imax
];
int
ix0
=
imax
%
data_width
;
int
iy0
=
imax
/
data_width
;
if
(
exclude_margins
)
{
if
((
ix0
==
0
)
||
(
iy0
==
0
)
||
(
ix0
==
(
data_width
-
1
))
||
(
iy0
==
(
data_height
-
1
)))
{
return
null
;
// maximum is on the tile border.
}
}
x0
=
ix0
;
y0
=
iy0
;
// if (fpn_mask != null
...
...
src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java
View file @
6dd7be11
...
...
@@ -716,8 +716,33 @@ min_str_neib_fpn 0.35
public
double
cuas_target_radius
=
3.0
;
// target centroids center radius
public
double
cuas_target_strength
=
0.8
;
// target centroids center radius
public
double
[][]
cuas_target_frac
=
{{
0
,
0.15
},{
2
,
0.3
},{
5
,
0.4
}};
public
boolean
cuas_no_border
=
true
;
// exclude targets with centers on the 16x16 tile edges
// CUAS Motion LMA parameters
public
double
cuas_lma_sigma
=
3.0
;
public
double
cuas_lma_r0
=
3.0
;
//maximum with with overshoot
public
double
cuas_lma_ovrsht
=
2.0
;
public
boolean
cuas_lma_fit_xy
=
true
;
public
boolean
cuas_lma_fit_a
=
true
;
public
boolean
cuas_lma_fit_c
=
true
;
public
boolean
cuas_lma_fit_r
=
true
;
public
boolean
cuas_lma_fit_k
=
true
;
public
double
cuas_lambda
=
0.1
;
public
double
cuas_lambda_good
=
0.5
;
public
double
cuas_lambda_bad
=
8
;
public
double
cuas_lambda_max
=
100
;
public
double
cuas_rms_diff
=
0.001
;
// relative RMS improvement
public
int
cuas_num_iter
=
20
;
// CUAS Motion LMA filter parameters
public
double
cuas_lma_rms
=
1.5
;
// Maximal RMS (should always match, regardless if A)
public
double
cuas_lma_arms
=
0.06
;
// Maximal absolute RMS (should match one of cuas_lma_arms OR cuas_lma_rrms (0.484)
public
double
cuas_lma_rrms
=
0.15
;
// Maximal relative to A rms. OK is when (RMS < cuas_lma_arms) || (RMS < cuas_lma_rrms * A)
public
double
cuas_lma_mina
=
1.0
;
// Minimal A (amplitude) = 1.0 (< 2.0)
public
double
cuas_lma_maxr
=
5.0
;
// Maximal R (radius) =5.0 (> 3.8)
public
double
cuas_lma_mink
=
0.0
;
// Minimal K (overshoot) = 0.0 (<0.007)
public
double
cuas_lma_maxk
=
5.0
;
// Maximal K (overshoot) = 5.0 (>3.8)
public
boolean
cuas_debug
=
false
;
// save debug images (and show them if not in batch mode)
public
boolean
cuas_step_debug
=
false
;
// save debug images during per-step cuas recalculation (and show them if not in batch mode)
...
...
@@ -2157,6 +2182,61 @@ min_str_neib_fpn 0.35
"Minimal value of the target image."
);
gd
.
addStringField
(
"Fraction for strengths"
,
double2dToString
(
this
.
cuas_target_frac
),
100
,
"Variable number of (strength, fraction) pairs separated by \":\". Each pair of strength, minimal fraction is separated by \",\"."
);
gd
.
addCheckbox
(
"Target not on the tile edge"
,
this
.
cuas_no_border
,
"Exclude targets with centers on the edge of 16x16 tiles."
);
gd
.
addMessage
(
"=== Moving target LMA ==="
);
gd
.
addNumericField
(
"Weight Gaussian sigma"
,
this
.
cuas_lma_sigma
,
5
,
8
,
"pix"
,
"Weights to emphasize maximum center area when fitting."
);
gd
.
addNumericField
(
"Target typical radius"
,
this
.
cuas_lma_r0
,
5
,
8
,
"pix"
,
"Typical target radius including negative overshoot (caused by UM filter)."
);
gd
.
addNumericField
(
"Target maximum overshoot"
,
this
.
cuas_lma_ovrsht
,
5
,
8
,
""
,
"Hos much smaller is the first zero than total maximum with overshoot (2.0 - first zero radius 1/2 of the full."
);
gd
.
addCheckbox
(
"LMA fit X,Y"
,
this
.
cuas_lma_fit_xy
,
"Fit target center position."
);
gd
.
addCheckbox
(
"LMA fit amplitude (strength)"
,
this
.
cuas_lma_fit_a
,
"Fit maximum amplitude."
);
gd
.
addCheckbox
(
"LMA fit offset"
,
this
.
cuas_lma_fit_c
,
"Fit out-of-maximum level (offset)."
);
gd
.
addCheckbox
(
"LMA fit radius"
,
this
.
cuas_lma_fit_r
,
"Fit target total radius - includes negative overshoot caused by UM filter."
);
gd
.
addCheckbox
(
"LMA fit overshoot"
,
this
.
cuas_lma_fit_k
,
"Fit target overshoot (2.0 - first zero crossing at half radius."
);
gd
.
addMessage
(
"--- Moving target LMA fitting parameters ---"
);
gd
.
addNumericField
(
"LMA lambda"
,
this
.
cuas_lambda
,
5
,
8
,
""
,
"LMA initial lambda."
);
gd
.
addNumericField
(
"Scale lambda after success"
,
this
.
cuas_lambda_good
,
5
,
8
,
""
,
"Multiply lambda if RMS decreaed."
);
gd
.
addNumericField
(
"Scale lambda after failure"
,
this
.
cuas_lambda_bad
,
5
,
8
,
""
,
"Multiply lambda if RMS increaed."
);
gd
.
addNumericField
(
"Maximal lambda"
,
this
.
cuas_lambda_max
,
5
,
8
,
""
,
"Give up if lambda gets higher value."
);
gd
.
addNumericField
(
"Relative RMS improvement"
,
this
.
cuas_rms_diff
,
5
,
8
,
""
,
"Finish fitting when the relative RMS improvement drops below this value."
);
gd
.
addNumericField
(
"LMA iterations"
,
this
.
cuas_num_iter
,
0
,
3
,
""
,
"Maximal number of the LMA iterations."
);
gd
.
addMessage
(
"--- Moving target discrimination parameters theresholds ---"
);
gd
.
addNumericField
(
"Maximal RMS"
,
this
.
cuas_lma_rms
,
5
,
8
,
""
,
"Maximal RMS for target that should match always, regardless of the amplitude."
);
gd
.
addNumericField
(
"Maximal sufficient RMS"
,
this
.
cuas_lma_arms
,
5
,
8
,
""
,
"Maximal sufficient RMS for target. Satisfying any of the sufficient or relative is enough"
);
gd
.
addNumericField
(
"Maximal relative RMS"
,
this
.
cuas_lma_rrms
,
5
,
8
,
""
,
"Maximal relative (to amplitude) RMS for target. Satisfying any of the absolute and relative is sufficient"
);
gd
.
addNumericField
(
"Minimal target amplitude"
,
this
.
cuas_lma_mina
,
5
,
8
,
""
,
"Filter out weak targets."
);
gd
.
addNumericField
(
"Maximal radius"
,
this
.
cuas_lma_maxr
,
5
,
8
,
"pix"
,
"Maximal target radius including negative overshoot."
);
gd
.
addNumericField
(
"Minimal overshoot ratio"
,
this
.
cuas_lma_mink
,
5
,
8
,
""
,
"Minimal ratio of the overshoot radius to the first 0 radius (typical 1.0)."
);
gd
.
addNumericField
(
"Maximal overshoot ratio"
,
this
.
cuas_lma_maxk
,
5
,
8
,
""
,
"Maximal ratio of the overshoot radius to the first 0 radius (typical 3.0)."
);
gd
.
addMessage
(
"=== Debug ==="
);
gd
.
addCheckbox
(
"Save/show debug images"
,
this
.
cuas_debug
,
...
...
@@ -2170,8 +2250,6 @@ min_str_neib_fpn 0.35
"Overwrite value (when Overwrite... is checked)."
);
gd
.
addNumericField
(
"Value to overwrote num_accum"
,
this
.
cuas_num_accum
,
0
,
3
,
""
,
"Overwrite value (when Overwrite... is checked)."
);
gd
.
addTab
(
"LMA sequence"
,
"Interscene LMA sequence control"
);
gd
.
addMessage
(
"Parameters for control of the LMA pose adjustment sequence"
);
...
...
@@ -3125,6 +3203,29 @@ min_str_neib_fpn 0.35
this
.
cuas_target_radius
=
gd
.
getNextNumber
();
this
.
cuas_target_strength
=
gd
.
getNextNumber
();
this
.
cuas_target_frac
=
stringToDouble2d
(
gd
.
getNextString
());
this
.
cuas_no_border
=
gd
.
getNextBoolean
();
this
.
cuas_lma_sigma
=
gd
.
getNextNumber
();
this
.
cuas_lma_r0
=
gd
.
getNextNumber
();
this
.
cuas_lma_ovrsht
=
gd
.
getNextNumber
();
this
.
cuas_lma_fit_xy
=
gd
.
getNextBoolean
();
this
.
cuas_lma_fit_a
=
gd
.
getNextBoolean
();
this
.
cuas_lma_fit_c
=
gd
.
getNextBoolean
();
this
.
cuas_lma_fit_r
=
gd
.
getNextBoolean
();
this
.
cuas_lma_fit_k
=
gd
.
getNextBoolean
();
this
.
cuas_lambda
=
gd
.
getNextNumber
();
this
.
cuas_lambda_good
=
gd
.
getNextNumber
();
this
.
cuas_lambda_bad
=
gd
.
getNextNumber
();
this
.
cuas_lambda_max
=
gd
.
getNextNumber
();
this
.
cuas_rms_diff
=
gd
.
getNextNumber
();
this
.
cuas_num_iter
=
(
int
)
gd
.
getNextNumber
();
this
.
cuas_lma_rms
=
gd
.
getNextNumber
();
this
.
cuas_lma_arms
=
gd
.
getNextNumber
();
this
.
cuas_lma_rrms
=
gd
.
getNextNumber
();
this
.
cuas_lma_mina
=
gd
.
getNextNumber
();
this
.
cuas_lma_maxr
=
gd
.
getNextNumber
();
this
.
cuas_lma_mink
=
gd
.
getNextNumber
();
this
.
cuas_lma_maxk
=
gd
.
getNextNumber
();
this
.
cuas_debug
=
gd
.
getNextBoolean
();
this
.
cuas_step_debug
=
gd
.
getNextBoolean
();
...
...
@@ -4018,6 +4119,29 @@ min_str_neib_fpn 0.35
properties
.
setProperty
(
prefix
+
"cuas_target_radius"
,
this
.
cuas_target_radius
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_target_strength"
,
this
.
cuas_target_strength
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_target_frac"
,
double2dToString
(
cuas_target_frac
)+
""
);
// double[][]
properties
.
setProperty
(
prefix
+
"cuas_no_border"
,
this
.
cuas_no_border
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lma_sigma"
,
this
.
cuas_lma_sigma
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_r0"
,
this
.
cuas_lma_r0
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_ovrsht"
,
this
.
cuas_lma_ovrsht
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_fit_xy"
,
this
.
cuas_lma_fit_xy
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lma_fit_a"
,
this
.
cuas_lma_fit_a
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lma_fit_c"
,
this
.
cuas_lma_fit_c
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lma_fit_r"
,
this
.
cuas_lma_fit_r
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lma_fit_k"
,
this
.
cuas_lma_fit_k
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_lambda"
,
this
.
cuas_lambda
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lambda_good"
,
this
.
cuas_lambda_good
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lambda_bad"
,
this
.
cuas_lambda_bad
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lambda_max"
,
this
.
cuas_lambda_max
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_rms_diff"
,
this
.
cuas_rms_diff
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_num_iter"
,
this
.
cuas_num_iter
+
""
);
// int
properties
.
setProperty
(
prefix
+
"cuas_lma_rms"
,
this
.
cuas_lma_rms
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_arms"
,
this
.
cuas_lma_arms
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_rrms"
,
this
.
cuas_lma_rrms
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_mina"
,
this
.
cuas_lma_mina
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_maxr"
,
this
.
cuas_lma_maxr
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_mink"
,
this
.
cuas_lma_mink
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_lma_maxk"
,
this
.
cuas_lma_maxk
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_debug"
,
this
.
cuas_debug
+
""
);
// boolean
properties
.
setProperty
(
prefix
+
"cuas_step_debug"
,
this
.
cuas_step_debug
+
""
);
// boolean
...
...
@@ -4883,6 +5007,30 @@ min_str_neib_fpn 0.35
if
(
properties
.
getProperty
(
prefix
+
"cuas_target_radius"
)!=
null
)
this
.
cuas_target_radius
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_target_radius"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_target_strength"
)!=
null
)
this
.
cuas_target_strength
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_target_strength"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_target_frac"
)!=
null
)
cuas_target_frac
=
stringToDouble2d
((
String
)
properties
.
getProperty
(
prefix
+
"cuas_target_frac"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_no_border"
)!=
null
)
this
.
cuas_no_border
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_no_border"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_sigma"
)!=
null
)
this
.
cuas_lma_sigma
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_sigma"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_r0"
)!=
null
)
this
.
cuas_lma_r0
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_r0"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_ovrsht"
)!=
null
)
this
.
cuas_lma_ovrsht
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_ovrsht"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_xy"
)!=
null
)
this
.
cuas_lma_fit_xy
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_xy"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_a"
)!=
null
)
this
.
cuas_lma_fit_a
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_a"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_c"
)!=
null
)
this
.
cuas_lma_fit_c
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_c"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_r"
)!=
null
)
this
.
cuas_lma_fit_r
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_r"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_k"
)!=
null
)
this
.
cuas_lma_fit_k
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"cuas_lma_fit_k"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lambda"
)!=
null
)
this
.
cuas_lambda
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lambda"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_good"
)!=
null
)
this
.
cuas_lambda_good
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_good"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_bad"
)!=
null
)
this
.
cuas_lambda_bad
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_bad"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_max"
)!=
null
)
this
.
cuas_lambda_max
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lambda_max"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_rms_diff"
)!=
null
)
this
.
cuas_rms_diff
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_rms_diff"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_num_iter"
)!=
null
)
this
.
cuas_num_iter
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"cuas_num_iter"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_rms"
)!=
null
)
this
.
cuas_lma_rms
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_rms"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_arms"
)!=
null
)
this
.
cuas_lma_arms
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_arms"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_rrms"
)!=
null
)
this
.
cuas_lma_rrms
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_rrms"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_mina"
)!=
null
)
this
.
cuas_lma_mina
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_mina"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_maxr"
)!=
null
)
this
.
cuas_lma_maxr
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_maxr"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_mink"
)!=
null
)
this
.
cuas_lma_mink
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_mink"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_lma_maxk"
)!=
null
)
this
.
cuas_lma_maxk
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_lma_maxk"
));
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"
));
...
...
@@ -5748,6 +5896,29 @@ min_str_neib_fpn 0.35
for
(
int
i
=
0
;
i
<
this
.
cuas_target_frac
.
length
;
i
++)
{
imp
.
cuas_target_frac
[
i
]
=
this
.
cuas_target_frac
[
i
].
clone
();
}
imp
.
cuas_no_border
=
this
.
cuas_no_border
;
imp
.
cuas_lma_sigma
=
this
.
cuas_lma_sigma
;
imp
.
cuas_lma_r0
=
this
.
cuas_lma_r0
;
imp
.
cuas_lma_ovrsht
=
this
.
cuas_lma_ovrsht
;
imp
.
cuas_lma_fit_xy
=
this
.
cuas_lma_fit_xy
;
imp
.
cuas_lma_fit_a
=
this
.
cuas_lma_fit_a
;
imp
.
cuas_lma_fit_c
=
this
.
cuas_lma_fit_c
;
imp
.
cuas_lma_fit_r
=
this
.
cuas_lma_fit_r
;
imp
.
cuas_lma_fit_k
=
this
.
cuas_lma_fit_k
;
imp
.
cuas_lambda
=
this
.
cuas_lambda
;
imp
.
cuas_lambda_good
=
this
.
cuas_lambda_good
;
imp
.
cuas_lambda_bad
=
this
.
cuas_lambda_bad
;
imp
.
cuas_lambda_max
=
this
.
cuas_lambda_max
;
imp
.
cuas_rms_diff
=
this
.
cuas_rms_diff
;
imp
.
cuas_num_iter
=
this
.
cuas_num_iter
;
imp
.
cuas_lma_rms
=
this
.
cuas_lma_rms
;
imp
.
cuas_lma_arms
=
this
.
cuas_lma_arms
;
imp
.
cuas_lma_rrms
=
this
.
cuas_lma_rrms
;
imp
.
cuas_lma_mina
=
this
.
cuas_lma_mina
;
imp
.
cuas_lma_maxr
=
this
.
cuas_lma_maxr
;
imp
.
cuas_lma_mink
=
this
.
cuas_lma_mink
;
imp
.
cuas_lma_maxk
=
this
.
cuas_lma_maxk
;
imp
.
cuas_debug
=
this
.
cuas_debug
;
imp
.
cuas_step_debug
=
this
.
cuas_step_debug
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment