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
904ad2bc
Commit
904ad2bc
authored
Jul 19, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented/debugged photometric sensors matching
parent
5a125530
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
395 additions
and
46 deletions
+395
-46
IntersceneMatchParameters.java
...lphel/imagej/tileprocessor/IntersceneMatchParameters.java
+10
-6
OpticalFlow.java
...ain/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
+74
-2
QuadCLT.java
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
+171
-1
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+140
-37
No files found.
src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java
View file @
904ad2bc
...
...
@@ -475,7 +475,7 @@ public class IntersceneMatchParameters {
String
[]
stereo_choices
=
new
String
[
stereo_views
.
length
+
1
];
stereo_choices
[
0
]
=
"--none--"
;
for
(
int
i
=
0
;
i
<
stereo_views
.
length
;
i
++)
{
stereo_choices
[
i
+
1
]
=
doublesToString
(
stereo_views
[
i
])+
" mm"
;
stereo_choices
[
i
+
1
]
=
doublesToString
(
stereo_views
[
i
]
,
"%.0f"
)+
" mm"
;
}
gd
.
addChoice
(
"Remove stereo-view (base, up, back)"
,
stereo_choices
,
stereo_choices
[
0
],
"Remove selected stereo-view, consisting of streo-base, viewpoint above camera, viewpoint behing camera - all in mm"
);
...
...
@@ -1031,7 +1031,7 @@ public class IntersceneMatchParameters {
*/
properties
.
setProperty
(
prefix
+
"stereo_views_num"
,
this
.
stereo_views
.
length
+
""
);
// int
for
(
int
i
=
0
;
i
<
this
.
stereo_views
.
length
;
i
++)
{
properties
.
setProperty
(
prefix
+
"stereo_views_"
+
i
,
doublesToString
(
this
.
stereo_views
[
i
]));
// String
properties
.
setProperty
(
prefix
+
"stereo_views_"
+
i
,
doublesToString
(
this
.
stereo_views
[
i
]
,
"%.0f"
));
// String
properties
.
setProperty
(
prefix
+
"generate_stereo_var_"
+
i
,
this
.
generate_stereo_var
[
i
]+
""
);
// boolean
}
...
...
@@ -1785,12 +1785,16 @@ public class IntersceneMatchParameters {
return
doublesToString
(
data
,
null
);
}
public
static
String
doublesToString
(
double
[]
data
,
String
fmt
)
{
if
((
fmt
==
null
)
||
(
fmt
.
trim
().
length
()==
0
))
{
fmt
=
"%.0f"
;
}
//
if ((fmt == null) || (fmt.trim().length()==0)) {
//
fmt = "%.0f";
//
}
String
s
=
""
;
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
if
(
fmt
==
null
)
{
s
+=
data
[
i
];
// unformatted
}
else
{
s
+=
String
.
format
(
fmt
,
data
[
i
]);
}
if
(
i
<
(
data
.
length
-
1
))
{
s
+=
", "
;
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
View file @
904ad2bc
...
...
@@ -4045,6 +4045,7 @@ public class OpticalFlow {
boolean
export_images
=
clt_parameters
.
imp
.
export_images
;
boolean
export_dsi_image
=
clt_parameters
.
imp
.
export_ranges
;
boolean
export_ml_files
=
clt_parameters
.
imp
.
export_ml_files
;
boolean
calibrate_photometric
=
true
;
boolean
show_dsi_image
=
clt_parameters
.
imp
.
show_ranges
&&
!
batch_mode
;
boolean
show_images
=
clt_parameters
.
imp
.
show_images
&&
!
batch_mode
;
...
...
@@ -4424,7 +4425,9 @@ public class OpticalFlow {
}
else
{
// if (build_orientations) {
if
(!
reuse_video
)
{
// reuse_video only uses reference scene
for
(
int
scene_index
=
ref_index
-
1
;
scene_index
>=
earliest_scene
;
scene_index
--)
{
quadCLTs
[
scene_index
]
=
(
QuadCLT
)
quadCLT_main
.
spawnNoModelQuadCLT
(
// restores image data
// quadCLTs[scene_index] = (QuadCLT) quadCLT_main.spawnNoModelQuadCLT( // restores image data
// to include ref scene photometric calibration
quadCLTs
[
scene_index
]
=
quadCLTs
[
ref_index
].
spawnNoModelQuadCLT
(
// restores image data
set_channels
[
scene_index
].
set_name
,
clt_parameters
,
colorProcParameters
,
//
...
...
@@ -4504,6 +4507,62 @@ public class OpticalFlow {
}
}
if
(
calibrate_photometric
)
{
if
(
combo_dsn_final
==
null
)
{
// always re-read?
combo_dsn_final
=
quadCLTs
[
ref_index
].
readDoubleArrayFromModelDirectory
(
// always re-read?
"-INTER-INTRA-LMA"
,
// String suffix,
0
,
// int num_slices, // (0 - all)
null
);
// int [] wh);
}
double
[][]
combo_dsn_final_filtered
=
conditionComboDsnFinal
(
true
,
// boolean use_conf, // use configuration parameters, false - use following
clt_parameters
,
// CLTParameters clt_parameters,
combo_dsn_final
,
// double [][] combo_dsn_final, // dls,
quadCLTs
[
ref_index
],
// QuadCLT scene,
debugLevel
);
// int debugLevel);// > 0
QuadCLT
.
calibratePhotometric
(
clt_parameters
,
// CLTParameters clt_parameters,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
0.0
,
// final double min_strength,
100.0
,
// final double max_diff, // 30.0
2
,
// final int num_refines, // 2
combo_dsn_final_filtered
,
// final double [][] combo_dsn_final, // double [][] combo_dsn_final, // dls,
threadsMax
,
// int threadsMax,
true
);
//final boolean debug)
// copy offsets to the current to be saved with other properties. Is it correct/needed?
quadCLTs
[
ref_index
].
saveInterProperties
(
// save properties for interscene processing (extrinsics, ers, ...)
null
,
// String path, // full name with extension or w/o path to use x3d directory
debugLevel
+
1
);
quadCLT_main
.
setLwirOffsets
(
quadCLTs
[
ref_index
].
getLwirOffsets
());
quadCLT_main
.
setLwirScales
(
quadCLTs
[
ref_index
].
getLwirScales
());
// Re-read reference and other scenes using new offsets
quadCLTs
[
ref_index
]
=
(
QuadCLT
)
quadCLT_main
.
spawnQuadCLT
(
// restores dsi from "DSI-MAIN"
set_channels
[
ref_index
].
set_name
,
clt_parameters
,
colorProcParameters
,
//
threadsMax
,
debugLevel
);
quadCLTs
[
ref_index
].
setDSRBG
(
clt_parameters
,
// CLTParameters clt_parameters,
threadsMax
,
// int threadsMax, // maximal number of threads to launch
updateStatus
,
// boolean updateStatus,
debugLevel
);
// int debugLevel)
ers_reference
=
quadCLTs
[
ref_index
].
getErsCorrection
();
if
(!
reuse_video
)
{
// reuse_video only uses reference scene
for
(
int
scene_index
=
ref_index
-
1
;
scene_index
>=
earliest_scene
;
scene_index
--)
{
// quadCLTs[scene_index] = (QuadCLT) quadCLT_main.spawnNoModelQuadCLT( // restores image data
// to include ref scene photometric calibration
quadCLTs
[
scene_index
]
=
quadCLTs
[
ref_index
].
spawnNoModelQuadCLT
(
// restores image data
set_channels
[
scene_index
].
set_name
,
clt_parameters
,
colorProcParameters
,
//
threadsMax
,
debugLevel
-
2
);
}
}
}
if
(
test_ers
)
{
// only debug feature
test_ers0
=
quadCLTs
.
length
-
1
;
// make it always == reference !
...
...
@@ -5025,6 +5084,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// toRGB, // final boolean toRGB,
clt_parameters
.
imp
.
show_color_nan
,
// boolean show_nan
"GPU-SHIFTED-D"
+
clt_parameters
.
disparity
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5042,6 +5102,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// toRGB, // final boolean toRGB,
clt_parameters
.
imp
.
show_mono_nan
,
// boolean show_nan
"GPU-SHIFTED-D"
+
clt_parameters
.
disparity
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5121,6 +5182,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// toRGB, // final boolean toRGB,
clt_parameters
.
imp
.
show_color_nan
,
scenes_suffix
+
"GPU-SHIFTED-FOREGROUND"
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5138,6 +5200,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// toRGB, // final boolean toRGB,
clt_parameters
.
imp
.
show_mono_nan
,
scenes_suffix
+
"GPU-SHIFTED-FOREGROUND"
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5164,6 +5227,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_color_nan
,
"GPU-SHIFTED-BACKGROUND"
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5181,6 +5245,7 @@ public class OpticalFlow {
quadCLTs
[
ref_index
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_mono_nan
,
"GPU-SHIFTED-BACKGROUND"
,
// String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5244,6 +5309,7 @@ public class OpticalFlow {
}
}
if
(
export_ml_files
)
{
if
(
combo_dsn_final
==
null
)
{
// always re-read?
combo_dsn_final
=
quadCLTs
[
ref_index
].
readDoubleArrayFromModelDirectory
(
// always re-read?
...
...
@@ -5381,6 +5447,8 @@ public class OpticalFlow {
quadCLTs
[
nscene
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_color_nan
,
""
,
// String suffix, no suffix here
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5403,6 +5471,7 @@ public class OpticalFlow {
quadCLTs
[
nscene
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_mono_nan
,
""
,
// String suffix, no suffix here
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5516,6 +5585,7 @@ public class OpticalFlow {
quadCLTs
[
nscene
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_color_nan
,
""
,
// String suffix, no suffix here
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5538,6 +5608,7 @@ public class OpticalFlow {
quadCLTs
[
nscene
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// final boolean toRGB,
clt_parameters
.
imp
.
show_mono_nan
,
""
,
// String suffix, no suffix here
threadsMax
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
@@ -5702,6 +5773,7 @@ public class OpticalFlow {
quadCLTs
[
nscene
],
// final QuadCLT scene,
quadCLTs
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
toRGB
,
// final boolean toRGB,
(
toRGB
?
clt_parameters
.
imp
.
show_color_nan
:
clt_parameters
.
imp
.
show_mono_nan
),
""
,
// String suffix, no suffix here
QuadCLT
.
THREADS_MAX
,
// int threadsMax,
debugLevel
);
// int debugLevel)
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
View file @
904ad2bc
...
...
@@ -2169,6 +2169,175 @@ public class QuadCLT extends QuadCLTCPU {
IJ
.
d2s
(
0.000000001
*(
System
.
nanoTime
()-
this
.
startTime
),
3
)+
" sec, --- Free memory3="
+
Runtime
.
getRuntime
().
freeMemory
()+
" (of "
+
Runtime
.
getRuntime
().
totalMemory
()+
")"
);
}
public
static
boolean
calibratePhotometric
(
CLTParameters
clt_parameters
,
final
QuadCLT
ref_scene
,
// now - may be null - for testing if scene is rotated ref
final
double
min_strength
,
final
double
max_diff
,
// 30.0
final
int
num_refines
,
// 2
final
double
[][]
combo_dsn_final
,
// double [][] combo_dsn_final, // dls,
int
threadsMax
,
final
boolean
debug
)
{
// filter disparity by LMA only, same bg and fg
double
[]
disparity_ref
=
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_DISP
].
clone
();
for
(
int
i
=
00
;
i
<
disparity_ref
.
length
;
i
++)
{
if
(
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_STRENGTH
][
i
]
<
min_strength
)
{
disparity_ref
[
i
]
=
Double
.
NaN
;
}
else
if
(
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_DISP_BG_ALL
][
i
]
!=
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_DISP
][
i
])
{
disparity_ref
[
i
]
=
Double
.
NaN
;
}
}
ImagePlus
img_ref
=
renderGPUFromDSI
(
-
1
,
// final int sensor_mask,
false
,
// final boolean merge_channels,
null
,
// final Rectangle full_woi_in, // show larger than sensor WOI in tiles (or null)
clt_parameters
,
// CLTParameters clt_parameters,
disparity_ref
,
// double [] disparity_ref,
OpticalFlow
.
ZERO3
,
// final double [] scene_xyz, // camera center in world coordinates
OpticalFlow
.
ZERO3
,
// final double [] scene_atr, // camera orientation relative to world frame
ref_scene
,
// final QuadCLT scene,
ref_scene
,
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false
,
// final boolean toRGB,
true
,
// final boolean show_nan,
"PHOTOMETRIC"
,
// String suffix,
threadsMax
,
// int threadsMax,
-
2
);
// final int debugLevel);
img_ref
.
show
();
ImageStack
imageStack
=
img_ref
.
getStack
();
int
num_sens
=
imageStack
.
getSize
();
float
[]
fpixels
;
double
[][]
dpixels
=
new
double
[
num_sens
][];
for
(
int
n
=
00
;
n
<
num_sens
;
n
++)
{
fpixels
=
(
float
[])
imageStack
.
getPixels
(
n
+
1
);
dpixels
[
n
]
=
new
double
[
fpixels
.
length
];
for
(
int
i
=
0
;
i
<
fpixels
.
length
;
i
++)
{
dpixels
[
n
][
i
]
=
fpixels
[
i
];
}
}
// double [][] dpix_orig = new double[num_sens][];
// for (int n = 0; n < num_sens; n++) {
// dpix_orig[n] = dpixels[n].clone();
// }
int
width
=
img_ref
.
getWidth
();
int
height
=
img_ref
.
getHeight
();
int
len
=
width
*
height
;
double
[]
avg_pix
=
new
double
[
len
];
double
[]
offsets
=
new
double
[
dpixels
.
length
];
double
[]
scales
=
new
double
[
dpixels
.
length
];
double
s0
=
0.0
;
double
sx
=
0.0
;
double
sx2
=
0.0
;
double
[]
sy
=
new
double
[
num_sens
];
double
[]
sxy
=
new
double
[
num_sens
];
boolean
[]
good_pix
=
new
boolean
[
len
];
Arrays
.
fill
(
good_pix
,
true
);
for
(
int
nref
=
0
;
nref
<
num_refines
;
nref
++)
{
Arrays
.
fill
(
avg_pix
,
0.0
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
avg_pix
[
i
]+=
dpixels
[
n
][
i
];
good_pix
[
i
]
&=
!
Double
.
isNaN
(
dpixels
[
n
][
i
]);
}
avg_pix
[
i
]
/=
dpixels
.
length
;
}
Arrays
.
fill
(
offsets
,
0.0
);
Arrays
.
fill
(
scales
,
0.0
);
s0
=
0.0
;
sx
=
0.0
;
sx2
=
0.0
;
Arrays
.
fill
(
sy
,
0.0
);
Arrays
.
fill
(
sxy
,
0.0
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
if
(
good_pix
[
i
])
{
// !Double.isNaN(avg_pix[i])){
s0
+=
1.0
;
sx
+=
avg_pix
[
i
];
sx2
+=
avg_pix
[
i
]
*
avg_pix
[
i
];
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
sy
[
n
]
+=
dpixels
[
n
][
i
];
sxy
[
n
]
+=
dpixels
[
n
][
i
]
*
avg_pix
[
i
];
}
}
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
double
d
=
s0
*
sx2
+
sx
*
sy
[
n
];
scales
[
n
]
=
(
sxy
[
n
]
*
s0
+
sy
[
n
]
*
sy
[
n
])
/
d
;
offsets
[
n
]
=
(
sy
[
n
]
*
sx2
-
sxy
[
n
]*
sx
)
/
d
;
}
if
(
debug
)
{
System
.
out
.
println
(
"calibratePhotometric() nref="
+
nref
);
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
System
.
out
.
println
(
String
.
format
(
"%2d: %8.4f %8.6f"
,
n
,
offsets
[
n
],
scales
[
n
]));
}
System
.
out
.
println
();
double
[][]
diffs
=
new
double
[
num_sens
][
len
];
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
Arrays
.
fill
(
diffs
[
n
],
Double
.
NaN
);
}
for
(
int
i
=
0
;
i
<
len
;
i
++)
if
(
good_pix
[
i
])
{
// if (!Double.isNaN(avg_pix[i])){
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
diffs
[
n
][
i
]
=
dpixels
[
n
][
i
]
-
(
scales
[
n
]
*
avg_pix
[
i
]
+
offsets
[
n
]);
}
}
(
new
ShowDoubleFloatArrays
()).
showArrays
(
// out of boundary 15
diffs
,
width
,
height
,
true
,
"photometric-err"
+
nref
);
// dpix_orig[n] = dpixels[n].clone();
double
[][]
corrected
=
new
double
[
num_sens
][
len
];
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
Arrays
.
fill
(
corrected
[
n
],
Double
.
NaN
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
if
(!
Double
.
isNaN
(
dpixels
[
n
][
i
])){
corrected
[
n
][
i
]
=
(
dpixels
[
n
][
i
]
-
offsets
[
n
])/
scales
[
n
];
}
}
(
new
ShowDoubleFloatArrays
()).
showArrays
(
// out of boundary 15
corrected
,
width
,
height
,
true
,
"photometric-corr"
+
nref
);
}
//max_diff
if
(
nref
<
(
num_refines
-
1
))
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
if
(
good_pix
[
i
])
{
// !Double.isNaN(avg_pix[i])){
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
double
diff
=
Math
.
abs
(
dpixels
[
n
][
i
]
-
(
scales
[
n
]
*
avg_pix
[
i
]
+
offsets
[
n
]));
if
(
diff
>
max_diff
)
{
// dpixels[n][i] = Double.NaN;
good_pix
[
i
]
=
false
;
break
;
}
}
}
}
}
double
[]
offsets_old
=
ref_scene
.
getLwirOffsets
();
double
[]
scales_old
=
ref_scene
.
getLwirScales
();
double
[]
offsets_new
=
new
double
[
num_sens
];
double
[]
scales_new
=
new
double
[
num_sens
];
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
scales_new
[
n
]
=
scales_old
[
n
]/
scales
[
n
];
// offsets_new[n] = offsets_old[n] - offsets[n] / scales_old[n];
offsets_new
[
n
]
=
offsets_old
[
n
]
+
offsets
[
n
]
/
scales_old
[
n
];
}
System
.
out
.
println
(
"calibratePhotometric() Updated calibration:"
);
for
(
int
n
=
0
;
n
<
num_sens
;
n
++)
{
System
.
out
.
println
(
String
.
format
(
"%2d: %8.4f %8.6f"
,
n
,
offsets_new
[
n
],
scales_new
[
n
]));
}
System
.
out
.
println
();
ref_scene
.
setLwirOffsets
(
offsets_new
);
ref_scene
.
setLwirScales
(
scales_new
);
return
true
;
}
public
static
ImagePlus
renderGPUFromDSI
(
final
int
sensor_mask
,
final
boolean
merge_channels
,
...
...
@@ -2182,10 +2351,11 @@ public class QuadCLT extends QuadCLTCPU {
final
QuadCLT
scene
,
final
QuadCLT
ref_scene
,
// now - may be null - for testing if scene is rotated ref
final
boolean
toRGB
,
final
boolean
show_nan
,
String
suffix
,
int
threadsMax
,
final
int
debugLevel
){
boolean
show_nan
=
toRGB
?
clt_parameters
.
imp
.
show_color_nan
:
clt_parameters
.
imp
.
show_mono_nan
;
//
boolean show_nan = toRGB? clt_parameters.imp.show_color_nan : clt_parameters.imp.show_mono_nan;
double
[][]
pXpYD
=
OpticalFlow
.
transformToScenePxPyD
(
// now should work with offset ref_scene
full_woi_in
,
// final Rectangle [] extra_woi, // show larger than sensor WOI (or null)
disparity_ref
,
// final double [] disparity_ref, // invalid tiles - NaN in disparity
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
904ad2bc
...
...
@@ -151,6 +151,7 @@ public class QuadCLTCPU {
boolean
[][]
saturation_imp
=
null
;
// (near) saturated pixels or null
boolean
is_aux
=
false
;
double
[]
lwir_offsets
=
null
;
// per image subtracted values
double
[]
lwir_scales
=
null
;
// per image scales
double
lwir_offset
=
Double
.
NaN
;
// average of lwir_offsets[]
// hot and cold are calculated during autoranging (when generating 4 images for restored (added lwir_offset)
// absolute temperatures to be used instead of colorProcParameters lwir_low and lwir_high if autoranging
...
...
@@ -261,6 +262,7 @@ public class QuadCLTCPU {
this
.
is_aux
=
qParent
.
is_aux
;
// this.is_mono = qParent.is_mono;
this
.
lwir_offsets
=
ErsCorrection
.
clone1d
(
qParent
.
lwir_offsets
);
this
.
lwir_scales
=
ErsCorrection
.
clone1d
(
qParent
.
lwir_scales
);
this
.
lwir_offset
=
qParent
.
lwir_offset
;
this
.
lwir_cold_hot
=
ErsCorrection
.
clone1d
(
qParent
.
lwir_cold_hot
);
this
.
ds_from_main
=
ErsCorrection
.
clone2d
(
qParent
.
ds_from_main
);
...
...
@@ -1478,6 +1480,37 @@ public class QuadCLTCPU {
public
double
getLwirOffset
()
{
return
lwir_offset
;}
// USED in lwir
public
boolean
isLwirCalibrated
()
{
return
lwir_offsets
!=
null
;
}
public
double
[]
getLwirOffsets
()
{
if
(
lwir_offsets
==
null
)
{
lwir_offsets
=
new
double
[
getNumSensors
()];
}
return
lwir_offsets
;
}
public
double
[]
getLwirScales
()
{
if
(
lwir_scales
==
null
)
{
lwir_scales
=
new
double
[
getNumSensors
()];
Arrays
.
fill
(
lwir_scales
,
1.0
);
}
return
lwir_scales
;
}
public
void
setLwirOffsets
(
double
[]
offsets
)
{
lwir_offsets
=
offsets
;
// will need to update properties!
if
(
offsets
!=
null
)
{
double
s
=
0
;
for
(
double
offset:
offsets
)
s
+=
offset
;
lwir_offset
=
s
/
offsets
.
length
;
}
else
{
lwir_offset
=
Double
.
NaN
;
}
}
public
void
setLwirScales
(
double
[]
scales
)
{
lwir_scales
=
scales
;
// will need to update properties!
}
public
double
[]
getColdHot
()
{
// USED in lwir
return
lwir_cold_hot
;
}
...
...
@@ -1668,6 +1701,14 @@ public class QuadCLTCPU {
}
properties
.
setProperty
(
prefix
+
"num_orient"
,
this
.
num_orient
+
""
);
properties
.
setProperty
(
prefix
+
"num_accum"
,
this
.
num_accum
+
""
);
if
(
this
.
lwir_offsets
!=
null
)
{
properties
.
setProperty
(
prefix
+
"lwir_offsets"
,
IntersceneMatchParameters
.
doublesToString
(
this
.
lwir_offsets
));
}
if
(
this
.
lwir_scales
!=
null
)
{
properties
.
setProperty
(
prefix
+
"lwir_scales"
,
IntersceneMatchParameters
.
doublesToString
(
this
.
lwir_scales
));
}
}
...
...
@@ -1697,7 +1738,19 @@ public class QuadCLTCPU {
this
.
num_accum
=
Integer
.
parseInt
(
other_properties
.
getProperty
(
other_prefix
+
"num_accum"
));
properties
.
setProperty
(
this_prefix
+
"num_accum"
,
this
.
num_accum
+
""
);
}
// copy offsets and scales
if
(
other_properties
.
getProperty
(
other_prefix
+
"lwir_offsets"
)!=
null
)
{
this
.
lwir_offsets
=
IntersceneMatchParameters
.
StringToDoubles
(
other_properties
.
getProperty
(
other_prefix
+
"lwir_offsets"
),
0
);
properties
.
setProperty
(
this_prefix
+
"lwir_offsets"
,
IntersceneMatchParameters
.
doublesToString
(
this
.
lwir_offsets
));
}
if
(
other_properties
.
getProperty
(
other_prefix
+
"lwir_scales"
)!=
null
)
{
this
.
lwir_scales
=
IntersceneMatchParameters
.
StringToDoubles
(
other_properties
.
getProperty
(
other_prefix
+
"lwir_scales"
),
0
);
properties
.
setProperty
(
this_prefix
+
"lwir_scales"
,
IntersceneMatchParameters
.
doublesToString
(
this
.
lwir_scales
));
}
/*
...
...
@@ -1803,8 +1856,24 @@ public class QuadCLTCPU {
geometryCorrection
.
setRigOffsetFromProperies
(
prefix
,
properties
);
}
// inter-frame properties only make sense for, well, scenes. So they will only be read
if
(
properties
.
getProperty
(
prefix
+
"num_orient"
)!=
null
)
this
.
num_orient
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"num_orient"
));
if
(
properties
.
getProperty
(
prefix
+
"num_accum"
)!=
null
)
this
.
num_accum
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"num_accum"
));
if
(
properties
.
getProperty
(
prefix
+
"num_orient"
)!=
null
)
{
this
.
num_orient
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"num_orient"
));
}
if
(
properties
.
getProperty
(
prefix
+
"num_accum"
)!=
null
)
{
this
.
num_accum
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"num_accum"
));
}
if
(
properties
.
getProperty
(
prefix
+
"lwir_offsets"
)!=
null
)
{
this
.
lwir_offsets
=
IntersceneMatchParameters
.
StringToDoubles
(
properties
.
getProperty
(
prefix
+
"lwir_offsets"
),
0
);
}
if
(
properties
.
getProperty
(
prefix
+
"lwir_scales"
)!=
null
)
{
this
.
lwir_scales
=
IntersceneMatchParameters
.
StringToDoubles
(
properties
.
getProperty
(
prefix
+
"lwir_scales"
),
0
);
}
}
public
void
setKernelImageFile
(
ImagePlus
img_kernels
){
// not used in lwir
...
...
@@ -4889,6 +4958,7 @@ public class QuadCLTCPU {
boolean
lwir_subtract_dc
=
colorProcParameters
.
lwir_subtract_dc
;
boolean
lwir_eq_chn
=
colorProcParameters
.
lwir_eq_chn
;
boolean
correct_vignetting
=
colorProcParameters
.
correct_vignetting
;
boolean
recalc_lwir_offsets
=
false
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
threadsMax
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
...
...
@@ -5176,13 +5246,16 @@ public class QuadCLTCPU {
debugLevel
);
}
if
(
is_lwir
&&
(
lwir_subtract_dc
||
lwir_eq_chn
))
{
this
.
lwir_offsets
=
channelLwirEqualize
(
if
(
recalc_lwir_offsets
||
!
isLwirCalibrated
())
{
// this.lwir_offsets =
setLwirOffsets
(
channelLwirEqualize
(
// now only calculates offsets, does not apply
channelFiles
,
imp_srcs
,
lwir_subtract_dc
,
// boolean remove_dc,
set_name
,
// just for debug messages == setNames.get(nSet)
threadsMax
,
debugLevel
);
debugLevel
)
);
int
num_avg
=
0
;
this
.
lwir_offset
=
0.0
;
for
(
int
srcChannel
=
0
;
srcChannel
<
channelFiles
.
length
;
srcChannel
++){
...
...
@@ -5194,6 +5267,16 @@ public class QuadCLTCPU {
}
this
.
lwir_offset
/=
num_avg
;
}
double
[]
offsets
=
getLwirOffsets
();
double
[]
scales
=
getLwirScales
();
channelLwirApplyEqualize
(
// now apply (was part of channelLwirEqualize() )
channelFiles
,
// int [] channelFiles,
imp_srcs
,
// ImagePlus [] imp_srcs,
offsets
,
// double [] offsets,
scales
,
// double [] scales,
threadsMax
,
debugLevel
);
}
// 08/12/2020 common part moved here, from getRigImageStacks()
image_name
=
(
String
)
imp_srcs
[
0
].
getProperty
(
"name"
);
image_path
=
(
String
)
imp_srcs
[
0
].
getProperty
(
"path"
);
...
...
@@ -5686,6 +5769,7 @@ public class QuadCLTCPU {
}
}
}
public
static
double
[]
channelLwirEqualize
(
// USED in lwir
int
[]
channelFiles
,
ImagePlus
[]
imp_srcs
,
...
...
@@ -5705,11 +5789,7 @@ public class QuadCLTCPU {
public
void
run
()
{
double
[]
wnd_x
;
double
[]
wnd_y
;
// for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
for
(
int
srcChannel
=
ai
.
getAndIncrement
();
srcChannel
<
channelFiles
.
length
;
srcChannel
=
ai
.
getAndIncrement
())
{
// for (int srcChannel=0; srcChannel < channelFiles.length; srcChannel++){
int
nFile
=
channelFiles
[
srcChannel
];
if
(
nFile
>=
0
){
avr_pix
[
srcChannel
][
0
]
=
0.0
;
...
...
@@ -5717,18 +5797,14 @@ public class QuadCLTCPU {
float
[]
pixels
=(
float
[])
imp_srcs
[
srcChannel
].
getProcessor
().
getPixels
();
int
width
=
imp_srcs
[
srcChannel
].
getWidth
();
int
height
=
imp_srcs
[
srcChannel
].
getHeight
();
// if (wnd_x.length != width) {
wnd_x
=
new
double
[
width
];
for
(
int
i
=
0
;
i
<
width
;
i
++)
{
wnd_x
[
i
]
=
0.5
-
0.5
*
Math
.
cos
(
2
*
Math
.
PI
*
(
i
+
1
)
/
(
width
+
1
));
}
// }
// if (wnd_y.length != height) {
wnd_y
=
new
double
[
height
];
for
(
int
i
=
0
;
i
<
height
;
i
++)
{
wnd_y
[
i
]
=
0.5
-
0.5
*
Math
.
cos
(
2
*
Math
.
PI
*
(
i
+
1
)
/
(
height
+
1
));
}
// }
int
indx
=
0
;
for
(
int
y
=
0
;
y
<
height
;
y
++)
{
for
(
int
x
=
0
;
x
<
width
;
x
++)
{
...
...
@@ -5737,8 +5813,6 @@ public class QuadCLTCPU {
avr_pix
[
srcChannel
][
1
]
+=
w
;
}
}
// total_s += avr_pix[srcChannel][0];
// total_w += avr_pix[srcChannel][1];
atotal_s
.
accumulate
(
avr_pix
[
srcChannel
][
0
]);
atotal_w
.
accumulate
(
avr_pix
[
srcChannel
][
1
]);
avr_pix
[
srcChannel
][
0
]/=
avr_pix
[
srcChannel
][
1
];
// weighted average
...
...
@@ -5748,7 +5822,6 @@ public class QuadCLTCPU {
};
}
ImageDtt
.
startAndJoin
(
threads
);
// double avg = total_s/total_w;
double
avg
=
atotal_s
.
get
()/
atotal_w
.
get
();
if
(!
remove_dc
)
{
// not used in lwir
...
...
@@ -5766,12 +5839,41 @@ public class QuadCLTCPU {
for
(
int
srcChannel
=
ai
.
getAndIncrement
();
srcChannel
<
channelFiles
.
length
;
srcChannel
=
ai
.
getAndIncrement
())
{
int
nFile
=
channelFiles
[
srcChannel
];
if
(
nFile
>=
0
)
{
// offsets[srcChannel]= (avr_pix[srcChannel][0] - (remove_dc ? 0.0: avg));
offsets
[
srcChannel
]=
avr_pix
[
srcChannel
][
0
];
// float fd = (float)offsets[srcChannel];
// float [] pixels = (float []) imp_srcs[srcChannel].getProcessor().getPixels();
// for (int i = 0; i < pixels.length; i++) {
// pixels[i] -= fd;
// }
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
offsets
;
}
public
static
void
channelLwirApplyEqualize
(
int
[]
channelFiles
,
ImagePlus
[]
imp_srcs
,
double
[]
offsets
,
double
[]
scales
,
final
int
threadsMax
,
int
debugLevel
){
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
threadsMax
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
srcChannel
=
ai
.
getAndIncrement
();
srcChannel
<
channelFiles
.
length
;
srcChannel
=
ai
.
getAndIncrement
())
{
int
nFile
=
channelFiles
[
srcChannel
];
if
(
nFile
>=
0
)
{
float
fd
=
(
float
)
offsets
[
srcChannel
];
float
fscale
=
(
float
)
scales
[
srcChannel
];
float
[]
pixels
=
(
float
[])
imp_srcs
[
srcChannel
].
getProcessor
().
getPixels
();
for
(
int
i
=
0
;
i
<
pixels
.
length
;
i
++)
{
pixels
[
i
]
-=
fd
;
pixels
[
i
]
=
(
pixels
[
i
]
-
fd
)
*
fscale
;
}
}
}
...
...
@@ -5779,9 +5881,10 @@ public class QuadCLTCPU {
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
offsets
;
}
// public ImagePlus [] processCLTQuadCorrCPU( // USED in lwir
public
void
processCLTQuadCorrCPU
(
// USED in lwir
// ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
...
...
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