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
da579ebb
Commit
da579ebb
authored
Jul 29, 2025
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enhancing moving targets
parent
4e5e1f22
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1890 additions
and
175 deletions
+1890
-175
ShowDoubleFloatArrays.java
.../java/com/elphel/imagej/common/ShowDoubleFloatArrays.java
+257
-34
Eyesis_Correction.java
.../java/com/elphel/imagej/correction/Eyesis_Correction.java
+95
-0
CorrectionFPN.java
src/main/java/com/elphel/imagej/cuas/CorrectionFPN.java
+1
-1
CuasData.java
src/main/java/com/elphel/imagej/cuas/CuasData.java
+1
-1
CuasMotion.java
src/main/java/com/elphel/imagej/cuas/CuasMotion.java
+1267
-0
GpuQuad.java
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
+76
-4
ComboMatch.java
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java
+17
-15
Correlation2d.java
...n/java/com/elphel/imagej/tileprocessor/Correlation2d.java
+27
-5
IntersceneMatchParameters.java
...lphel/imagej/tileprocessor/IntersceneMatchParameters.java
+97
-2
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+9
-88
TDCorrTile.java
...main/java/com/elphel/imagej/tileprocessor/TDCorrTile.java
+41
-23
VegetationSynthesis.java
...ava/com/elphel/imagej/vegetation/VegetationSynthesis.java
+2
-2
No files found.
src/main/java/com/elphel/imagej/common/ShowDoubleFloatArrays.java
View file @
da579ebb
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/correction/Eyesis_Correction.java
View file @
da579ebb
...
...
@@ -109,6 +109,7 @@ import com.elphel.imagej.common.DoubleGaussianBlur;
import
com.elphel.imagej.common.GenericJTabbedDialog
;
import
com.elphel.imagej.common.ShowDoubleFloatArrays
;
import
com.elphel.imagej.common.WindowTools
;
import
com.elphel.imagej.cuas.CuasMotion
;
import
com.elphel.imagej.dct.FactorConvKernel
;
import
com.elphel.imagej.gpu.GPUTileProcessor
;
import
com.elphel.imagej.gpu.GpuQuad
;
...
...
@@ -905,6 +906,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
addJButton
(
"UAS log"
,
jpanelOrange
,
color_process
);
addJButton
(
"DJI SRT"
,
jpanelOrange
,
color_process
);
addJButton
(
"SRT to KML"
,
jpanelOrange
,
color_process
);
addJButton
(
"Motion_CUAS"
,
jpanelOrange
,
color_stop
);
addJButton
(
"Motion_scan"
,
jpanelOrange
,
color_stop
);
//
plugInJFrame
.
add
(
jpanelOrange
);
}
...
...
@@ -1484,6 +1487,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
b
.
addActionListener
(
this
);
b
.
addKeyListener
(
IJ
.
getInstance
());
b
.
setToolTipText
(
label
);
panel
.
add
(
b
);
}
...
...
@@ -6285,6 +6289,26 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
testDjiSrt
();
}
else
if
(
label
.
equals
(
"SRT to KML"
))
{
djiSrtToKml
();
}
else
if
(
label
.
equals
(
"Motion_CUAS"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
!=
null
)
{
motion_cuas
(
imp_sel
,
0
);
// int mode));
}
else
{
System
.
out
.
println
(
"No image selected"
);
}
}
else
if
(
label
.
equals
(
"Motion_scan"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
!=
null
)
{
motion_cuas
(
imp_sel
,
1
);
// int mode));
}
else
{
System
.
out
.
println
(
"No image selected"
);
}
}
}
...
...
@@ -6328,7 +6352,78 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
return
true
;
}
public
static
boolean
motion_cuas
(
ImagePlus
imp_sel
,
int
mode
)
{
// long startTime = System.nanoTime();
// load needed sensor and kernels files
setAllProperties
(
PROPERTIES
);
// batchRig may save properties with the model. Extrinsics will be updated,
if
(
GPU_TILE_PROCESSOR
==
null
)
{
try
{
GPU_TILE_PROCESSOR
=
new
GPUTileProcessor
(
CORRECTION_PARAMETERS
.
tile_processor_gpu
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Failed to initialize GPU class"
);
// TODO Auto-generated catch block
e
.
printStackTrace
();
return
false
;
}
// final int debugLevel);
}
EYESIS_CORRECTIONS_AUX
.
initSensorFiles
(
DEBUG_LEVEL
);
if
(!
QUAD_CLT_AUX
.
CLTKernelsAvailable
())
{
if
(
DEBUG_LEVEL
>
0
)
{
System
.
out
.
println
(
"Reading AUX CLT kernels"
);
}
QUAD_CLT_AUX
.
readCLTKernels
(
CLT_PARAMETERS
,
THREADS_MAX
,
UPDATE_STATUS
,
// update status info
DEBUG_LEVEL
);
if
(
DEBUG_LEVEL
>
1
)
{
QUAD_CLT_AUX
.
showCLTKernels
(
THREADS_MAX
,
UPDATE_STATUS
,
// update status info
DEBUG_LEVEL
);
}
}
if
(!
QUAD_CLT_AUX
.
geometryCorrectionAvailable
())
{
if
(
DEBUG_LEVEL
>
0
)
{
System
.
out
.
println
(
"Calculating geometryCorrection"
);
}
if
(!
QUAD_CLT_AUX
.
initGeometryCorrection
(
DEBUG_LEVEL
+
2
))
{
return
false
;
}
}
if
(
CLT_PARAMETERS
.
useGPU
(
true
)
&&
(
QUAD_CLT_AUX
!=
null
)
&&
(
GPU_QUAD_AUX
==
null
))
{
// if GPU AUX is
// needed
try
{
GPU_QUAD_AUX
=
new
GpuQuad
(
//
GPU_TILE_PROCESSOR
,
QUAD_CLT_AUX
,
CLT_PARAMETERS
.
gpu_debug_level
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Failed to initialize GpuQuad class"
);
// TODO Auto-generated catch block
e
.
printStackTrace
();
return
false
;
}
// final int debugLevel);
QUAD_CLT_AUX
.
setGPU
(
GPU_QUAD_AUX
);
}
switch
(
mode
)
{
case
0
:
CuasMotion
.
testCuasMotion
(
imp_sel
,
// ImagePlus imp_sel,
CLT_PARAMETERS
,
// CLTParameters clt_parameters,
QUAD_CLT_AUX
,
// QuadCLT parentCLT)
DEBUG_LEVEL
);
// //int debugLevel)
break
;
case
1
:
CuasMotion
.
testCuasScanMotion
(
imp_sel
,
// ImagePlus imp_sel,
CLT_PARAMETERS
,
// CLTParameters clt_parameters,
QUAD_CLT_AUX
,
// QuadCLT parentCLT)
DEBUG_LEVEL
);
// //int debugLevel)
break
;
}
return
true
;
}
public
static
boolean
djiSrtToKml
()
{
String
srt_path
=
"/home/elphel/Documents/dji/images/DJI_001-02/DJI_20250515122524_0007_D.SRT"
;
String
kml_path
=
"/home/elphel/Documents/dji/images/DJI_001-02/DJI_20250515122524_0007_D.kml"
;
...
...
src/main/java/com/elphel/imagej/cuas/CorrectionFPN.java
View file @
da579ebb
...
...
@@ -492,7 +492,7 @@ public class CorrectionFPN {
return
null
;
}
ImagejJp4Tiff
.
decodeProperiesFromInfo
(
imp
);
double
[][]
rowcol_data2
=
QuadCLT
.
readDoubleArray
(
double
[][]
rowcol_data2
=
ShowDoubleFloatArrays
.
readDoubleArray
(
imp
,
// ImagePlus imp,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh); // int [] wh)
...
...
src/main/java/com/elphel/imagej/cuas/CuasData.java
View file @
da579ebb
...
...
@@ -123,7 +123,7 @@ public class CuasData implements Serializable {
int
[]
wh
=
new
int
[
2
];
float
[][]
fclt_w
;
String
cuas_old_path
=
full_path
+
Prefs
.
getFileSeparator
()
+
name
+
QuadCLTCPU
.
CENTER_CLT_SUFFIX
+
".tiff"
;
fclt_w
=
QuadCLT
.
readFloatArray
(
fclt_w
=
ShowDoubleFloatArrays
.
readFloatArray
(
cuas_old_path
,
// String file_path,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh) {
...
...
src/main/java/com/elphel/imagej/cuas/CuasMotion.java
0 → 100644
View file @
da579ebb
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
View file @
da579ebb
...
...
@@ -245,6 +245,11 @@ public class GpuQuad{ // quad camera description
return
this
.
quadCLT
;
}
public
GPUTileProcessor
getGpuTileProcessor
()
{
return
this
.
gpuTileProcessor
;
}
public
int
getTaskSize
()
{
if
(
rectilinear
)
return
TpTask
.
getSize
(
1
);
return
TpTask
.
getSize
(
quadCLT
.
getNumSensors
());
...
...
@@ -265,8 +270,8 @@ public class GpuQuad{ // quad camera description
this
.
num_cams
=
quadCLT
.
getNumSensors
();
this
.
num_all_pairs
=
Correlation2d
.
getNumPairs
(
num_cams
);
this
.
num_colors
=
quadCLT
.
isMonochrome
()?
1
:
3
;
//num_colors; // maybe should always be 3?
this
.
kernels_hor
=
quadCLT
.
getCLTKernels
()[
0
][
0
][
0
].
length
;
// kernels_hor;
this
.
kernels_vert
=
quadCLT
.
getCLTKernels
()[
0
][
0
].
length
;
// kernels_vert;
this
.
kernels_hor
=
(
quadCLT
.
getCLTKernels
()
==
null
)
?
0
:
quadCLT
.
getCLTKernels
()[
0
][
0
][
0
].
length
;
// kernels_hor;
this
.
kernels_vert
=
(
quadCLT
.
getCLTKernels
()
==
null
)
?
0
:
quadCLT
.
getCLTKernels
()[
0
][
0
].
length
;
// kernels_vert;
this
.
kern_tiles
=
kernels_hor
*
kernels_vert
*
num_colors
;
this
.
kern_size
=
kern_tiles
*
4
*
64
;
if
(
debug_level
>=
100
)
{
...
...
@@ -4713,12 +4718,79 @@ public class GpuQuad{ // quad camera description
return
tp_tasks_out
;
}
/**
* Prepare tasks for accumulation of multiple images, shifted proportionally to the vector field
* and temporal distance from the middle frame. Accumulation uses the feature developed for the
* thermal camera motion blur correction that allows accumulation in the transform domain. It only
* works with the negative scales, so the result will be a negative image in the TD.
* @param vector_field sparse array of motion vectors (may be longer, only Vx and Vy used). Null elements
* are allowed, they will be skipped, resultin in null TpTask elements.
* @param offset_scale multiply all vectors by this value when calculatingpixel offsets
* @param magnitude_scale Scale data for accumulation (here positive, will be negated
* @param image_width image width in tiles (80 for 640-wide images).
* @return condensed array of TpTask
*/
public
static
TpTask
[]
setRectilinearMovingTasks
(
final
double
[][]
vector_field
,
final
double
offset_scale
,
final
double
magnitude_scale
,
final
int
tilesX
)
{
final
float
fmagnitude_scale
=
(
float
)
-
magnitude_scale
;
final
int
tiles
=
vector_field
.
length
;
final
TpTask
[]
tp_tasks_full
=
new
TpTask
[
tiles
];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
00
);
final
AtomicInteger
aTiles
=
new
AtomicInteger
(
0
);
// Not sure which bits are needed to enable GPU processing
final
int
task_code
=
(
1
<<
GPUTileProcessor
.
TASK_TEXT_EN
)
|
(
1
<<
GPUTileProcessor
.
TASK_CORR_EN
)
|
(
1
<<
GPUTileProcessor
.
TASK_INTER_EN
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
@Override
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
tiles
;
nTile
=
ai
.
getAndIncrement
())
if
(
vector_field
[
nTile
]
!=
null
){
int
tileY
=
nTile
/
tilesX
;
int
tileX
=
nTile
%
tilesX
;;
double
dx
=
vector_field
[
nTile
][
0
]*
offset_scale
;
double
dy
=
vector_field
[
nTile
][
1
]*
offset_scale
;
double
[]
cxy0
=
{
// uniform coordinates for the center scene
(
tileX
+
0.5
)
*
GPUTileProcessor
.
DTT_SIZE
,
(
tileY
+
0.5
)
*
GPUTileProcessor
.
DTT_SIZE
};
// check just
TpTask
tp_task
=
new
TpTask
(
1
,
tileX
,
tileY
);
// single "sensor"
tp_task
.
task
=
task_code
;
tp_task
.
scale
=
fmagnitude_scale
;
tp_task
.
setCenterXY
(
cxy0
);
// this pair of coordinates will be used by GPU... not yet
tp_task
.
xy
=
new
float
[
1
][
2
];
// see where task.disp_dist is used - only in GeometryCorrection, when calculating .xy
tp_task
.
xy
[
0
][
0
]
=
(
float
)
(
cxy0
[
0
]
+
dx
);
tp_task
.
xy
[
0
][
1
]
=
(
float
)
(
cxy0
[
1
]
+
dy
);
int
iTile
=
aTiles
.
getAndIncrement
();
tp_tasks_full
[
iTile
]
=
tp_task
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
final
TpTask
[]
tp_tasks
=
new
TpTask
[
aTiles
.
get
()];
System
.
arraycopy
(
tp_tasks_full
,
0
,
tp_tasks
,
0
,
tp_tasks
.
length
);
return
tp_tasks
;
}
/**
*
* @param fpixels
* @param img_width
* @param woi
* @param affine
* @return
*/
public
static
TpTask
[][]
setRectilinearInterTasks
(
final
float
[][]
fpixels
,
// to check for empty
final
int
img_width
,
Rectangle
woi
,
final
double
[][][]
affine
// [2][2][3] affine coefficients to translate common to 2 images
){
final
double
[][][]
affine
_in
){
// [2][2][3] affine coefficients to translate common to 2 images
final
double
[][][]
affine
=
(
affine_in
!=
null
)
?
affine_in
:
new
double
[][][]
{{{
1
,
0
,
0
},{
0
,
1
,
0
}},{{
1
,
0
,
0
},{
0
,
1
,
0
}}};
final
int
img_height
=
fpixels
[
0
].
length
/
img_width
;
if
(
woi
==
null
)
{
woi
=
new
Rectangle
(
0
,
0
,
img_width
,
img_height
);
...
...
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java
View file @
da579ebb
...
...
@@ -1995,17 +1995,17 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
/**
*
* @param clt_parameters
* @param fpixels
* @param img_width
* @param woi
* @param affine
* @param tp_tasks_o
* @param batch_mode
* @param dbg_suffix
* @param debugLevel
* @return [2
][tilesX*tilesY][3
]
*
Calculate single-tile and neighbors vector fields
* @param clt_parameters
meta parameters
* @param fpixels
{reference, other}, each img_width * img_height(calculated)
* @param img_width
image width
* @param woi
image window to process, if null, use full GPU window
* @param affine
[2][2][3] affine coefficients to translate common to 2 images
* @param tp_tasks_o
null or TpTask [2][] - will get copy of tasks for both images (different, centers, same tasks)
* @param batch_mode
avoid graphics debug in batch mode
* @param dbg_suffix
for image_names, such as batch_mode? null: String.format("_%02d", ntry);
* @param debugLevel
debug level
* @return [2
:neibs/single][tilesX*tilesY][3:x,y,str
]
*/
public
static
double
[][][]
rectilinearVectorField
(
// scene0/scene1
final
CLTParameters
clt_parameters
,
...
...
@@ -2019,7 +2019,7 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
final
int
debugLevel
)
{
int
[]
wh
=
{
img_width
,
fpixels
[
0
].
length
/
img_width
};
TpTask
[][]
tp_tasks
=
GpuQuad
.
setRectilinearInterTasks
(
fpixels
,
// final float [][] fpixels, // to check for empty
fpixels
,
// final float [][] fpixels, // to check for empty
(no processing where it images have NaN
img_width
,
// final int img_width,
woi
,
// Rectangle woi,
affine
);
// final double [][][] affine // [2][2][3] affine coefficients to translate common to 2 images
...
...
@@ -2066,7 +2066,7 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
final
double
gpu_sigma_log_corr
=
clt_parameters
.
getGpuCorrLoGSigma
(
image_dtt
.
isMonochrome
());
image_dtt
.
interRectilinearCorrTD
(
clt_parameters
.
img_dtt
,
//final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
batch_mode
,
// final boolean batch_mode,
batch_mode
,
// final boolean batch_mode,
erase_clt
,
// final int erase_clt,
fpixels
[
1
],
// final float [] fpixels,
wh
,
// final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels
...
...
@@ -2139,13 +2139,15 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
corr_tiles_pd
[
0
],
// final double[][] tiles,
rln_sngl_rstr
,
// double rmax,
rln_cent_radius
,
// final double centroid_radius, // 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
rln_n_recenter
);
// final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
rln_n_recenter
,
// final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
false
);
// final boolean calc_fraction ){ // calculate fraction inside center circle
if
(
corr_tiles_pd
.
length
>
1
)
{
vector_field
[
1
]
=
TDCorrTile
.
getMismatchVector
(
corr_tiles_pd
[
1
],
// final double[][] tiles,
rln_neib_rstr
,
// double rmax,
rln_cent_radius
,
// final double centroid_radius, // 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
rln_n_recenter
);
// final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
rln_n_recenter
,
// final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
false
);
// final boolean calc_fraction ){ // calculate fraction inside center circle
}
boolean
show_vector_field
=
(
debugLevel
>
100
);
// true;
boolean
show_2d_correlations
=
(
debugLevel
>
0
);
// true;
...
...
src/main/java/com/elphel/imagej/tileprocessor/Correlation2d.java
View file @
da579ebb
...
...
@@ -2411,16 +2411,21 @@ public class Correlation2d {
}
return
rslt
;
}
public
static
double
[]
getMaxXYCm
(
double
[]
data
,
// will be modified if fpn_mask != null;
int
data_width
,
// = 2 * transform_size - 1;
int
data_width
,
// = 2 * transform_size - 1;
// negative - calculate fraction
double
radius
,
// 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
int
refine
,
// re-center window around new maximum. 0 -no refines (single-pass)
boolean
[]
fpn_mask
,
boolean
ignore_border
,
// only if fpn_mask != null - ignore tile if maximum touches fpn_mask
boolean
debug
)
{
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;
double
x0
=
center_xy
,
y0
=
center_xy
;
...
...
@@ -2455,6 +2460,7 @@ public class Correlation2d {
}
}
//calculate as "center of mass"
double
frac
=
0
;
if
(
radius
==
0
)
{
double
s0
=
0
,
sx
=
0
,
sy
=
0
;
for
(
int
iy
=
0
;
iy
<
data_height
;
iy
++)
{
...
...
@@ -2474,9 +2480,11 @@ public class Correlation2d {
}
x0
+=
sx
/
s0
;
y0
+=
sy
/
s0
;
// s00 = s0;
}
else
{
double
radius2
=
radius
*
radius
;
for
(
int
nref
=
0
;
nref
<=
refine
;
nref
++)
{
double
s_other
=
0
;
double
s0
=
0
,
sx
=
0
,
sy
=
0
;
for
(
int
iy
=
0
;
iy
<
data_height
;
iy
++)
{
double
y
=
iy
-
y0
;
...
...
@@ -2492,18 +2500,32 @@ public class Correlation2d {
sx
+=
d
*
x
;
sy
+=
d
*
y
;
}
}
else
if
(
calc_fraction
)
{
double
d
=
data
[
iy
*
data_width
+
ix
];
if
(
d
>
0
)
{
// ignore negative
s_other
+=
d
;
}
}
}
}
x0
+=
sx
/
s0
;
y0
+=
sy
/
s0
;
frac
=
s0
/
(
s0
+
s_other
);
}
}
double
[]
rslt
=
{
x0
-
center_xy
,
y0
-
center_xy
,
mx
};
if
(
debug
){
System
.
out
.
println
(
"getMaxXYCm() -> "
+
rslt
[
0
]+
":"
+
rslt
[
1
]);
if
(
calc_fraction
)
{
double
[]
rslt
=
{
x0
-
center_xy
,
y0
-
center_xy
,
mx
,
frac
};
if
(
debug
){
System
.
out
.
println
(
"getMaxXYCm() -> "
+
rslt
[
0
]+
":"
+
rslt
[
1
]
+
" ("
+
rslt
[
2
]+
"), frac = "
+
rslt
[
3
]);
}
return
rslt
;
}
else
{
double
[]
rslt
=
{
x0
-
center_xy
,
y0
-
center_xy
,
mx
};
if
(
debug
){
System
.
out
.
println
(
"getMaxXYCm() -> "
+
rslt
[
0
]+
":"
+
rslt
[
1
]
+
" ("
+
rslt
[
2
]+
")"
);
}
return
rslt
;
}
return
rslt
;
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java
View file @
da579ebb
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
da579ebb
...
...
@@ -244,6 +244,14 @@ public class QuadCLTCPU {
public
ImagePlus
imp_center_average
=
null
;
public
CorrectionFPN
correctionFPN
=
null
;
public
int
getWidth
()
{
return
tp
.
getTilesX
()*
tp
.
getTileSize
();
}
public
int
getHeight
()
{
return
tp
.
getTilesY
()*
tp
.
getTileSize
();
}
public
boolean
dsiIsFromCombo
()
{
return
dsi_from_combo
;
}
...
...
@@ -5943,100 +5951,13 @@ public class QuadCLTCPU {
readX3dDirectory
(
correctionsParameters
.
getModelName
(
image_name
));
String
file_name
=
image_name
+
suffix
;
String
file_path
=
x3d_path
+
Prefs
.
getFileSeparator
()
+
file_name
+
".tiff"
;
return
readFloatArray
(
return
ShowDoubleFloatArrays
.
readFloatArray
(
file_path
,
// String file_path,
num_slices
,
// int num_slices, // (0 - all)
wh
);
// int [] wh)
}
public
static
float
[][]
readFloatArray
(
String
file_path
,
int
num_slices
,
// (0 - all)
int
[]
wh
)
{
ImagePlus
imp
=
null
;
try
{
imp
=
new
ImagePlus
(
file_path
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Failed to open "
+
file_path
+
", maybe will generate it"
);
}
if
((
imp
==
null
)
||
(
imp
.
getTitle
()
==
null
)
||
(
imp
.
getTitle
().
equals
(
""
)))
{
return
null
;
}
System
.
out
.
println
(
"Read "
+(
imp
.
getStack
().
getSize
())+
" slices from "
+
file_path
);
return
readFloatArray
(
imp
,
// ImagePlus imp,
num_slices
,
//int num_slices, // (0 - all)
wh
);
// int [] wh)
/*
ImageStack imageStack = imp.getStack();
int nChn=imageStack.getSize();
if ((num_slices > 0) && (num_slices < nChn)) {
nChn = num_slices;
}
float [][] result = new float [nChn][];
for (int n = 0; n < nChn; n++) {
result[n] = (float[]) imageStack.getPixels(n + 1);
}
if (wh != null) {
wh[0] = imp.getWidth();
wh[1] = imp.getHeight();
}
return result;
*/
}
public
static
double
[][]
readDoubleArray
(
ImagePlus
imp
,
int
num_slices
,
// (0 - all)
int
[]
wh
)
{
float
[][]
fdata
=
readFloatArray
(
imp
,
// ImagePlus imp,
num_slices
,
// int num_slices, // (0 - all)
wh
);
// int [] wh)
if
(
fdata
==
null
)
{
return
null
;
}
double
[][]
result
=
new
double
[
fdata
.
length
][];
for
(
int
n
=
0
;
n
<
fdata
.
length
;
n
++)
if
(
fdata
[
n
]!=
null
)
{
result
[
n
]
=
new
double
[
fdata
[
n
].
length
];
for
(
int
i
=
0
;
i
<
fdata
[
n
].
length
;
i
++)
{
result
[
n
][
i
]
=
fdata
[
n
][
i
];
}
}
return
result
;
}
public
static
float
[][]
readFloatArray
(
ImagePlus
imp
,
int
num_slices
,
// (0 - all)
int
[]
wh
)
{
if
((
imp
==
null
)
||
(
imp
.
getTitle
()
==
null
)
||
(
imp
.
getTitle
().
equals
(
""
)))
{
return
null
;
}
ImageStack
imageStack
=
imp
.
getStack
();
int
nChn
=
imageStack
.
getSize
();
if
((
num_slices
>
0
)
&&
(
num_slices
<
nChn
))
{
nChn
=
num_slices
;
}
float
[][]
result
=
new
float
[
nChn
][];
for
(
int
n
=
0
;
n
<
nChn
;
n
++)
{
result
[
n
]
=
(
float
[])
imageStack
.
getPixels
(
n
+
1
);
}
if
(
wh
!=
null
)
{
wh
[
0
]
=
imp
.
getWidth
();
wh
[
1
]
=
imp
.
getHeight
();
}
return
result
;
}
public
ImagePlus
readImagePlusFromModelDirectory
(
String
suffix
)
...
...
src/main/java/com/elphel/imagej/tileprocessor/TDCorrTile.java
View file @
da579ebb
...
...
@@ -208,7 +208,7 @@ public class TDCorrTile {
* Get number of defined (non-null) tiles
* @param tiles sparse array of tiles
* @param indices - null or int [tiles.length] that will be set to have unique
* indices for non-null tiles. Indices for n
on-null tiles will not be modified
* indices for non-null tiles. Indices for n
ull tiles will be set to -1
* @return number of non-null tiles
*/
public
static
int
getNumTiles
(
...
...
@@ -223,6 +223,8 @@ public class TDCorrTile {
public
void
run
()
{
for
(
int
iTile
=
ai
.
getAndIncrement
();
iTile
<
tiles
.
length
;
iTile
=
ai
.
getAndIncrement
())
if
(
tiles
[
iTile
]
!=
null
)
{
indices
[
iTile
]
=
anum_tiles
.
getAndIncrement
();
}
else
{
indices
[
iTile
]
=
-
1
;
}
}
};
...
...
@@ -458,54 +460,70 @@ public class TDCorrTile {
return
mapped_corrs
;
}
/**
* Calculate per-tile motion vectors {x,y,strength_over_min) using centroid approach
* @param tiles sparse array of correlation tiles (now 15*15=255 pix)
* @param rmax minimal tile strength relative to the absolute maximum strength. if negative - use absolute, not relative
* @param centroid_radius 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
* @param n_recenter re-center window around new maximum. 0 -no refines (single-pass)
* @return per-tile array of triplets (x,y,strength-min_strength)
*/
public
static
double
[][]
getMismatchVector
(
final
double
[][]
tiles
,
double
rmax
,
double
rmax
,
// minimal tile strength relative to the absolute maximum strength.
final
double
centroid_radius
,
// 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
final
int
n_recenter
){
// re-center window around new maximum. 0 -no refines (single-pass)
final
int
n_recenter
,
// re-center window around new maximum. 0 -no refines (single-pass)
final
boolean
calc_fraction
){
// calculate fraction inside center circle
double
[][]
vector_field
=
new
double
[
tiles
.
length
][];
final
int
corr_size
=
2
*
GPUTileProcessor
.
DTT_SIZE
-
1
;
final
int
corr_size
=
(
calc_fraction
?
-
1
:
1
)
*
(
2
*
GPUTileProcessor
.
DTT_SIZE
-
1
);
// negate to force fraction calculation
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
th_max
=
new
double
[
threads
.
length
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
thread_num
=
ati
.
getAndIncrement
();
for
(
int
iTile
=
ai
.
getAndIncrement
();
iTile
<
tiles
.
length
;
iTile
=
ai
.
getAndIncrement
())
if
(
tiles
[
iTile
]
!=
null
)
{
for
(
double
d:
tiles
[
iTile
])
{
if
(
d
>
th_max
[
thread_num
])
{
th_max
[
thread_num
]
=
d
;
double
amax
=
0
;
if
(
rmax
>
0
)
{
final
double
[]
th_max
=
new
double
[
threads
.
length
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
thread_num
=
ati
.
getAndIncrement
();
for
(
int
iTile
=
ai
.
getAndIncrement
();
iTile
<
tiles
.
length
;
iTile
=
ai
.
getAndIncrement
())
if
(
tiles
[
iTile
]
!=
null
)
{
for
(
double
d:
tiles
[
iTile
])
{
if
(
d
>
th_max
[
thread_num
])
{
th_max
[
thread_num
]
=
d
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
amax
=
th_max
[
0
];
for
(
int
i
=
1
;
i
<
th_max
.
length
;
i
++)
{
if
(
th_max
[
i
]
>
amax
)
{
amax
=
th_max
[
i
];
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
amax
=
th_max
[
0
];
for
(
int
i
=
1
;
i
<
th_max
.
length
;
i
++)
{
if
(
th_max
[
i
]
>
amax
)
{
amax
=
th_max
[
i
];
}
}
final
double
min_str
=
rmax
*
amax
;
final
double
min_str
=
(
rmax
>
0
)
?
rmax
*
amax
:
(-
rmax
)
;
ai
.
set
(
0
);
final
int
dbg_tile
=
-(
33
+
35
*
80
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
iTile
=
ai
.
getAndIncrement
();
iTile
<
tiles
.
length
;
iTile
=
ai
.
getAndIncrement
())
if
(
tiles
[
iTile
]
!=
null
)
{
if
(
iTile
==
dbg_tile
)
{
System
.
out
.
println
(
"getMismatchVector(): iTile="
+
iTile
);
}
double
[]
mv
=
Correlation2d
.
getMaxXYCm
(
// last, average
tiles
[
iTile
],
// corrs.length-1], // double [] data,
corr_size
,
// int data_width, // = 2 * transform_size - 1;
corr_size
,
// 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,
false
,
// boolean ignore_border, // only if fpn_mask != null - ignore tile if maximum touches fpn_mask
false
);
// boolean debug)
if
(
mv
[
2
]
>
min_str
)
{
vector_field
[
iTile
]
=
new
double
[]
{
mv
[
0
],
mv
[
1
],
mv
[
2
]-
min_str
};
vector_field
[
iTile
]
=
new
double
[]
{
mv
[
0
],
mv
[
1
],
mv
[
2
]-
min_str
,
mv
[
3
]
};
}
}
}
...
...
src/main/java/com/elphel/imagej/vegetation/VegetationSynthesis.java
View file @
da579ebb
...
...
@@ -111,7 +111,7 @@ public class VegetationSynthesis {
int
[]
wh
=
new
int
[
2
];
int
model_slices
=
imp_model
.
getStackSize
();
System
.
out
.
println
(
"testSynthetic(): read model from: "
+
path_model
+
", got "
+
model_slices
+
" slices"
);
double
[][]
model_data
=
QuadCLT
.
readDoubleArray
(
double
[][]
model_data
=
ShowDoubleFloatArrays
.
readDoubleArray
(
imp_model
,
// ImagePlus imp,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh); // int [] wh)
...
...
@@ -156,7 +156,7 @@ public class VegetationSynthesis {
}
else
{
int
scene_offs_slices
=
imp_scene_offs
.
getStackSize
();
System
.
out
.
println
(
"testSynthetic(): read scene offsets from: "
+
path_scene_offs
+
", got "
+
scene_offs_slices
+
" slices, will add them to the rendered images"
);
scene_offs
=
QuadCLT
.
readDoubleArray
(
scene_offs
=
ShowDoubleFloatArrays
.
readDoubleArray
(
imp_scene_offs
,
// ImagePlus imp,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh); // int [] wh)
...
...
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