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
d15a47db
Commit
d15a47db
authored
May 30, 2025
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improving cuas
parent
0630471a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1172 additions
and
114 deletions
+1172
-114
CalibrationFileManagement.java
.../elphel/imagej/calibration/CalibrationFileManagement.java
+4
-0
Cuas.java
src/main/java/com/elphel/imagej/cuas/Cuas.java
+600
-40
CuasCenterLma.java
src/main/java/com/elphel/imagej/cuas/CuasCenterLma.java
+96
-5
GpuQuad.java
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
+10
-0
Interscene.java
...main/java/com/elphel/imagej/tileprocessor/Interscene.java
+1
-1
IntersceneMatchParameters.java
...lphel/imagej/tileprocessor/IntersceneMatchParameters.java
+28
-2
OpticalFlow.java
...ain/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
+13
-35
QuadCLT.java
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
+299
-16
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+121
-15
No files found.
src/main/java/com/elphel/imagej/calibration/CalibrationFileManagement.java
View file @
d15a47db
...
...
@@ -168,6 +168,10 @@ public class CalibrationFileManagement {
if
((
dir
!=
null
)
&&
(!
dir
.
isDirectory
())){
dir
=
dir
.
getParentFile
();
}
if
(!
smart
)
{
// 05.29.2025
return
null
;
}
JFileChooser
fc
=
new
JFileChooser
();
...
...
src/main/java/com/elphel/imagej/cuas/Cuas.java
View file @
d15a47db
...
...
@@ -16,7 +16,11 @@ import com.elphel.imagej.tileprocessor.OpticalFlow;
import
com.elphel.imagej.tileprocessor.QuadCLT
;
import
com.elphel.imagej.tileprocessor.TileProcessor
;
import
ij.ImagePlus
;
public
class
Cuas
{
/*
@Deprecated
public static QuadCLT createCenterClt( // assuming cuas_rotation is true
CLTParameters clt_parameters,
QuadCLT [] quadCLTs,
...
...
@@ -121,6 +125,217 @@ public class Cuas {
// center_CLT.setDSI(center_combo_dsi); // WRONG!
String rslt_suffix = "-INTER-INTRA";
rslt_suffix += (clt_parameters.correlate_lma?"-LMA":"-NOLMA");
// fixing NaN in strengths. It is uses to return RMS in Not needed - NaN was from Arrays.fill(combo_dsn_final[i], Double.NaN);
// OpticalFlow:10348
for (int slice: OpticalFlow.COMBO_DSN_NONNAN) { // new int[] {COMBO_DSN_INDX_STRENGTH,COMBO_DSN_INDX_STRENGTH_BG}) {
if (center_combo_dsi[slice] != null) {
for (int i = 0; i <center_combo_dsi[slice].length; i++) {
if (Double.isNaN(center_combo_dsi[slice][i])) {
center_combo_dsi[slice][i] = 0.0;
}
}
}
}
center_CLT.saveDoubleArrayInModelDirectory( // error
rslt_suffix, // String suffix,
OpticalFlow.COMBO_DSN_TITLES, // combo_dsn_titles_full, // null, // String [] labels, // or null
center_combo_dsi, // dbg_data, // double [][] data,
tilesX, // int width,
tilesY); // int height)
// center_CLT.saveDSI();
center_CLT.saveCenterClt();
boolean save_clt = true;
boolean save_dsi = true;
boolean save_in_ref = true;
boolean save_in_last = true;
if (save_clt) {
final int height_clt = combo_seq_clt[0].length/width_clt;
String [] clt_titles = new String [combo_seq_clt_w.length];
for (int i = 0; i < combo_seq_clt.length; i++) {
clt_titles[i] = "chn-"+i;
if (save_weights) {
clt_titles[i+combo_seq_clt.length] = "weight-"+i;
}
}
String suffix_clt = "-clt_combo";
if (save_weights) {
suffix_clt+="_weights";
}
if (save_in_ref) {
ref_clt.saveFloatArrayInModelDirectory( // error
suffix_clt, // String suffix,
clt_titles, // combo_dsn_titles_full, // null, // String [] labels, // or null
combo_seq_clt_w, // dbg_data, // float [][] data,
width_clt, // int width,
height_clt); // int height)
}
if (save_in_last) {
quadCLTs[quadCLTs.length - 1].saveFloatArrayInModelDirectory( // error
suffix_clt, // String suffix,
clt_titles, // combo_dsn_titles_full, // null, // String [] labels, // or null
combo_seq_clt_w, // dbg_data, // float [][] data,
width_clt, // int width,
height_clt); // int height)
}
}
if (save_dsi) {
// final double [][] combo_dsi_cli = ref_clt.restoreComboDSI (true);
TileProcessor tp = quadCLTs[quadCLTs.length - 1].getTileProcessor();
final int transform_size = tp.getTileSize();
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final double [][] center_dsi = interpolateDSI(
ref_pXpYD, // final double [][] ref_pXpYD,
ref_dsi, // combo_dsi_cli, // final double [][] dsi_in,
transform_size, // final int transform_size,
tilesX, // final int tilesX,
tilesY); //final int tilesY);
String rslt_suffix = "-CENTER-INTER-INTRA";
// use quadCLTs[quadCLTs.length - 1].restoreComboDSI ("-CENTER",true); to restore
rslt_suffix += (clt_parameters.correlate_lma?"-LMA":"-NOLMA");
if (save_in_ref) {
ref_clt.saveDoubleArrayInModelDirectory( // error
rslt_suffix, // String suffix,
OpticalFlow.COMBO_DSN_TITLES, // combo_dsn_titles_full, // null, // String [] labels, // or null
center_dsi, // dbg_data, // double [][] data,
tilesX, // int width,
tilesY); // int height)
}
if (save_in_last) {
quadCLTs[quadCLTs.length - 1].saveDoubleArrayInModelDirectory( // error
rslt_suffix, // String suffix,
OpticalFlow.COMBO_DSN_TITLES, // combo_dsn_titles_full, // null, // String [] labels, // or null
center_dsi, // dbg_data, // double [][] data,
tilesX, // int width,
tilesY); // int height)
}
}
return center_CLT;
}
*/
@Deprecated
public
static
QuadCLT
createCenterClt_old
(
// assuming cuas_rotation is true
CLTParameters
clt_parameters
,
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_scene
,
// where combo_dsi is
int
[]
range
,
// or null
double
[][]
ref_combo_dsi
,
// DSI data for the reference scene (or null to read it from file)
boolean
condition_dsi
,
int
sensor_mask
,
// -1 - all;
int
debugLevel
)
{
QuadCLT
last_clt
=
quadCLTs
[
quadCLTs
.
length
-
1
];
// save center with the latest timestamp
if
(
range
==
null
)
{
range
=
new
int
[]
{
0
,
quadCLTs
.
length
-
1
};
}
double
[][]
center_ATR
=
CuasCenterLma
.
getCenterATR
(
// relative to ref_scene
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
// QuadCLT ref_scene, //
range
,
//int [] range,
debugLevel
);
// int debugLevel);
double
[]
cuas_xyz
=
new
double
[
3
];
//maybe use later
double
[]
cuas_atr
=
new
double
[]
{
center_ATR
[
0
][
0
],
center_ATR
[
0
][
1
],
center_ATR
[
0
][
2
]};
double
[][]
cuas_xyzatr
=
{
cuas_xyz
,
cuas_atr
};
if
(
ref_combo_dsi
==
null
)
{
ref_combo_dsi
=
ref_scene
.
restoreComboDSI
(
true
);
// also sets quadCLTs[ref_index].dsi and blue sky
}
double
[][]
dls
=
{
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_DISP
],
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_LMA
],
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_STRENGTH
]
};
double
[][]
ds
=
new
double
[][]
{
dls
[
0
],
dls
[
2
]};
// {disparity, strength}
if
(
condition_dsi
)
{
ds
=
OpticalFlow
.
conditionInitialDS
(
// only
true
,
// boolean use_conf, // use configuration parameters, false - use following
clt_parameters
,
// CLTParameters clt_parameters,
dls
,
// double [][] dls
ref_scene
,
// QuadCLT scene,
debugLevel
);
}
// getRefPxPyD: pX, pY reference image X,Y corresponding to the uniform grid of the center view
final
double
[][]
ref_pXpYD
=
getRefPxPyD
(
// Use to interpolate disparity layers
clt_parameters
,
// CLTParameters clt_parameters,
true
,
// boolean mode_cuas,
null
,
// Rectangle fov_tiles,
OpticalFlow
.
ZERO3
,
// double [] stereo_xyz, // offset reference camera {x,y,z}
cuas_atr
,
// double [] stereo_atr_in, // offset reference orientation (cuas)
ds
[
0
],
// double [] ref_disparity,
ref_scene
,
// QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel
);
// int debugLevel)
boolean
save_weights
=
true
;
// always
float
[][][]
center_clt_w
=
getTDComboSceneSequence
(
clt_parameters
,
// CLTParameters clt_parameters,
ref_pXpYD
,
// double [][] ref_pXpYD,
save_weights
,
// boolean save_weights, // output corresponding weights for each data
true
,
// boolean merge_all,
sensor_mask
,
// int sensor_mask,
null
,
// Rectangle fov_tiles,
OpticalFlow
.
ZERO3
,
// double [] stereo_xyz, // offset reference camera {x,y,z}
cuas_atr
,
// double [] stereo_atr_in, // offset reference orientation (cuas)
null
,
// ds[0], // double [] ref_disparity, // may be null if ref_pXpYD != null
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
// QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel
);
// int debugLevel)
// remove weights
//// float [][] center_clt = save_weights? new float [center_clt_w.length/2][]: center_clt_w;
//// int [][] center_clt_num = save_weights? new int [center_clt_w.length/2][]: null;
/*
int [][] center_clt_num = save_weights? new int [center_clt_w.length/2][]: null;
if (save_weights) { // remove second half (weights as integer numbers)
for (int i = 0; i< center_clt.length; i++) {
center_clt[i] = center_clt_w[i];
center_clt_num[i] = new int [center_clt_w[i + center_clt.length].length];
for (int j = 0; j < center_clt_num[i].length; j++) {
center_clt_num[i][j] = (int) Math.round(center_clt_w[i + center_clt.length][j]);
}
}
}
int [] wh_c = ref_scene.getWHC(false);
//final int tile_size_td = 4 * GPUTileProcessor.DTT_SIZE * GPUTileProcessor.DTT_SIZE;
final int width_clt = wh_c[0] * 2; // to make image dimensions similar
*/
String
center_name
=
QuadCLT
.
getCenterDirName
(
last_clt
.
getImageName
());
// make name from last timestamp, not reference
String
ref_dir_path
=
ref_scene
.
getX3dDirectory
(
center_name
);
File
cdir
=
new
File
(
ref_dir_path
);
QuadCLT
center_CLT
=
new
QuadCLT
(
ref_scene
,
center_name
);
//null
cdir
.
mkdirs
();
center_CLT
.
setImagePath
(
cdir
.
getPath
());
/*
center_CLT.setCenterClt(
center_clt[0], // float [] clt,
center_clt_num[0], // int [] clt_num,
width_clt); // int clt_width);
*/
center_CLT
.
setCenterClt
(
// only for merged sensors
center_clt_w
[
0
][
0
],
// float [] clt,
center_clt_w
[
1
][
0
]);
// int [] clt_num, // Index 1 out of bounds for length 1
// TileProcessor tp = quadCLTs[quadCLTs.length - 1].getTileProcessor();
final
int
transform_size
=
ref_scene
.
getTileSize
();
final
int
tilesX
=
ref_scene
.
getTilesX
();
final
int
tilesY
=
ref_scene
.
getTilesY
();
final
double
[][]
center_combo_dsi
=
interpolateDSI
(
ref_pXpYD
,
// final double [][] ref_pXpYD,
ref_combo_dsi
,
// combo_dsi_cli, // final double [][] dsi_in,
transform_size
,
// final int transform_size,
tilesX
,
// final int tilesX,
tilesY
);
//final int tilesY);
center_CLT
.
setDSIFromCombo
(
center_combo_dsi
);
// reformat
// center_CLT.setDSI(center_combo_dsi); // WRONG!
String
rslt_suffix
=
"-INTER-INTRA"
;
rslt_suffix
+=
(
clt_parameters
.
correlate_lma
?
"-LMA"
:
"-NOLMA"
);
/*
// fixing NaN in strengths. It is uses to return RMS in Not needed - NaN was from Arrays.fill(combo_dsn_final[i], Double.NaN);
// OpticalFlow:10348
...
...
@@ -218,7 +433,227 @@ public class Cuas {
*/
return
center_CLT
;
}
public
static
double
[][]
interpolateDSI
(
// uses combo_dsi, not this.dsi
public
static
QuadCLT
createCenterClt
(
// assuming cuas_rotation is true
CLTParameters
clt_parameters
,
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_scene
,
// where combo_dsi is
int
[]
range
,
// or null
double
[][]
ref_combo_dsi
,
// DSI data for the reference scene (or null to read it from file)
boolean
condition_dsi
,
int
sensor_mask
,
// -1 - all;
int
debugLevel
)
{
QuadCLT
last_clt
=
quadCLTs
[
quadCLTs
.
length
-
1
];
// save center with the latest timestamp
if
(
range
==
null
)
{
range
=
new
int
[]
{
0
,
quadCLTs
.
length
-
1
};
}
double
[][]
center_ATR
=
CuasCenterLma
.
getCenterATR
(
// relative to ref_scene
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
// QuadCLT ref_scene, //
range
,
//int [] range,
debugLevel
);
// int debugLevel);
double
[]
cuas_xyz
=
new
double
[
3
];
//maybe use later
double
[]
cuas_atr
=
new
double
[]
{
center_ATR
[
0
][
0
],
center_ATR
[
0
][
1
],
center_ATR
[
0
][
2
]};
double
[][]
cuas_xyzatr
=
{
cuas_xyz
,
cuas_atr
};
String
center_name
=
QuadCLT
.
getCenterDirName
(
quadCLTs
[
quadCLTs
.
length
-
1
].
getImageName
());
QuadCLT
center_CLT
=
changeReference
(
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
// QuadCLT ref_old,
null
,
// QuadCLT ref_new,
center_name
,
// String name_new,
cuas_xyzatr
);
// double[][] new_xyzatr);
if
(
ref_combo_dsi
==
null
)
{
ref_combo_dsi
=
ref_scene
.
restoreComboDSI
(
true
);
// also sets quadCLTs[ref_index].dsi and blue sky
}
double
[][]
dls
=
{
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_DISP
],
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_LMA
],
ref_combo_dsi
[
OpticalFlow
.
COMBO_DSN_INDX_STRENGTH
]
};
double
[][]
ds
=
new
double
[][]
{
dls
[
0
],
dls
[
2
]};
// {disparity, strength}
if
(
condition_dsi
)
{
ds
=
OpticalFlow
.
conditionInitialDS
(
// only
true
,
// boolean use_conf, // use configuration parameters, false - use following
clt_parameters
,
// CLTParameters clt_parameters,
dls
,
// double [][] dls
ref_scene
,
// QuadCLT scene,
debugLevel
);
}
// getRefPxPyD: pX, pY reference image X,Y corresponding to the uniform grid of the center view
final
double
[][]
ref_pXpYD
=
getRefPxPyD
(
// Use to interpolate disparity layers
clt_parameters
,
// CLTParameters clt_parameters,
true
,
// boolean mode_cuas,
null
,
// Rectangle fov_tiles,
OpticalFlow
.
ZERO3
,
// double [] stereo_xyz, // offset reference camera {x,y,z}
cuas_atr
,
// double [] stereo_atr_in, // offset reference orientation (cuas)
ds
[
0
],
// double [] ref_disparity,
ref_scene
,
// QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel
);
// int debugLevel)
double
[]
disparity_center
=
new
double
[
ref_pXpYD
.
length
];
Arrays
.
fill
(
disparity_center
,
Double
.
NaN
);
for
(
int
i
=
0
;
i
<
ref_pXpYD
.
length
;
i
++)
if
(
ref_pXpYD
[
i
]
!=
null
)
{
disparity_center
[
i
]
=
ref_pXpYD
[
i
][
2
];
}
// TODO: extrapolate, fill gaps in disparity_center
boolean
save_weights
=
true
;
// always
/*
float [][][] center_clt_w = getTDComboSceneSequence(
clt_parameters, // CLTParameters clt_parameters,
ref_pXpYD, // double [][] ref_pXpYD,
save_weights, // boolean save_weights, // output corresponding weights for each data
true, // boolean merge_all,
sensor_mask, // int sensor_mask,
null, // Rectangle fov_tiles,
OpticalFlow.ZERO3, // double [] stereo_xyz, // offset reference camera {x,y,z}
cuas_atr, // double [] stereo_atr_in, // offset reference orientation (cuas)
null, // ds[0], // double [] ref_disparity, // may be null if ref_pXpYD != null
quadCLTs, // QuadCLT [] quadCLTs,
ref_scene, // QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel); // int debugLevel)
*/
float
[][][]
center_clt_w
=
getTDComboSceneSequence
(
clt_parameters
,
// CLTParameters clt_parameters,
null
,
// ref_pXpYD, // double [][] ref_pXpYD,
save_weights
,
// boolean save_weights, // output corresponding weights for each data
true
,
// boolean merge_all,
sensor_mask
,
// int sensor_mask,
null
,
// Rectangle fov_tiles,
OpticalFlow
.
ZERO3
,
// double [] stereo_xyz, // offset reference camera {x,y,z}
OpticalFlow
.
ZERO3
,
// cuas_atr, // double [] stereo_atr_in, // offset reference orientation (cuas)
disparity_center
,
// ds[0], // double [] ref_disparity, // may be null if ref_pXpYD != null
quadCLTs
,
// QuadCLT [] quadCLTs,
center_CLT
,
// ref_scene, // QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel
);
// int debugLevel)
/*
String center_name = QuadCLT.getCenterDirName(last_clt.getImageName()); // make name from last timestamp, not reference
String ref_dir_path = ref_scene.getX3dDirectory(center_name);
File cdir = new File(ref_dir_path);
QuadCLT center_CLT = new QuadCLT(ref_scene, center_name); //null
cdir.mkdirs();
center_CLT.setImagePath(cdir.getPath());
*/
center_CLT
.
setCenterClt
(
// only for merged sensors
center_clt_w
[
0
][
0
],
// float [] clt,
center_clt_w
[
1
][
0
]);
// int [] clt_num, // Index 1 out of bounds for length 1
final
int
transform_size
=
ref_scene
.
getTileSize
();
final
int
tilesX
=
ref_scene
.
getTilesX
();
final
int
tilesY
=
ref_scene
.
getTilesY
();
final
double
[][]
center_combo_dsi
=
interpolateDSI
(
ref_pXpYD
,
// final double [][] ref_pXpYD,
ref_combo_dsi
,
// combo_dsi_cli, // final double [][] dsi_in,
transform_size
,
// final int transform_size,
tilesX
,
// final int tilesX,
tilesY
);
//final int tilesY);
center_CLT
.
setDSIFromCombo
(
center_combo_dsi
);
// reformat
// center_CLT.setDSI(center_combo_dsi); // WRONG!
String
rslt_suffix
=
"-INTER-INTRA"
;
rslt_suffix
+=
(
clt_parameters
.
correlate_lma
?
"-LMA"
:
"-NOLMA"
);
/*
// fixing NaN in strengths. It is uses to return RMS in Not needed - NaN was from Arrays.fill(combo_dsn_final[i], Double.NaN);
// OpticalFlow:10348
for (int slice: OpticalFlow.COMBO_DSN_NONNAN) { // new int[] {COMBO_DSN_INDX_STRENGTH,COMBO_DSN_INDX_STRENGTH_BG}) {
if (center_combo_dsi[slice] != null) {
for (int i = 0; i <center_combo_dsi[slice].length; i++) {
if (Double.isNaN(center_combo_dsi[slice][i])) {
center_combo_dsi[slice][i] = 0.0;
}
}
}
}
*/
center_CLT
.
saveDoubleArrayInModelDirectory
(
// error
rslt_suffix
,
// String suffix,
OpticalFlow
.
COMBO_DSN_TITLES
,
// combo_dsn_titles_full, // null, // String [] labels, // or null
center_combo_dsi
,
// dbg_data, // double [][] data,
tilesX
,
// int width,
tilesY
);
// int height)
// center_CLT.saveDSI();
center_CLT
.
saveCenterClt
();
/*
boolean save_clt = true;
boolean save_dsi = true;
boolean save_in_ref = true;
boolean save_in_last = true;
if (save_clt) {
final int height_clt = combo_seq_clt[0].length/width_clt;
String [] clt_titles = new String [combo_seq_clt_w.length];
for (int i = 0; i < combo_seq_clt.length; i++) {
clt_titles[i] = "chn-"+i;
if (save_weights) {
clt_titles[i+combo_seq_clt.length] = "weight-"+i;
}
}
String suffix_clt = "-clt_combo";
if (save_weights) {
suffix_clt+="_weights";
}
if (save_in_ref) {
ref_clt.saveFloatArrayInModelDirectory( // error
suffix_clt, // String suffix,
clt_titles, // combo_dsn_titles_full, // null, // String [] labels, // or null
combo_seq_clt_w, // dbg_data, // float [][] data,
width_clt, // int width,
height_clt); // int height)
}
if (save_in_last) {
quadCLTs[quadCLTs.length - 1].saveFloatArrayInModelDirectory( // error
suffix_clt, // String suffix,
clt_titles, // combo_dsn_titles_full, // null, // String [] labels, // or null
combo_seq_clt_w, // dbg_data, // float [][] data,
width_clt, // int width,
height_clt); // int height)
}
}
if (save_dsi) {
// final double [][] combo_dsi_cli = ref_clt.restoreComboDSI (true);
TileProcessor tp = quadCLTs[quadCLTs.length - 1].getTileProcessor();
final int transform_size = tp.getTileSize();
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final double [][] center_dsi = interpolateDSI(
ref_pXpYD, // final double [][] ref_pXpYD,
ref_dsi, // combo_dsi_cli, // final double [][] dsi_in,
transform_size, // final int transform_size,
tilesX, // final int tilesX,
tilesY); //final int tilesY);
String rslt_suffix = "-CENTER-INTER-INTRA";
// use quadCLTs[quadCLTs.length - 1].restoreComboDSI ("-CENTER",true); to restore
rslt_suffix += (clt_parameters.correlate_lma?"-LMA":"-NOLMA");
if (save_in_ref) {
ref_clt.saveDoubleArrayInModelDirectory( // error
rslt_suffix, // String suffix,
OpticalFlow.COMBO_DSN_TITLES, // combo_dsn_titles_full, // null, // String [] labels, // or null
center_dsi, // dbg_data, // double [][] data,
tilesX, // int width,
tilesY); // int height)
}
if (save_in_last) {
quadCLTs[quadCLTs.length - 1].saveDoubleArrayInModelDirectory( // error
rslt_suffix, // String suffix,
OpticalFlow.COMBO_DSN_TITLES, // combo_dsn_titles_full, // null, // String [] labels, // or null
center_dsi, // dbg_data, // double [][] data,
tilesX, // int width,
tilesY); // int height)
}
}
*/
return
center_CLT
;
}
public
static
double
[][]
interpolateDSI
(
// uses combo_dsi, not this.dsi
final
double
[][]
ref_pXpYD
,
final
double
[][]
combo_dsi_in
,
final
int
transform_size
,
...
...
@@ -328,6 +763,7 @@ public class Cuas {
return
combo_dsi
;
}
/*
public static float [][] getTDComboSceneSequence( // never used
CLTParameters clt_parameters,
final boolean save_weights, // output corresponding weights for each data
...
...
@@ -368,42 +804,69 @@ public class Cuas {
refCLT, // QuadCLT refCLT, // should be the same instance if one of quadCLTs
debugLevel); // int debugLevel);
}
public
static
float
[][]
getTDComboSceneSequence
(
*/
// TODO: Use only center disparity, ignore pX,pY
public
static
float
[][][]
getTDComboSceneSequence
(
CLTParameters
clt_parameters
,
double
[][]
ref_pXpYD
,
double
[][]
ref_pXpYD
,
// TODO: Use disparity, ignore pXpYD?
final
boolean
save_weights
,
// output corresponding weights for each data
final
boolean
merge_all
,
final
int
sensor_mask
,
Rectangle
fov_tiles
,
double
[]
stereo_xyz
,
// offset reference camera {x,y,z}
double
[]
stereo_atr_in
,
// offset reference orientation (cuas)
double
[]
ref_disparity
,
double
[]
ref_disparity
,
// null
QuadCLT
[]
quadCLTs
,
QuadCLT
refCLT
,
// should be the same instance if one of quadCLTs
QuadCLT
refCLT
,
// should be the same instance if one of quadCLTs
?
int
debugLevel
)
{
boolean
debug_pxpyd
=
false
;
int
dbg_slices
=
3
;
double
[][][]
dbg_PxPyD
=
debug_pxpyd
?
(
new
double
[
dbg_slices
][
quadCLTs
.
length
][]):
null
;
double
[][][]
dbg_PxPyD_slice
=
debug_pxpyd
?
(
new
double
[
1
][][]):
null
;
int
dbg_scene
=
-
95
;
if
(
ref_pXpYD
==
null
)
{
ref_pXpYD
=
OpticalFlow
.
transformToScenePxPyD
(
// now should work with offset ref_scene
fov_tiles
,
// final Rectangle [] extra_woi, // show larger than sensor WOI (or null)
ref_disparity
,
// final double [] disparity_ref, // invalid tiles - NaN in disparity
OpticalFlow
.
ZERO3
,
// stereo_xyz, // ZERO3, // final double [] scene_xyz, // camera center in world coordinates
OpticalFlow
.
ZERO3
,
// stereo_atr, // ZERO3, // final double [] scene_atr, // camera orientation relative to world frame
refCLT
,
// final QuadCLT scene_QuadClt,
refCLT
,
// final QuadCLT reference_QuadClt, // now - may be null - for testing if scene is rotated ref
ImageDtt
.
THREADS_MAX
);
// int threadsMax)
if
(
debug_pxpyd
)
{
refCLT
.
show_pXpYD
(
ref_pXpYD
,
// double [][] pXpYD,
"-getTDComboSceneSequence"
,
// String suffix,
true
);
// boolean show)
}
}
double
[]
stereo_atr
=
(
stereo_atr_in
!=
null
)?
stereo_atr_in:
OpticalFlow
.
ZERO3
;
// maybe later play with rotated camera
boolean
mode_cuas
=
(
stereo_atr
[
0
]
!=
0
)
||
(
stereo_atr
[
1
]
!=
0
)
||
(
stereo_atr
[
2
]
!=
0
);
double
[][]
ref_pXpYD_or_null
=
mode_cuas
?
ref_pXpYD
:
null
;
// debugging cuas mode keeping old
double
[][]
ref_pXpYD_or_null
=
null
;
//
mode_cuas ? ref_pXpYD : null; // debugging cuas mode keeping old
boolean
mb_en
=
clt_parameters
.
imp
.
mb_en
&&
(
fov_tiles
==
null
);
double
mb_tau
=
clt_parameters
.
imp
.
mb_tau
;
// 0.008; // time constant, sec
double
mb_max_gain
=
clt_parameters
.
imp
.
mb_max_gain
;
// 5.0; // motion blur maximal gain (if more - move second point more than a pixel
int
cuas_discard_border
=
clt_parameters
.
imp
.
cuas_discard_border
;
double
cuas_max_fold
=
clt_parameters
.
imp
.
cuas_max_fold
;
int
cuas_min_in_row_col
=
clt_parameters
.
imp
.
cuas_min_in_row_col
;
ErsCorrection
ers_reference
=
refCLT
.
getErsCorrection
();
// quadCLTs[0].getCltLength(boolean use_ref)
int
sc0
=
-
1
;
for
(
int
nscene
=
0
;
nscene
<
quadCLTs
.
length
;
nscene
++)
if
(
quadCLTs
[
nscene
]
!=
null
){
sc0
=
nscene
;
break
;
}
final
int
num_slices
=
merge_all
?
1
:
quadCLTs
[
sc0
].
getNumSensors
();
final
float
[][]
sumFclt
=
new
float
[
num_slices
*
(
save_weights
?
2
:
1
)][
quadCLTs
[
sc0
].
getCltSize
(
false
)];
final
int
[][]
numAcc
=
new
int
[
num_slices
][
sumFclt
[
0
].
length
];
// next two to improve multithreading performance
final
int
tile_size_td
=
4
*
GPUTileProcessor
.
DTT_SIZE
*
GPUTileProcessor
.
DTT_SIZE
;
final
int
tiles_td
=
sumFclt
[
0
].
length
/
tile_size_td
;
final
int
tiles_td_all
=
tiles_td
*
num_slices
;
// usually sumFclt.length==1
final
int
num_tiles
=
quadCLTs
[
sc0
].
getNumTiles
(
false
);
final
int
tile_length
=
quadCLTs
[
sc0
].
getCltTileLength
();
// includes color
final
float
[][]
sumFclt
=
new
float
[
num_slices
][
tile_length
*
num_tiles
];
final
float
[][]
sum_weights
=
new
float
[
num_slices
][
num_tiles
];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
ImageDtt
.
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
...
...
@@ -414,10 +877,9 @@ public class Cuas {
String
ts
=
quadCLTs
[
nscene
].
getImageName
();
double
[]
scene_xyz
=
OpticalFlow
.
ZERO3
;
double
[]
scene_atr
=
OpticalFlow
.
ZERO3
;
// if (nscene != ref_index) { // Check even for raw, so video frames will match in all modes
if
(
quadCLTs
[
nscene
]
!=
refCLT
)
{
// Check even for raw, so video frames will match in all modes
scene_xyz
=
ers_reference
.
getSceneXYZ
(
ts
);
scene_atr
=
ers_reference
.
getSceneATR
(
ts
);
scene_xyz
=
ers_reference
.
getSceneXYZ
(
ts
);
// saved @ reference, relative to reference
scene_atr
=
ers_reference
.
getSceneATR
(
ts
);
// saved @ reference, relative to reference
if
((
scene_atr
==
null
)
||
(
scene_xyz
==
null
))
{
continue
;
}
...
...
@@ -464,6 +926,10 @@ public class Cuas {
fclt
=
QuadCLT
.
getTDCombo
(
sm
,
// final int sensor_mask,
merge_all
,
// final boolean merge_channels,
cuas_discard_border
,
// final int discard_border,
cuas_max_fold
,
// final double max_fold,
cuas_min_in_row_col
,
// final int min_in_row_col, // Minimal number of defined tiles in a row/column
null
,
// final Rectangle full_woi_in, // show larger than sensor WOI (or null)
clt_parameters
,
// CLTParameters clt_parameters,
ref_disparity
,
// double [] disparity_ref,
...
...
@@ -477,6 +943,7 @@ public class Cuas {
quadCLTs
[
nscene
],
// final QuadCLT scene,
refCLT
,
// quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// final boolean show_nan,
dbg_PxPyD_slice
,
// final double [][][] dbg_PxPyD_slice,
QuadCLT
.
THREADS_MAX
,
// int threadsMax,
debugLevel
);
// final int debugLevel)
...
...
@@ -484,6 +951,9 @@ public class Cuas {
fclt
=
QuadCLT
.
getTDCombo
(
sm
,
// final int sensor_mask,
merge_all
,
// final boolean merge_channels,
cuas_discard_border
,
// final int discard_border,
cuas_max_fold
,
// final double max_fold,
cuas_min_in_row_col
,
// final int min_in_row_col, // Minimal number of defined tiles in a row/column
null
,
// final Rectangle full_woi_in, // show larger than sensor WOI (or null)
clt_parameters
,
// CLTParameters clt_parameters,
ref_disparity
,
// double [] disparity_ref,
...
...
@@ -497,24 +967,51 @@ public class Cuas {
quadCLTs
[
nscene
],
// final QuadCLT scene,
refCLT
,
// quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true
,
// final boolean show_nan,
dbg_PxPyD_slice
,
// final double [][][] dbg_PxPyD_slice,
QuadCLT
.
THREADS_MAX
,
// int threadsMax,
debugLevel
);
// final int debugLevel)
}
if
(
dbg_PxPyD_slice
!=
null
)
{
for
(
int
slice
=
0
;
slice
<
dbg_PxPyD
.
length
;
slice
++)
{
// 3
dbg_PxPyD
[
slice
][
nscene
]
=
new
double
[
dbg_PxPyD_slice
[
0
].
length
];
// tiles
Arrays
.
fill
(
dbg_PxPyD
[
slice
][
nscene
],
Double
.
NaN
);
}
for
(
int
ntile
=
0
;
ntile
<
dbg_PxPyD_slice
[
0
].
length
;
ntile
++)
if
(
dbg_PxPyD_slice
[
0
][
ntile
]
!=
null
)
{
for
(
int
slice
=
0
;
slice
<
dbg_PxPyD
.
length
;
slice
++)
{
dbg_PxPyD
[
slice
][
nscene
][
ntile
]
=
dbg_PxPyD_slice
[
0
][
ntile
][
slice
];
}
}
}
final
float
[][]
ffclt
=
fclt
;
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTileAll
=
ai
.
getAndIncrement
();
nTileAll
<
tiles_td_all
;
nTileAll
=
ai
.
getAndIncrement
())
{
int
ntile
=
nTileAll
%
tiles_td
;
int
nsens
=
nTileAll
/
tiles_td
;
int
indx0
=
ntile
*
tile_size_td
;
int
indx1
=
indx0
+
tile_size_td
;
for
(
int
indx
=
indx0
;
indx
<
indx1
;
indx
++)
{
float
d
=
ffclt
[
nsens
][
indx
];
if
(!
Float
.
isNaN
(
d
)){
sumFclt
[
nsens
][
indx
]
+=
d
;
numAcc
[
nsens
][
indx
]++
;
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
num_tiles
;
nTile
=
ai
.
getAndIncrement
())
{
for
(
int
slice
=
0
;
slice
<
num_slices
;
slice
++)
{
// normally just one
int
fclt_offs
=
nTile
*
tile_length
;
float
[]
fclt_slice
=
ffclt
[
slice
];
float
[]
sumFclt_slice
=
sumFclt
[
slice
];
boolean
no_nans
=
true
;
int
indx
=
fclt_offs
;
for
(
int
i
=
0
;
i
<
tile_length
;
i
++)
{
if
(
Float
.
isNaN
(
fclt_slice
[
indx
++]))
{
no_nans
=
false
;
break
;
}
}
if
(
no_nans
)
{
indx
=
fclt_offs
;
float
w
=
1.0f
;
// constant weight
for
(
int
i
=
0
;
i
<
tile_length
;
i
++)
{
if
(
Float
.
isNaN
(
fclt_slice
[
indx
]))
{
sumFclt_slice
[
indx
]
+=
0
;
}
else
{
sumFclt_slice
[
indx
]
+=
w
*
fclt_slice
[
indx
];
}
indx
++;
}
sum_weights
[
slice
][
nTile
]
+=
w
;
}
}
}
...
...
@@ -528,19 +1025,21 @@ public class Cuas {
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTileAll
=
ai
.
getAndIncrement
();
nTileAll
<
tiles_td_all
;
nTileAll
=
ai
.
getAndIncrement
())
{
int
ntile
=
nTileAll
%
tiles_td
;
int
nsens
=
nTileAll
/
tiles_td
;
int
indx0
=
ntile
*
tile_size_td
;
int
indx1
=
indx0
+
tile_size_td
;
for
(
int
indx
=
indx0
;
indx
<
indx1
;
indx
++)
{
if
(
numAcc
[
nsens
][
indx
]
>
0
)
{
sumFclt
[
nsens
][
indx
]/=
numAcc
[
nsens
][
indx
];
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
num_tiles
;
nTile
=
ai
.
getAndIncrement
())
{
for
(
int
slice
=
0
;
slice
<
num_slices
;
slice
++)
{
// normally just one
int
fclt_offs
=
nTile
*
tile_length
;
float
[]
sumFclt_slice
=
sumFclt
[
slice
];
int
indx
=
fclt_offs
;
indx
=
fclt_offs
;
float
w
=
sum_weights
[
slice
][
nTile
];
// 1.0f; // constant weight
if
(
w
>
0
)
{
for
(
int
i
=
0
;
i
<
tile_length
;
i
++)
{
sumFclt_slice
[
indx
++]
/=
w
;
}
}
else
{
sumFclt
[
nsens
][
indx
]
=
Float
.
NaN
;
}
if
(
save_weights
)
{
sumFclt
[
nsens
+
num_slices
][
indx
]
=
numAcc
[
nsens
][
indx
];
for
(
int
i
=
0
;
i
<
tile_length
;
i
++)
{
sumFclt_slice
[
indx
++]
=
Float
.
NaN
;
}
}
}
}
...
...
@@ -548,7 +1047,64 @@ public class Cuas {
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
sumFclt
;
if
(
dbg_PxPyD
!=
null
)
{
String
[]
debug_frame_titles
=
{
"pX"
,
"pY"
,
"Disparity"
};
String
[]
debug_titles
=
new
String
[
quadCLTs
.
length
];
for
(
int
nscene
=
0
;
nscene
<
quadCLTs
.
length
;
nscene
++)
{
debug_titles
[
nscene
]
=
quadCLTs
[
nscene
].
getImageName
();
}
String
debugTitle
=
refCLT
.
getImageName
()+
"-pXpYD-discard"
+
cuas_discard_border
+
"_fold"
+
cuas_max_fold
+
"_min"
+
cuas_min_in_row_col
;
ShowDoubleFloatArrays
.
showArraysHyperstack
(
dbg_PxPyD
,
// double[][][] pixels,
refCLT
.
getTilesX
(),
// int width,
debugTitle
,
// String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
debug_titles
,
// String [] titles, // all slices*frames titles or just slice titles or null
debug_frame_titles
,
// String [] frame_titles, // frame titles or null
true
);
// boolean show)
}
return
new
float
[][][]
{
sumFclt
,
sum_weights
};
}
/**
* Convert scenes to a new reference (does not need to be one of the series, such as a virtual
* center in CUAS mode)
* @param quadCLTs array of scene instances,
* @param ref_old old reference scene instance with a list of reference positions and velocities
* @param ref_new new reference scene (does not need to be one of quadCLTs)
* @param name_new only needed if ref_new == null
* @param new_xyzatr new reference offset and rotation relative to the old reference scene
* @return true if no errors
*/
public
static
QuadCLT
changeReference
(
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_old
,
QuadCLT
ref_new
,
String
name_new
,
double
[][]
new_xyzatr
)
{
ErsCorrection
ers_old_reference
=
ref_old
.
getErsCorrection
();
double
[][]
inv_new_xyzatr
=
ErsCorrection
.
invertXYZATR
(
new_xyzatr
);
if
(
ref_new
==
null
)
{
String
ref_dir_path
=
ref_old
.
getX3dDirectory
(
name_new
);
File
cdir
=
new
File
(
ref_dir_path
);
ref_new
=
new
QuadCLT
(
ref_old
,
name_new
);
// empty scenes_poses
cdir
.
mkdirs
();
ref_new
.
setImagePath
(
cdir
.
getPath
());
}
ErsCorrection
ers_new_reference
=
ref_new
.
getErsCorrection
();
for
(
int
scene_index
=
0
;
scene_index
<
quadCLTs
.
length
;
scene_index
++)
{
double
[][]
scene_xyzatr
,
dxyzatr_dt
;
String
ts
=
quadCLTs
[
scene_index
].
getImageName
();
scene_xyzatr
=
ers_old_reference
.
getSceneXYZATR
(
ts
);
dxyzatr_dt
=
ers_old_reference
.
getSceneErsXYZATR_dt
(
ts
);
double
[][]
scene_new_xyzatr
=
ErsCorrection
.
combineXYZATR
(
scene_xyzatr
,
// double [][] reference_xyzatr,
inv_new_xyzatr
);
// double [][] scene_xyzatr)
ers_new_reference
.
addScene
(
ts
,
// String timestamp,
scene_new_xyzatr
,
// double [][] xyzatr,
dxyzatr_dt
);
// double [][] ers_xyzatr_dt)
}
return
ref_new
;
}
public
static
double
[][]
getRefPxPyD
(
...
...
@@ -816,5 +1372,9 @@ public class Cuas {
return
reference_pXpYD
;
// ref_pXpYD_0; //
}
}
src/main/java/com/elphel/imagej/cuas/CuasCenterLma.java
View file @
d15a47db
...
...
@@ -42,8 +42,9 @@ public class CuasCenterLma {
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
double
[][]
last_jt
=
null
;
/*
@Deprecated
public static double [][] getCenterATR(
QuadCLT [] quadCLTs,
int ref_index,
...
...
@@ -83,6 +84,46 @@ public class CuasCenterLma {
}
return rslt;
}
*/
public
static
double
[][]
getCenterATR
(
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_scene
,
int
[]
range
,
int
debugLevel
)
{
boolean
[]
param_select
=
new
boolean
[
PARAMETER_NAMES
.
length
];
Arrays
.
fill
(
param_select
,
true
);
CuasCenterLma
cuasCenterLma
=
new
CuasCenterLma
(
param_select
,
// boolean [] param_select,
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
// QuadCLT ref_scene,
range
,
// int [] range,
debugLevel
);
// int debugLevel)
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
lmaResult
=
cuasCenterLma
.
runLma
(
lambda
,
// double lambda, // 0.1
lambda_scale_good
,
// double lambda_scale_good,// 0.5
lambda_scale_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)
double
[][]
rslt
=
{
cuasCenterLma
.
getCenter
(),
cuasCenterLma
.
getRadius
()};
if
(
debugLevel
>
-
3
)
{
System
.
out
.
println
(
"lmaResult ="
+
lmaResult
+
" iterations, RMSE ="
+
cuasCenterLma
.
getRMS
()+
" ("
+
cuasCenterLma
.
getInitialRMS
()+
")"
);
System
.
out
.
println
(
"azimuth_center = "
+
rslt
[
0
][
0
]);
System
.
out
.
println
(
" tilt_center = "
+
rslt
[
0
][
1
]);
System
.
out
.
println
(
" average roll = "
+
rslt
[
0
][
2
]);
System
.
out
.
println
(
"azimuth_radius = "
+
rslt
[
1
][
0
]);
System
.
out
.
println
(
" tilt_radius = "
+
rslt
[
1
][
1
]);
}
return
rslt
;
}
public
static
double
[][]
getCenterATR
(
double
[][]
scenes_atr
,
...
...
@@ -122,6 +163,8 @@ public class CuasCenterLma {
return
rslt
;
}
/*
@Deprecated
public CuasCenterLma(
boolean [] param_select,
QuadCLT [] quadCLTs,
...
...
@@ -136,7 +179,24 @@ public class CuasCenterLma {
range, // int [] range,
debugLevel); //int debugLevel)
}
*/
public
CuasCenterLma
(
boolean
[]
param_select
,
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_scene
,
int
[]
range
,
int
debugLevel
)
{
prepareLMA
(
param_select
,
// boolean [] param_select,
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_scene
,
//int ref_index,
range
,
// int [] range,
debugLevel
);
//int debugLevel)
}
public
CuasCenterLma
(
boolean
[]
param_select
,
double
[][]
scenes_atr
,
...
...
@@ -149,8 +209,8 @@ public class CuasCenterLma {
debugLevel
);
//int debugLevel)
}
/*
@Deprecated
public int prepareLMA(
boolean [] param_select,
QuadCLT [] quadCLTs,
...
...
@@ -160,7 +220,7 @@ public class CuasCenterLma {
this.param_select = param_select;
earliest_scene = range[0];
last_scene = range[1];
int
num_scenes
=
last_scene
-
earliest_scene
+
1
;
//
int num_scenes = last_scene- earliest_scene + 1;
ErsCorrection ers_reference = quadCLTs[ref_index].getErsCorrection();
double [][] scenes_atr = new double [quadCLTs.length][];
scenes_atr[ref_index] = new double[3]; // all zeros
...
...
@@ -180,6 +240,37 @@ public class CuasCenterLma {
new int [] {earliest_scene,last_scene}, // int [] range,
debugLevel); // int debugLevel);
}
*/
public
int
prepareLMA
(
boolean
[]
param_select
,
QuadCLT
[]
quadCLTs
,
QuadCLT
ref_scene
,
int
[]
range
,
int
debugLevel
)
{
this
.
param_select
=
param_select
;
earliest_scene
=
range
[
0
];
last_scene
=
range
[
1
];
// int num_scenes = last_scene- earliest_scene + 1;
ErsCorrection
ers_reference
=
ref_scene
.
getErsCorrection
();
double
[][]
scenes_atr
=
new
double
[
quadCLTs
.
length
][];
// scenes_atr[ref_index] = new double[3]; // all zeros should not be needed, it should be in ers_reference.getSceneATR(ts) for "normal scenes
for
(
int
nscene
=
last_scene
;
nscene
>=
earliest_scene
;
nscene
--)
{
// just checking it is not isolated
if
(
quadCLTs
[
nscene
]
==
null
)
{
earliest_scene
=
nscene
+
1
;
break
;
}
// now reference scene should also be in ers_reference.getSceneXYZ(ts)
String
ts
=
quadCLTs
[
nscene
].
getImageName
();
scenes_atr
[
nscene
]
=
ers_reference
.
getSceneATR
(
ts
);
}
return
prepareLMA
(
param_select
,
// boolean [] param_select,
scenes_atr
,
// double [][] scenes_atr,
new
int
[]
{
earliest_scene
,
last_scene
},
// int [] range,
debugLevel
);
// int debugLevel);
}
public
int
prepareLMA
(
boolean
[]
param_select
,
...
...
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
View file @
d15a47db
...
...
@@ -1132,6 +1132,16 @@ public class GpuQuad{ // quad camera description
int
tilesY
=
wh
[
1
]
/
GPUTileProcessor
.
DTT_SIZE
;
return
tilesY
*
tilesX
*
num_colors
*
4
*
GPUTileProcessor
.
DTT_SIZE
*
GPUTileProcessor
.
DTT_SIZE
;
}
public
int
getNumTiles
(
boolean
use_ref
)
{
int
[]
wh
=
use_ref
?
gpu_clt_ref_wh
:
gpu_clt_wh
;
int
tilesX
=
wh
[
0
]
/
GPUTileProcessor
.
DTT_SIZE
;
int
tilesY
=
wh
[
1
]
/
GPUTileProcessor
.
DTT_SIZE
;
return
tilesY
*
tilesX
;
// *num_colors* 4 * GPUTileProcessor.DTT_SIZE * GPUTileProcessor.DTT_SIZE;
}
public
int
getCltTileLength
()
{
// per camera, in floats
return
num_colors
*
4
*
GPUTileProcessor
.
DTT_SIZE
*
GPUTileProcessor
.
DTT_SIZE
;
}
/*
public int getCltLength(boolean use_ref) {
int [] wh = use_ref ? gpu_clt_ref_wh : gpu_clt_wh;
...
...
src/main/java/com/elphel/imagej/tileprocessor/Interscene.java
View file @
d15a47db
...
...
@@ -1859,7 +1859,7 @@ public class Interscene {
public
static
double
[][]
getXyzatrImsCenter
(
public
static
double
[][]
getXyzatrImsCenter
(
// Not used
final
CLTParameters
clt_parameters
,
final
boolean
compensate_ims_rotation
,
final
boolean
inertial_only
,
...
...
src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java
View file @
d15a47db
...
...
@@ -654,8 +654,10 @@ min_str_neib_fpn 0.35
public
double
mb_tau
=
0.008
;
// time constant, sec
public
double
mb_max_gain
=
5.0
;
// motion blur maximal gain (if more - move second point more than a pixel
public
double
mb_max_gain_inter
=
2.0
;
// same for interscene correlation for pose adjustment
//CUAS mode
public
int
cuas_discard_border
=
8
;
// Discard this number of pixels from each side when merging
public
double
cuas_max_fold
=
50
;
public
int
cuas_min_in_row_col
=
4
;
// Minimal number of defined tiles in a row/column
// TODO: move next parameters elsewhere - they are not the motion blur ones.
public
int
mb_gain_index_pose
=
5
;
// pose readjust pass to switch to full mb_max_gain from mb_max_gain_inter
public
int
mb_gain_index_depth
=
5
;
// depth map refine pass (SfM) to switch to full mb_max_gain from mb_max_gain_inter
...
...
@@ -1963,6 +1965,13 @@ min_str_neib_fpn 0.35
"Maximal gain for motion blur correction (if needed more for 1 pixel, increase offset). Will be forced fro the last adjustment"
);
gd
.
addNumericField
(
"Maximal gain pose"
,
this
.
mb_max_gain_inter
,
5
,
7
,
"x"
,
"Maximal gain for motion blur correction during interscene correlation. Will be used for all but the last adjustment."
);
gd
.
addTab
(
"CUAS"
,
"CUAS Parameters"
);
gd
.
addNumericField
(
"Discard margins"
,
this
.
cuas_discard_border
,
0
,
3
,
"pix"
,
"Discards this number of pixels from each side when merging images."
);
gd
.
addNumericField
(
"Maximal X,Y fold"
,
this
.
cuas_max_fold
,
5
,
7
,
"pix"
,
"Maximal non-monotonic Px, Py in PxPyD (usually near image edges)."
);
gd
.
addNumericField
(
"Minimal tiles in a row/column"
,
this
.
cuas_min_in_row_col
,
0
,
3
,
"tiles"
,
"Discards rows then columns that have less defined tiles (noticed in a diagonal after folds removal)."
);
gd
.
addTab
(
"LMA sequence"
,
"Interscene LMA sequence control"
);
gd
.
addMessage
(
"Parameters for control of the LMA pose adjustment sequence"
);
gd
.
addNumericField
(
"Pose readjust number for full mb_gain"
,
this
.
mb_gain_index_pose
,
0
,
3
,
""
,
...
...
@@ -2845,6 +2854,11 @@ min_str_neib_fpn 0.35
this
.
mb_tau
=
gd
.
getNextNumber
();
this
.
mb_max_gain
=
gd
.
getNextNumber
();
this
.
mb_max_gain_inter
=
gd
.
getNextNumber
();
this
.
cuas_discard_border
=
(
int
)
gd
.
getNextNumber
();
this
.
cuas_max_fold
=
gd
.
getNextNumber
();
this
.
cuas_min_in_row_col
=
(
int
)
gd
.
getNextNumber
();
this
.
mb_gain_index_pose
=
(
int
)
gd
.
getNextNumber
();
this
.
mb_gain_index_depth
=(
int
)
gd
.
getNextNumber
();
...
...
@@ -3659,6 +3673,10 @@ min_str_neib_fpn 0.35
properties
.
setProperty
(
prefix
+
"mb_max_gain"
,
this
.
mb_max_gain
+
""
);
// double
properties
.
setProperty
(
prefix
+
"mb_max_gain_inter"
,
this
.
mb_max_gain_inter
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_discard_border"
,
this
.
cuas_discard_border
+
""
);
// int
properties
.
setProperty
(
prefix
+
"cuas_max_fold"
,
this
.
cuas_max_fold
+
""
);
// double
properties
.
setProperty
(
prefix
+
"cuas_min_in_row_col"
,
this
.
cuas_min_in_row_col
+
""
);
// int
properties
.
setProperty
(
prefix
+
"mb_gain_index_pose"
,
this
.
mb_gain_index_pose
+
""
);
// int
properties
.
setProperty
(
prefix
+
"mb_gain_index_depth"
,
this
.
mb_gain_index_depth
+
""
);
// int
...
...
@@ -4448,6 +4466,10 @@ min_str_neib_fpn 0.35
if
(
properties
.
getProperty
(
prefix
+
"mb_max_gain"
)!=
null
)
this
.
mb_max_gain
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"mb_max_gain"
));
if
(
properties
.
getProperty
(
prefix
+
"mb_max_gain_inter"
)!=
null
)
this
.
mb_max_gain_inter
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"mb_max_gain_inter"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_discard_border"
)!=
null
)
this
.
cuas_discard_border
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"cuas_discard_border"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_max_fold"
)!=
null
)
this
.
cuas_max_fold
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"cuas_max_fold"
));
if
(
properties
.
getProperty
(
prefix
+
"cuas_min_in_row_col"
)!=
null
)
this
.
cuas_min_in_row_col
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"cuas_min_in_row_col"
));
if
(
properties
.
getProperty
(
prefix
+
"mb_gain_index_pose"
)!=
null
)
this
.
mb_gain_index_pose
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"mb_gain_index_pose"
));
if
(
properties
.
getProperty
(
prefix
+
"mb_gain_index_depth"
)!=
null
)
this
.
mb_gain_index_depth
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"mb_gain_index_depth"
));
...
...
@@ -5239,6 +5261,10 @@ min_str_neib_fpn 0.35
imp
.
mb_max_gain
=
this
.
mb_max_gain
;
imp
.
mb_max_gain_inter
=
this
.
mb_max_gain_inter
;
imp
.
cuas_discard_border
=
this
.
cuas_discard_border
;
imp
.
cuas_max_fold
=
this
.
cuas_max_fold
;
imp
.
cuas_min_in_row_col
=
this
.
cuas_min_in_row_col
;
imp
.
mb_gain_index_pose
=
this
.
mb_gain_index_pose
;
imp
.
mb_gain_index_depth
=
this
.
mb_gain_index_depth
;
...
...
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
View file @
d15a47db
...
...
@@ -5786,16 +5786,15 @@ public class OpticalFlow {
double
[]
cuas_atr
=
ZERO3
;
if
(
extract_center_orientation
&&
clt_parameters
.
imp
.
lock_position
)
{
center_ATR
=
CuasCenterLma
.
getCenterATR
(
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_index
,
//int ref_index,
new
int
[]
{
earliest_scene
,
last_index
},
//int [] range,
quadCLTs
,
// QuadCLT [] quadCLTs,
quadCLTs
[
ref_index
],
// QuadCLT ref_scene,
ref_index, //int ref_index,
new
int
[]
{
earliest_scene
,
last_index
},
//
int [] range,
debugLevel
);
// int debugLevel);
// cuas_atr = new double [] {-center_ATR[0][0],-center_ATR[0][1],-center_ATR[0][2]};
cuas_atr
=
new
double
[]
{
center_ATR
[
0
][
0
],
center_ATR
[
0
][
1
],
center_ATR
[
0
][
2
]};
}
boolean
combine_clt
=
clt_parameters
.
imp
.
cuas_rotation
;
// (cuas_atr[0] != 0) || (cuas_atr[1] != 0) || (cuas_atr[2] != 0);
// TODO: Refine center_CLT if it exists, not crete
// TODO: Refine center_CLT if it exists, not cre
a
te
if
(
combine_clt
)
{
...
...
@@ -5810,10 +5809,11 @@ public class OpticalFlow {
if
(
combo_dsn_final
==
null
)
{
combo_dsn_final
=
quadCLTs
[
ref_index
].
restoreComboDSI
(
true
);
// also sets quadCLTs[ref_index].dsi and blue sky
}
center_CLT
=
Cuas
.
createCenterClt
(
// assuming cuas_rotation is true
clt_parameters
,
// CLTParameters clt_parameters,
quadCLTs
,
// QuadCLT [] quadCLTs,
ref_index
,
// int ref_index,
quadCLTs
[
ref_index
],
// QuadCLT ref_scene, // where combo_dsi is
null
,
// int [] range, // or null
combo_dsn_final
,
// double [][] ref_dsi, // DSI data for the reference scene (or null to read it from file)
condition_dsi
,
// boolean condition_dsi,
...
...
@@ -5828,38 +5828,16 @@ public class OpticalFlow {
}
}
// just for verification
boolean
apply_clt
=
true
;
boolean
show_clt
=
true
;
int
[]
whc
=
new
int
[
3
];
if
(
apply_clt
)
{
// set GPU with data
center_CLT
.
setQuadClt
();
//2025 mark that GPU is used for center_CLT
// quadCLTs[ref_index].setComboToTD(
center_CLT
.
setComboToTD
(
null
,
// new float [][] {center_CLT.getCenterClt()}, // ,combo_seq_clt, // final float [][] fclt,
true
,
// merge_clt, // final boolean merge_channels, // duplicate same data to all selected channels
sensor_mask_clt
,
// final int sensor_mask, // only if merge_channels
whc
,
// final int [] whc, // if int[2], will return width, height
false
);
// final boolean use_reference);
if
(
show_clt
)
{
String
suffix
=
"-virtual"
;
// ImagePlus imp_virtual = ref_clt.renderFromTD ( // do we need to update gpuQuad ?
ImagePlus
imp_virtual
=
center_CLT
.
renderFromTD
(
// do we need to update gpuQuad ?
sensor_mask_clt
,
// final int sensor_mask,
true
,
// merge_clt, // boolean merge_channels,
clt_parameters
,
// CLTParameters clt_parameters,
// clt_parameters.getColorProcParameters(ref_clt.isAux()), //ColorProcParameters colorProcParameters,
clt_parameters
.
getColorProcParameters
(
center_CLT
.
isAux
()),
//ColorProcParameters colorProcParameters,
clt_parameters
.
getRGBParameters
(),
//EyesisCorrectionParameters.RGBParameters rgbParameters,\
whc
,
// null, // int [] wh,
false
,
// toRGB, // boolean toRGB,
false
,
// use_reference, // boolean use_reference
suffix
);
// String suffix)
imp_virtual
.
show
();
}
boolean
show_clt
=
false
;
// true;
if
(
show_clt
)
{
center_CLT
.
showCenterClt
(
clt_parameters
);
// CLTParameters clt_parameters,
center_CLT
.
showCenterCltWeights
(
clt_parameters
);
// CLTParameters clt_parameters,
}
}
if
(
generate_egomotion
)
{
boolean
ego_show
=
!
clt_parameters
.
batch_run
;
//true;
String
ego_path
=
quadCLTs
[
ref_index
].
getX3dDirectory
()+
Prefs
.
getFileSeparator
()+
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
View file @
d15a47db
...
...
@@ -123,6 +123,53 @@ public class QuadCLT extends QuadCLTCPU {
}
}
public
ImagePlus
showCenterClt
(
CLTParameters
clt_parameters
)
{
if
(
getCenterClt
()
==
null
)
{
System
.
out
.
println
(
"showCenterClt(): not a center CLT"
);
return
null
;
}
int
sensor_mask_clt
=
1
;
// just one
setQuadClt
();
int
[]
whc
=
new
int
[
3
];
setComboToTD
(
null
,
// new float [][] {center_CLT.getCenterClt()}, // ,combo_seq_clt, // final float [][] fclt,
true
,
// merge_clt, // final boolean merge_channels, // duplicate same data to all selected channels
sensor_mask_clt
,
// final int sensor_mask, // only if merge_channels
whc
,
// final int [] whc, // if int[2], will return width, height
false
);
// final boolean use_reference);
String
suffix
=
"-virtual"
;
ImagePlus
imp_virtual
=
renderFromTD
(
// do we need to update gpuQuad ?
sensor_mask_clt
,
// final int sensor_mask,
true
,
// merge_clt, // boolean merge_channels,
clt_parameters
,
// CLTParameters clt_parameters,
clt_parameters
.
getColorProcParameters
(
isAux
()),
//ColorProcParameters colorProcParameters,
clt_parameters
.
getRGBParameters
(),
//EyesisCorrectionParameters.RGBParameters rgbParameters,\
whc
,
// null, // int [] wh,
false
,
// toRGB, // boolean toRGB,
false
,
// use_reference, // boolean use_reference
suffix
);
// String suffix)
imp_virtual
.
show
();
return
imp_virtual
;
}
public
ImagePlus
showCenterCltWeights
(
CLTParameters
clt_parameters
)
{
if
(
getCenterCltWeights
()
==
null
)
{
System
.
out
.
println
(
"showCenterCltWeights(): not a center CLT"
);
return
null
;
}
String
title
=
getImageName
()+
"-center_clt_weights"
;
ImagePlus
imp
=
ShowDoubleFloatArrays
.
makeArrays
(
getCenterCltWeights
(),
// float[] pixels,
getTilesX
(),
// int width,
getTilesY
(),
// int height,
title
);
// String title)
imp
.
show
();
return
imp
;
}
/**
* Remove weak non-LMA tiles if they do not have any LMA or strong neighbors and
* too few weak neighbors. Single strong neighbor within range is enough, strong/LMA
...
...
@@ -1515,6 +1562,10 @@ public class QuadCLT extends QuadCLTCPU {
preRenderGPUFromDSI
(
sensor_mask
,
// final int sensor_mask,
merge_channels
,
// final boolean merge_channels,
0
,
// final int discard_border,
0
,
// final double max_fold,
0
,
// final int min_in_row_col, // Minimal number of defined tiles in a row/column
full_woi_in
,
// final Rectangle full_woi_in, // show larger than sensor WOI in tiles (or null)
clt_parameters
,
// CLTParameters clt_parameters,
disparity_ref
,
// double [] disparity_ref,
...
...
@@ -1552,6 +1603,9 @@ public class QuadCLT extends QuadCLTCPU {
public
static
float
[][]
getTDCombo
(
final
int
sensor_mask
,
final
boolean
merge_channels
,
final
int
discard_border
,
final
double
max_fold
,
final
int
min_in_row_col
,
// Minimal number of defined tiles in a row/column
final
Rectangle
full_woi_in
,
// show larger than sensor WOI in tiles (or null)
CLTParameters
clt_parameters
,
double
[]
disparity_ref
,
...
...
@@ -1567,12 +1621,15 @@ public class QuadCLT extends QuadCLTCPU {
final
QuadCLT
ref_scene
,
// now - may be null - for testing if scene is rotated ref
// final boolean toRGB,
final
boolean
show_nan
,
// String suffix
,
final
double
[][][]
dbg_PxPyD_slice
,
int
threadsMax
,
final
int
debugLevel
){
preRenderGPUFromDSI
(
double
[][]
PxPyD
=
preRenderGPUFromDSI
(
sensor_mask
,
// final int sensor_mask,
merge_channels
,
// final boolean merge_channels,
discard_border
,
// final int discard_border,
max_fold
,
// final double max_fold,
min_in_row_col
,
// final int min_in_row_col, // Minimal number of defined tiles in a row/column
full_woi_in
,
// final Rectangle full_woi_in, // show larger than sensor WOI in tiles (or null)
clt_parameters
,
// CLTParameters clt_parameters,
disparity_ref
,
// double [] disparity_ref,
...
...
@@ -1586,11 +1643,12 @@ public class QuadCLT extends QuadCLTCPU {
scene_atr
,
// double [] scene_atr, // camera orientation relative to world frame
scene
,
//final QuadCLT scene,
ref_scene
,
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
// toRGB, // final boolean toRGB,
show_nan
,
// final boolean show_nan,
// suffix, // String suffix,
threadsMax
,
// int threadsMax,
debugLevel
);
// final int debugLevel)
if
(
dbg_PxPyD_slice
!=
null
)
{
dbg_PxPyD_slice
[
0
]
=
PxPyD
;
}
int
[]
whc
=
new
int
[
3
];
float
[][]
fclt
=
scene
.
getComboFromTD
(
sensor_mask
,
// final int sensor_mask, // only if merge_channels
...
...
@@ -1604,9 +1662,12 @@ public class QuadCLT extends QuadCLTCPU {
public
static
void
preRenderGPUFromDSI
(
public
static
double
[][]
preRenderGPUFromDSI
(
// will return PxPyD
final
int
sensor_mask
,
final
boolean
merge_channels
,
final
int
discard_border
,
final
double
max_fold
,
final
int
min_in_row_col
,
// Minimal number of defined tiles in a row/column
final
Rectangle
full_woi_in
,
// show larger than sensor WOI in tiles (or null)
CLTParameters
clt_parameters
,
double
[]
disparity_ref
,
// may be null if ref_pXpYD!=null
...
...
@@ -1620,12 +1681,15 @@ public class QuadCLT extends QuadCLTCPU {
double
[]
scene_atr
,
// camera orientation relative to world frame
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
){
double
[][]
pXpYD
;
// int tile_size = ref_scene.getTileSize();
int
width
=
ref_scene
.
getTilesX
()*
ref_scene
.
getTileSize
();
int
height
=
ref_scene
.
getTilesY
()*
ref_scene
.
getTileSize
();
// window in pixels!
final
Rectangle
window
=
(
discard_border
>
0
)?
(
new
Rectangle
(
discard_border
,
discard_border
,
width
-
2
*
discard_border
,
height
-
2
*
discard_border
)):
null
;
if
(
ref_pXpYD
!=
null
)
{
// cuas mode, ref_pXpYD defines offset reference scene
pXpYD
=
OpticalFlow
.
transformToScenePxPyD
(
ref_pXpYD
,
// final double [][] reference_pXpYD, // invalid tiles - NaN in disparity. Should be no nulls, no NaN disparity
...
...
@@ -1659,6 +1723,14 @@ public class QuadCLT extends QuadCLTCPU {
threadsMax
);
// int threadsMax)
}
}
if
(
window
!=
null
)
{
ref_scene
.
windowPsPyD
(
pXpYD
,
// final double [][] pXpYD,
window
,
// final Rectangle window) // window in pixels!
max_fold
,
// final double max_fold)
min_in_row_col
);
// final int min_in_row_col, // Minimal number of defined tiles in a row/column
}
int
rendered_width
=
scene
.
getErsCorrection
().
getSensorWH
()[
0
];
if
(
full_woi_in
!=
null
)
{
rendered_width
=
full_woi_in
.
width
*
GPUTileProcessor
.
DTT_SIZE
;
...
...
@@ -1770,15 +1842,183 @@ public class QuadCLT extends QuadCLTCPU {
threadsMax
,
// final int threadsMax, // maximal number of threads to launch
debugLevel
);
// final int globalDebugLevel);
}
return
;
return
pXpYD
;
}
public
void
windowPsPyD
(
final
double
[][]
pXpYD
,
final
Rectangle
window
,
// window in pixels!
final
double
max_fold
,
final
int
min_in_row_col
)
{
// Minimal number of defined tiles in a row/column
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
OpticalFlow
.
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
// final int tile_size = getTileSize();
final
int
tilesX
=
getTilesX
();
final
int
tilesY
=
getTilesY
();
if
(
window
==
null
)
{
return
;
}
final
double
x0
=
window
.
x
;
///dtile_size;
final
double
y0
=
window
.
y
;
//dtile_size;
final
double
x1
=
x0
+
window
.
width
;
// /dtile_size;
final
double
y1
=
y0
+
window
.
height
;
// /dtile_size;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
pXpYD
.
length
;
nTile
=
ai
.
getAndIncrement
()){
double
[]
xyd
=
pXpYD
[
nTile
];
if
((
xyd
!=
null
)
&&
((
xyd
[
0
]
<
x0
)
||
(
xyd
[
0
]
>
x1
)
||
(
xyd
[
1
]
<
y0
)
||
(
xyd
[
1
]
>
y1
)))
{
pXpYD
[
nTile
]
=
null
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
max_fold
>
0
)
{
// horizontal near-monotonic
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
[]
num_mono
=
new
int
[
tilesX
];
for
(
int
nTileY
=
ai
.
getAndIncrement
();
nTileY
<
tilesY
;
nTileY
=
ai
.
getAndIncrement
()){
Arrays
.
fill
(
num_mono
,
0
);
int
max_len_indx
=
0
;
double
prev
=
0
;
boolean
has_inv
=
false
;
for
(
int
tileX
=
1
;
tileX
<
tilesX
;
tileX
++)
{
int
indx
=
tileX
+
tilesX
*
nTileY
;
if
(
pXpYD
[
indx
]
==
null
)
{
num_mono
[
tileX
]=
num_mono
[
tileX
-
1
];
}
else
if
(
pXpYD
[
indx
][
0
]
>
(
prev
-
max_fold
))
{
num_mono
[
tileX
]=
num_mono
[
tileX
-
1
]+
1
;
if
(
num_mono
[
tileX
]
>
num_mono
[
max_len_indx
])
{
max_len_indx
=
tileX
;
}
prev
=
pXpYD
[
indx
][
0
];
}
else
{
num_mono
[
tileX
]=
0
;
has_inv
=
true
;
// at least one inversion
prev
=
pXpYD
[
indx
][
0
];
}
}
if
(
has_inv
)
{
// if there is at least one (significant) inversion - keep only longest
int
offs
=
nTileY
*
tilesX
;
for
(
int
i
=
max_len_indx
+
1
;
i
<
tilesX
;
i
++)
{
pXpYD
[
offs
+
i
]
=
null
;
}
int
start_i
=
max_len_indx
-
num_mono
[
max_len_indx
];
for
(;
start_i
>=
0
;
start_i
--){
if
((
pXpYD
[
offs
+
start_i
]
!=
null
)
&&
(
num_mono
[
start_i
]==
0
))
{
break
;
// first in monotonic sequence;
}
for
(
int
i
=
0
;
i
<
start_i
;
i
++)
{
pXpYD
[
offs
+
i
]
=
null
;
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
// vertical near-monotonic
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
[]
num_mono
=
new
int
[
tilesY
];
for
(
int
nTileX
=
ai
.
getAndIncrement
();
nTileX
<
tilesX
;
nTileX
=
ai
.
getAndIncrement
()){
Arrays
.
fill
(
num_mono
,
0
);
int
max_len_indx
=
0
;
double
prev
=
0
;
boolean
has_inv
=
false
;
for
(
int
tileY
=
1
;
tileY
<
tilesY
;
tileY
++)
{
int
indx
=
nTileX
+
tilesX
*
tileY
;
if
(
pXpYD
[
indx
]
==
null
)
{
num_mono
[
tileY
]
=
num_mono
[
tileY
-
1
];
}
else
if
(
pXpYD
[
indx
][
0
]
>
(
prev
-
max_fold
))
{
num_mono
[
tileY
]=
num_mono
[
tileY
-
1
]+
1
;
if
(
num_mono
[
tileY
]
>
num_mono
[
max_len_indx
])
{
max_len_indx
=
tileY
;
}
prev
=
pXpYD
[
indx
][
0
];
}
else
{
num_mono
[
tileY
]=
0
;
has_inv
=
true
;
// at least one inversion
prev
=
pXpYD
[
indx
][
0
];
}
}
if
(
has_inv
)
{
// if there is at least one (significant) inversion - keep only longest
for
(
int
i
=
max_len_indx
+
1
;
i
<
tilesX
;
i
++)
{
pXpYD
[
nTileX
+
i
*
tilesX
]
=
null
;
}
int
start_i
=
max_len_indx
-
num_mono
[
max_len_indx
];
for
(;
start_i
>=
0
;
start_i
--){
if
((
pXpYD
[
nTileX
+
start_i
*
tilesX
]
!=
null
)
&&
(
num_mono
[
start_i
]==
0
))
{
break
;
// first in monotonic sequence;
}
for
(
int
i
=
0
;
i
<
start_i
;
i
++)
{
pXpYD
[
nTileX
+
i
*
tilesX
]
=
null
;
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
//final int min_in_row_col, // Minimal number of defined tiles in a row/column
if
(
min_in_row_col
>
0
)
{
// horizontal too few non-null in a row
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTileY
=
ai
.
getAndIncrement
();
nTileY
<
tilesY
;
nTileY
=
ai
.
getAndIncrement
()){
int
num_defined
=
0
;
for
(
int
tileX
=
0
;
tileX
<
tilesX
;
tileX
++)
{
if
(
pXpYD
[
tileX
+
tilesX
*
nTileY
]
!=
null
)
{
num_defined
++;
}
}
if
(
num_defined
<
min_in_row_col
)
{
for
(
int
tileX
=
0
;
tileX
<
tilesX
;
tileX
++)
{
pXpYD
[
tileX
+
tilesX
*
nTileY
]
=
null
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
// vertical too few non-null in a column
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTileX
=
ai
.
getAndIncrement
();
nTileX
<
tilesX
;
nTileX
=
ai
.
getAndIncrement
()){
int
num_defined
=
0
;
for
(
int
tileY
=
0
;
tileY
<
tilesY
;
tileY
++)
{
if
(
pXpYD
[
nTileX
+
tilesX
*
tileY
]
!=
null
)
{
num_defined
++;
}
}
if
(
num_defined
<
min_in_row_col
)
{
for
(
int
tileY
=
0
;
tileY
<
tilesY
;
tileY
++)
{
pXpYD
[
nTileX
+
tilesX
*
tileY
]
=
null
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
return
;
}
public
static
double
[][]
getScenePxPyD
(
final
Rectangle
full_woi_in
,
// show larger than sensor WOI in tiles (or null)
...
...
@@ -2622,6 +2862,48 @@ public class QuadCLT extends QuadCLTCPU {
return
gpuQuad
.
getCltSize
(
use_ref
);
}
public
int
getNumTiles
(
boolean
use_ref
)
{
return
gpuQuad
.
getNumTiles
(
use_ref
);
}
public
int
getCltTileLength
()
{
// per camera, in floats
return
gpuQuad
.
getCltTileLength
();
}
public
boolean
saveCenterClt
()
{
if
(!
hasCenterClt
())
{
System
.
out
.
println
(
"saveCenterCli(): center CLT data is not set"
);
return
false
;
}
int
fclt_tile_length
=
getCltTileLength
();
float
[]
fcenter_clt_data_weights
=
new
float
[
center_clt
.
length
+
center_clt_weights
.
length
];
// to include weights
System
.
arraycopy
(
center_clt
,
0
,
fcenter_clt_data_weights
,
0
,
center_clt
.
length
);
System
.
arraycopy
(
center_clt_weights
,
0
,
fcenter_clt_data_weights
,
center_clt
.
length
,
center_clt_weights
.
length
);
saveFloatArrayInModelDirectory
(
// error
CENTER_CLT_SUFFIX
,
// String suffix,
new
String
[
1
],
// String [] labels, // or null
new
float
[][]
{
fcenter_clt_data_weights
},
// dbg_data, // float [][] data,
(
fclt_tile_length
+
1
),
// getCenterCltWH()[0], // int width,
center_clt
.
length
/
fclt_tile_length
);
// getCenterCltWH()[1]); // int height)
/*
float [] fcenter_clt_num = new float [center_clt_num.length];
for (int i = 0; i <center_clt_num.length; i++) {
fcenter_clt_num[i] = center_clt_num[i];
}
String [] clt_titles= {"CLT","num-acc"};
float [][] fdata = {center_clt, fcenter_clt_num};
saveFloatArrayInModelDirectory( // error
CENTER_CLT_SUFFIX, // String suffix,
clt_titles, // String [] labels, // or null
fdata, // dbg_data, // float [][] data,
getCenterCltWH()[0], // int width,
getCenterCltWH()[1]); // int height)
*/
return
true
;
}
public
int
getNumSensors
()
{
// Use QCC - this one may be null
if
(
gpuQuad
!=
null
)
{
return
gpuQuad
.
getNumSensors
();
...
...
@@ -4506,9 +4788,10 @@ public class QuadCLT extends QuadCLTCPU {
titles
);
}
public
void
showCentersXY
(
String
title
)
{
int
tilesX
=
tp
.
getTilesX
();
int
tilesY
=
tp
.
getTilesY
();
int
tilesX
=
getTilesX
();
int
tilesY
=
getTilesY
();
String
[]
titles
=
{
"centerX"
,
"centerY"
};
double
[][]
centers_xy
=
getCenterXY
();
double
[][]
data
=
new
double
[
2
][
tilesX
*
tilesY
];
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
d15a47db
...
...
@@ -212,8 +212,9 @@ public class QuadCLTCPU {
// combined clt for center view, only used in cuas mode
public
float
[]
center_clt
=
null
;
// clt data (single accumulated channel)
public
int
[]
center_clt_num
=
null
;
// same size as combo_clt - number of accumulated scenes for this point
public
int
center_clt_width
=
0
;
// image width to save combo_clt (and combo_clt_num) as image
/// public int [] center_clt_num = null; // same size as combo_clt - number of accumulated scenes for this point
public
float
[]
center_clt_weights
=
null
;
// 1/64 of center_clt (tilesX*tilesY)
/// public int center_clt_width = 0; // image width to save combo_clt (and combo_clt_num) as image
public
boolean
isPhotometricUpdated
()
{
...
...
@@ -238,9 +239,10 @@ public class QuadCLTCPU {
}
public
boolean
hasCenterClt
()
{
return
(
center_clt
!=
null
)
&&
(
center_clt_
num
!=
null
)
&&
(
center_clt_width
!=
0
);
return
(
center_clt
!=
null
)
&&
(
center_clt_
weights
!=
null
);
}
/*
public void setCenterClt(
float [] clt,
int [] clt_num,
...
...
@@ -249,17 +251,31 @@ public class QuadCLTCPU {
center_clt_num = clt_num;
center_clt_width = clt_width;
}
*/
public
void
setCenterClt
(
float
[]
clt
,
float
[]
clt_weights
)
{
center_clt
=
clt
;
center_clt_weights
=
clt_weights
;
}
public
float
[]
getCenterClt
()
{
return
center_clt
;
}
public
float
[]
getCenterCltWeights
()
{
return
center_clt_weights
;
}
/*
public int [] getCenterCltNum() {
return center_clt_num;
}
public int [] getCenterCltWH() {
return new int [] {center_clt_width, center_clt.length / center_clt_width};
}
public
boolean
saveCenterClt
()
{
public boolean saveCenterClt
_old
() {
if (!hasCenterClt()) {
System.out.println("saveCenterCli(): center CLT data is not set");
return false;
...
...
@@ -278,12 +294,15 @@ public class QuadCLTCPU {
getCenterCltWH()[1]); // int height)
return true;
}
*/
public
static
String
getCenterDirName
(
String
ref_name
)
{
return
ref_name
+
CENTER_DIR_SUFFIX
;
}
public
static
QuadCLT
restoreCenterClt
(
QuadCLT
ref_clt
)
{
/*
public static QuadCLT restoreCenterClt
_old
(QuadCLT ref_clt) {
String center_name = QuadCLT.getCenterDirName(ref_clt.getImageName());
String ref_dir_path = ref_clt.getX3dDirectory(center_name);
File cdir = new File(ref_dir_path);
...
...
@@ -312,20 +331,49 @@ public class QuadCLTCPU {
num, // int [] clt_num,
wh[0]); // int clt_width);
}
// TwoQuadCLT.DSI_COMBO_SUFFIX
/*
center_CLT.restoreDSI(
TwoQuadCLT.DSI_COMBO_SUFFIX, // String suffix,
true); // boolean silent)
*/
center_CLT.restoreComboDSI(true);
return center_CLT;
}
*/
public
static
QuadCLT
restoreCenterClt
(
QuadCLT
ref_clt
)
{
String
center_name
=
QuadCLT
.
getCenterDirName
(
ref_clt
.
getImageName
());
String
ref_dir_path
=
ref_clt
.
readX3dDirectory
(
center_name
);
if
(
ref_dir_path
==
null
)
{
System
.
out
.
println
(
"restoreCenterClt(): directory does not exist: "
+
ref_dir_path
);
return
null
;
}
File
cdir
=
new
File
(
ref_dir_path
);
if
(!
cdir
.
exists
()
||
!
cdir
.
isDirectory
())
{
System
.
out
.
println
(
"restoreCenterClt(): directory does not exist: "
+
ref_dir_path
);
return
null
;
}
QuadCLT
center_CLT
=
new
QuadCLT
(
ref_clt
,
center_name
);
center_CLT
.
setImagePath
(
cdir
.
getPath
());
int
[]
wh
=
new
int
[
2
];
float
[][]
fclt_w
=
center_CLT
.
readFloatArrayFromModelDirectory
(
CENTER_CLT_SUFFIX
,
// String suffix,
0
,
// int num_slices, // (0 - all)
wh
);
// int [] wh)
if
(
fclt_w
!=
null
)
{
if
(
fclt_w
.
length
!=
1
)
{
System
.
out
.
println
(
"restoreCenterClt(): expected a single-slice data, got "
+
fclt_w
.
length
+
" slices."
);
return
null
;
}
int
fclt_tile_length
=
center_CLT
.
getCltTileLength
();
float
[]
center_clt_weights
=
new
float
[
fclt_w
[
0
].
length
/(
fclt_tile_length
+
1
)];
float
[]
center_clt
=
new
float
[
fclt_w
[
0
].
length
/(
fclt_tile_length
+
1
)
*
fclt_tile_length
];
System
.
arraycopy
(
fclt_w
[
0
],
0
,
center_clt
,
0
,
center_clt
.
length
);
System
.
arraycopy
(
fclt_w
[
0
],
center_clt
.
length
,
center_clt_weights
,
0
,
center_clt_weights
.
length
);
center_CLT
.
setCenterClt
(
center_clt
,
// float [] clt,
center_clt_weights
);
// int clt_width);
}
center_CLT
.
restoreComboDSI
(
true
);
return
center_CLT
;
}
public
String
getReferenceTimestamp
()
{
return
timestamp_reference
;
}
...
...
@@ -2848,6 +2896,25 @@ public class QuadCLTCPU {
public
TileProcessor
getTileProcessor
()
{
return
tp
;
}
/*
public int getTileLength() {
return tp.getTileSize()*tp.getTileSize();
}
public int getCltTileLength() {
return 4*tp.getTileSize()*tp.getTileSize();
}
*/
public
int
getTileSize
()
{
return
tp
.
getTileSize
();
}
public
int
getTilesX
()
{
return
tp
.
getTilesX
();
}
public
int
getTilesY
()
{
return
tp
.
getTilesY
();
}
public
int
getNumSensors
()
{
if
(
geometryCorrection
==
null
)
{
System
.
out
.
println
(
"*** BUG! geometryCorrection is not set, number of sensors is unknown! Will use 4 sensors ****"
);
...
...
@@ -3050,6 +3117,14 @@ public class QuadCLTCPU {
true
);
//newAllowed, // save
return
x3d_path
;
}
public
String
readX3dDirectory
(
String
name
)
{
// replace direct calculations
String
x3d_path
=
correctionsParameters
.
selectX3dDirectory
(
// for x3d and obj
name
,
// quad timestamp. Will be ignored if correctionsParameters.use_x3d_subdirs is false
correctionsParameters
.
x3dModelVersion
,
false
,
// smart,
false
);
//newAllowed, // save
return
x3d_path
;
}
/**
* Discriminate "blue sky" areas with no details at infinity. Such areas
...
...
@@ -11848,6 +11923,37 @@ public class QuadCLTCPU {
}
}
public
ImagePlus
show_pXpYD
(
double
[][]
pXpYD
,
String
suffix
,
boolean
show
)
{
if
(
suffix
==
null
)
{
suffix
=
""
;
}
String
[]
titles
=
{
"pX"
,
"pY"
,
"Disparity"
};
double
[][]
dbg_img
=
new
double
[
titles
.
length
][
pXpYD
.
length
];
for
(
int
i
=
0
;
i
<
dbg_img
.
length
;
i
++)
{
Arrays
.
fill
(
dbg_img
[
i
],
Double
.
NaN
);
}
for
(
int
nTile
=
0
;
nTile
<
pXpYD
.
length
;
nTile
++){
if
(
pXpYD
[
nTile
]
!=
null
)
{
for
(
int
i
=
0
;
i
<
pXpYD
[
nTile
].
length
;
i
++)
{
dbg_img
[
i
][
nTile
]
=
pXpYD
[
nTile
][
i
];
}
}
}
ImagePlus
imp
=
ShowDoubleFloatArrays
.
makeArrays
(
dbg_img
,
getTilesX
(),
// int width,
getTilesY
(),
// int height,
getImageName
()+
"-pXpYD"
+
suffix
,
titles
);
if
(
show
)
{
imp
.
show
();
}
return
imp
;
}
public
static
void
showPimuOffsets
(
CLTParameters
clt_parameters
)
{
showPimuOffsets
(
clt_parameters
.
imp
.
get_pimu_offs
());
}
...
...
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