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
164444fe
Commit
164444fe
authored
Dec 02, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
still working on textures
parent
433c7f7f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
967 additions
and
656 deletions
+967
-656
OpticalFlow.java
...ain/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
+1
-1
QuadCLT.java
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
+22
-3
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+8
-4
TexturedModel.java
...n/java/com/elphel/imagej/tileprocessor/TexturedModel.java
+776
-634
TileCluster.java
...ain/java/com/elphel/imagej/tileprocessor/TileCluster.java
+101
-6
TileNeibs.java
src/main/java/com/elphel/imagej/tileprocessor/TileNeibs.java
+32
-0
TileProcessor.java
...n/java/com/elphel/imagej/tileprocessor/TileProcessor.java
+27
-8
No files found.
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
View file @
164444fe
...
...
@@ -8044,7 +8044,7 @@ public class OpticalFlow {
payload_blue_sky
=
new
double
[
tiles
];
Arrays
.
fill
(
payload_blue_sky
,
Double
.
NaN
);
}
combo_dsn_final
[
COMBO_DSN_INDX_BLUE_SKY
]
=
payload_blue_sky
;
// restore modified parameters
clt_parameters
.
img_dtt
.
bimax_combine_mode
=
save_bimax_combine_mode
;
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
View file @
164444fe
...
...
@@ -1788,7 +1788,9 @@ public class QuadCLT extends QuadCLTCPU {
final
boolean
filter_bg
,
// remove bg tiles (possibly occluded)
final
double
max_distortion
,
// maximal neighbor tiles offset as a fraction of tile size (8)
final
int
[]
cluster_index
,
// [tilesX*tilesY]
final
boolean
[]
border
,
// border tiles
final
boolean
[]
border
,
// border tiles for clusters?
final
int
discard_frame_edges
,
// do not use tiles that have pixels closer to the frame margins
final
int
keep_frame_tiles
,
// do not discard pixels for border tiles in reference frame
final
boolean
keep_channels
,
final
int
debugLevel
){
// FIXME: Move to clt_parameters;
...
...
@@ -1990,8 +1992,12 @@ public class QuadCLT extends QuadCLTCPU {
final
int
tilesX
=
scene
.
getTileProcessor
().
getTilesX
();
final
int
tilesY
=
scene
.
getTileProcessor
().
getTilesY
();
final
int
tiles
=
tilesX
*
tilesY
;
int
tile_size
=
scene
.
getTileProcessor
().
getTileSize
();
final
int
tile_size
=
scene
.
getTileProcessor
().
getTileSize
();
int
tile_len
=
tile_size
*
tile_size
;
// final int transform_size = clt_parameters.transform_size;
final
int
full_width
=
tilesX
*
tile_size
;
final
int
full_height
=
tilesY
*
tile_size
;
final
double
[][][][]
texture_tiles88
=
new
double
[
tilesY
][
tilesX
][][];
// here - non-overlapped!
// copy from windowed output to
final
TpTask
[]
ftp_tasks
=
tp_tasks
[
0
];
...
...
@@ -2033,7 +2039,7 @@ public class QuadCLT extends QuadCLTCPU {
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
max_distortion
>
0
)
{
// remove distorted tiles
if
(
(
max_distortion
>
0
)
||
(
discard_frame_edges
>
0
)
)
{
// remove distorted tiles
double
max_distortion2
=
max_distortion
*
max_distortion
;
final
TileNeibs
tn
=
new
TileNeibs
(
tilesX
,
tilesY
);
final
boolean
[]
distorted
=
new
boolean
[
tiles
];
...
...
@@ -2078,6 +2084,19 @@ public class QuadCLT extends QuadCLTCPU {
}
}
}
// see if the tile should be removed because it is too close to the edge of the scene frame
if
(!
distorted
[
nTile
]
&&
(
discard_frame_edges
>
0
))
{
if
((
tileX
>=
keep_frame_tiles
)
&&
(
tileY
>=
keep_frame_tiles
)
&&
(
tileX
<
(
tilesX
-
keep_frame_tiles
))
&&
(
tileY
<
(
tilesY
-
keep_frame_tiles
)))
{
if
(
(
centerXY
[
0
]
<
discard_frame_edges
)
||
(
centerXY
[
1
]
<
discard_frame_edges
)
||
(
centerXY
[
0
]
>
(
full_width
-
discard_frame_edges
-
1
))
||
(
centerXY
[
1
]
>
(
full_height
-
discard_frame_edges
-
1
)))
{
distorted
[
nTile
]
=
true
;
}
}
}
}
else
{
if
(
debugLevel
>
-
3
)
{
System
.
out
.
println
(
"Non-null texture for no-cluster, nTile="
+
nTile
+
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
164444fe
...
...
@@ -12056,6 +12056,7 @@ public class QuadCLTCPU {
clt_parameters
.
maxZtoXY
,
// double maxZtoXY, // 10.0. <=0 - do not use
clt_parameters
.
maxZ
,
clt_parameters
.
limitZ
,
null
,
// dbg_disp_tri_slice, // double [][] dbg_disp_tri_slice,
debugLevel
+
1
);
// int debug_level) > 0
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
...
...
@@ -12155,6 +12156,7 @@ public class QuadCLTCPU {
clt_parameters
.
maxZtoXY
,
// double maxZtoXY, // 10.0. <=0 - do not use
clt_parameters
.
maxZ
,
clt_parameters
.
limitZ
,
null
,
// double [][] dbg_disp_tri_slice,
debugLevel
+
1
);
// int debug_level) > 0
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
...
...
@@ -12203,7 +12205,8 @@ public class QuadCLTCPU {
double
maxDispTriangle
,
// relative <=0 - do not use
double
maxZtoXY
,
// 10.0. <=0 - do not use
double
maxZ
,
// far clip (0 - do not clip). Negative - limit by max
boolean
limitZ
,
boolean
limitZ
,
double
[][]
dbg_disp_tri_slice
,
int
debug_level
)
throws
IOException
{
...
...
@@ -12315,19 +12318,20 @@ public class QuadCLTCPU {
}
}
if
(
show_triangles
)
{
if
(
show_triangles
||
(
dbg_disp_tri_slice
!=
null
)
)
{
double
[]
ddisp
=
(
disparity
==
null
)?(
new
double
[
1
]):
disparity
;
if
(
disparity
==
null
)
{
ddisp
[
0
]
=
min_disparity
;
}
tp
.
testTriangles
(
texturePath
,
(
show_triangles
?
texturePath:
null
)
,
bounds
,
selected
,
ddisp
,
// disparity, // if disparity.length == 1 - use for all
tile_size
,
indices
,
triangles
);
triangles
,
dbg_disp_tri_slice
);
// double [][] debug_triangles);
}
if
(
x3dOutput
!=
null
)
{
x3dOutput
.
addCluster
(
...
...
src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java
View file @
164444fe
...
...
@@ -48,14 +48,14 @@ import ij.Prefs;
public
class
TexturedModel
{
public
static
final
int
THREADS_MAX
=
100
;
// maximal number of threads to launch
public
static
final
int
TILE_EMPTY
=
0
;
public
static
final
int
TILE_BORDER
=
1
;
public
static
final
int
TILE_BORDER_FLOAT
=
2
;
public
static
final
int
TILE_CONFIRMED
=
3
;
public
static
final
int
TILE_BORDER
=
1
;
// tile shared between meshes, border with known (not float) disparity
public
static
final
int
TILE_BORDER_FLOAT
=
2
;
// border tile with disparity calculated from neighbors
public
static
final
int
TILE_CONFIRMED
=
3
;
// internal (not border) mesh tile
public
static
final
int
TILE_CANDIDATE
=
4
;
// not used
public
static
final
int
CLUSTER_NAN
=
-
2
;
// disparity is NaN
public
static
final
int
CLUSTER_UNASSIGNED
=
-
1
;
// not yet assinged (>=0 - cluster number)
//
// long startStepTime;
public
static
boolean
isBorder
(
int
d
)
{
return
(
d
==
TILE_BORDER
)
||
(
d
==
TILE_BORDER_FLOAT
);
...
...
@@ -64,12 +64,16 @@ public class TexturedModel {
public
static
TileCluster
[]
clusterizeFgBg
(
//
final
int
tilesX
,
final
double
[][]
disparities
,
// may have more layers
final
boolean
[]
blue_sky
,
// use to expand background by blurring available data?
final
int
blue_sky_layer
,
final
int
blue_sky_below
,
final
boolean
[]
selected
,
// to remove sky (pre-filter by caller, like for ML?)
final
double
disp_adiffo
,
final
double
disp_rdiffo
,
final
double
disp_adiffd
,
final
double
disp_rdiffd
,
final
double
disp_fof
,
// enable higher difference (scale) for fried of a friend
final
int
cluster_gap
,
// gap between clusters
final
int
debugLevel
)
{
final
double
disp_border
=
disp_fof
;
final
int
tiles
=
disparities
[
0
].
length
;
...
...
@@ -78,10 +82,7 @@ public class TexturedModel {
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
TileNeibs
tn
=
new
TileNeibs
(
tilesX
,
tilesY
);
// final boolean [][][] connections = new boolean [tiles][][];
final
double
[][][][]
connections
=
new
double
[
tiles
][][][];
// final boolean [][][][] bconn = new double [boolean][][][];
// final int [][] num_neibs = new int[tiles][layers];
final
int
[][]
num_neibs_dir
=
new
int
[
tiles
][
layers
];
// -1 - none, otherwise - bitmask
final
int
[][]
ncluster
=
new
int
[
tiles
][
layers
];
// -2 - NaN, -1 - not yet assigned, 0+ - cluster number
for
(
int
tile
=
0
;
tile
<
tiles
;
tile
++)
{
...
...
@@ -93,7 +94,7 @@ public class TexturedModel {
num_bits
[
i
]+=(
d
&
1
);
}
}
// calculate "connections - per tile, per layer, per direction (1 of the first 4), per target layer - normalized difference difference
final
int
dbg_tile
=
(
debugLevel
>
0
)?
1090
:-
1
;
// 977 : -1;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
...
...
@@ -108,7 +109,7 @@ public class TexturedModel {
if
(
connections
[
tile
]
==
null
)
{
connections
[
tile
]
=
new
double
[
layers
][][];
}
// connections[tile][layer] = new double [TileNeibs.DIRS/2][
];
boolean
is_bs
=
(
layer
==
blue_sky_layer
)
&&
blue_sky
[
tile
];
connections
[
tile
][
layer
]
=
new
double
[
TileNeibs
.
DIRS
][];
// leave room for future symmetry
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
/
2
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
...
...
@@ -124,7 +125,10 @@ public class TexturedModel {
double
max_disp_diff
=
((
dir
&
1
)
==
0
)
?
(
disp_adiffo
+
mid_disp
*
disp_rdiffo
)
:
(
disp_adiffd
+
mid_disp
*
disp_rdiffd
);
connections
[
tile
][
layer
][
dir
][
layer1
]
=
Math
.
abs
(
disparities
[
layer
][
tile
]
-
disparities
[
layer1
][
tile1
])/
max_disp_diff
;
boolean
is_bs1
=
(
layer1
==
blue_sky_layer
)
&&
blue_sky
[
tile1
];
if
(
is_bs1
==
is_bs
)
{
// do not fix bs/no bs
connections
[
tile
][
layer
][
dir
][
layer1
]
=
Math
.
abs
(
disparities
[
layer
][
tile
]
-
disparities
[
layer1
][
tile1
])/
max_disp_diff
;
}
}
}
}
...
...
@@ -138,7 +142,7 @@ public class TexturedModel {
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
//
calculate total number of connections (w/o fof)
by combining opposite directions
//
Fill in opposite connections
by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
...
...
@@ -171,7 +175,8 @@ public class TexturedModel {
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
// calculate total number of connections (w/o fof) with value < 1.0, increment once
// per direction even if there are multiple connected layers
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
...
...
@@ -180,13 +185,11 @@ public class TexturedModel {
System
.
out
.
println
(
"clusterizeFgBg().3: tile="
+
tile
);
}
for
(
int
layer
=
0
;
layer
<
layers
;
layer
++)
if
(
connections
[
tile
][
layer
]
!=
null
){
// num_neibs[tile][layer]++; // has center tile, maximal will be 9
num_neibs_dir
[
tile
][
layer
]
=
1
;
// center tile
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
;
dir
++)
{
if
(
connections
[
tile
][
layer
][
dir
]
!=
null
)
{
for
(
int
layer1
=
0
;
layer1
<
layers
;
layer1
++)
{
if
(
connections
[
tile
][
layer
][
dir
][
layer1
]
<=
1.0
)
{
// Double.NaN - OK
// num_neibs[tile][layer]++;
num_neibs_dir
[
tile
][
layer
]
|=
2
<<
dir
;
// 9 bits
break
;
// increment once per dir
}
...
...
@@ -199,6 +202,7 @@ public class TexturedModel {
};
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
debugLevel
>
0
)
{
String
[]
dbg_titles
=
{
"FG"
,
"BG"
};
double
[][]
dbg_img
=
new
double
[
layers
][
tiles
];
...
...
@@ -222,13 +226,13 @@ public class TexturedModel {
"disparities"
,
dbg_titles
);
}
final
ArrayList
<
TileCluster
>
cluster_list
=
new
ArrayList
<
TileCluster
>();
// build all clusters
int
tile_start
=
0
;
double
disparity
[]
=
new
double
[
tiles
];
// current cluster disparities
int
[]
tile_stat
=
new
int
[
tiles
];
// int [] tile_layer = new int [tiles]; // just to know which layer was used for assigned tiles
// int current_cluster = 0;
final
boolean
debug_index
=
debugLevel
>
0
;
while
(
true
)
{
...
...
@@ -246,7 +250,7 @@ public class TexturedModel {
nn
=
n_neibs
;
best_tile
=
tile
;
best_layer
=
layer
;
if
(
nn
==
(
TileNeibs
.
DIRS
+
1
))
{
if
(
nn
==
(
TileNeibs
.
DIRS
+
1
))
{
// No sense to look more - it can not be > 9
break
find_start
;
}
}
...
...
@@ -264,6 +268,7 @@ public class TexturedModel {
Arrays
.
fill
(
tile_stat
,
0
);
ArrayList
<
Point
>
tile_layer_list
=
new
ArrayList
<
Point
>();
// pair of int x tile, int y - layer
Point
p0
=
new
Point
(
best_tile
,
best_layer
);
// First point will always be good
boolean
sky_cluster
=
(
best_layer
==
blue_sky_layer
)
&&
blue_sky
[
best_tile
];
int
num_tiles
=
0
;
tile_layer_list
.
add
(
p0
);
while
(!
tile_layer_list
.
isEmpty
())
{
...
...
@@ -281,21 +286,20 @@ public class TexturedModel {
}
}
else
{
confirm
=
true
;
// see if it has confirmed (or margin) same-layer neighbor 1.5 times more disparity difference
// in such case - mark this tile TILE_BORDER_FLOAT (to split mesh) and unconfirm
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
// should always be > 0 here
//is it a border tile or already confirmed one ?
// if ((tile_stat[tile1] == TILE_BORDER) || (tile_stat[tile1] == TILE_CONFIRMED)){
if
(
isBorder
(
tile_stat
[
tile1
])
||
(
tile_stat
[
tile1
]
==
TILE_CONFIRMED
)){
double
mid_disp
=
Math
.
max
(
0.0
,
0.5
*(
disparities
[
layer
][
tile
]
+
disparity
[
tile1
]));
double
max_disp_diff
=
((
dir
&
1
)
==
0
)
?
(
disp_adiffo
+
mid_disp
*
disp_rdiffo
)
:
(
disp_adiffd
+
mid_disp
*
disp_rdiffd
);
// max_disp_diff *= (tile_stat[tile1] == TILE_BORDER)? disp_border : disp_fof;
max_disp_diff
*=
isBorder
(
tile_stat
[
tile1
])?
disp_border
:
disp_fof
;
if
((
Math
.
abs
(
disparities
[
layer
][
tile
]
-
disparity
[
tile1
])/
max_disp_diff
)
>
1.0
){
confirm
=
false
;
// too large diff
// make it a border tile, but keep disparity
// disparity[tile] = disparities[layer][tile];
tile_stat
[
tile
]
=
TILE_BORDER_FLOAT
;
// TILE_BORDER;
break
;
}
...
...
@@ -311,7 +315,6 @@ public class TexturedModel {
System
.
out
.
println
(
"clusterizeFgBg(): 5. Disparity is set NaN for tile "
+
tile
);
}
ncluster
[
tile
][
layer
]
=
cluster_list
.
size
();
// current cluster number - Mark as assigned
// tile_layer[tile] = layer;
// right here - update number of neighbors for used tile
num_neibs_dir
[
tile
][
layer
]
=
0
;
// bitmap, 0- -center, 1..8 - up, ...
// update number of neighbors pointed here
...
...
@@ -324,6 +327,8 @@ public class TexturedModel {
// update neighbors bits (for number of neighbors calculation)
int
rdir
=
TileNeibs
.
reverseDir
(
dir
);
num_neibs_dir
[
tile
][
layer
]
&=
~(
2
<<
rdir
);
// zero out pointed to this tile
// check - maybe there is another layer (but why both layer1 and layer2?)
// do we need to hadle sky here too?
for
(
int
layer1
=
0
;
layer1
<
layers
;
layer1
++)
if
(
ncluster
[
tile1
][
layer1
]
==
CLUSTER_UNASSIGNED
)
{
// from where connection
// ncluster[tile][layer] is already assigned
for
(
int
layer2
=
0
;
layer2
<
layers
;
layer2
++)
if
(
ncluster
[
tile
][
layer2
]
==
CLUSTER_UNASSIGNED
){
// to where connection
...
...
@@ -337,16 +342,16 @@ public class TexturedModel {
int
layer1
=
-
1
;
int
layer_assigned
=
-
1
;
//earlier assigned, can not continue but use disparity
if
((
connections
[
tile
][
layer
]
!=
null
)
&&
(
connections
[
tile
][
layer
][
dir
]
!=
null
))
{
for
(
int
l
=
0
;
l
<
layers
;
l
++)
if
(
connections
[
tile
][
layer
][
dir
][
l
]
<=
1.0
){
for
(
int
l
=
0
;
l
<
layers
;
l
++)
if
(
connections
[
tile
][
layer
][
dir
][
l
]
<=
1.0
){
// connections between sky and not sky will be NaN here
// verify it was not already used. If used - use used disparity for the border
// **** (select correct layer for that border disparity
if
(
ncluster
[
tile1
][
l
]
==
CLUSTER_UNASSIGNED
)
{
if
((
layer1
<
0
)
||
(
connections
[
tile
][
layer
][
dir
][
l
]
<
connections
[
tile
][
layer
][
dir
][
layer1
]))
{
layer1
=
l
;
layer1
=
l
;
// best neighbor
}
}
else
{
// already assigned to some cluster that was split
if
((
layer_assigned
<
0
)
||
(
connections
[
tile
][
layer
][
dir
][
l
]
<
connections
[
tile
][
layer
][
dir
][
layer_assigned
]))
{
layer_assigned
=
l
;
layer_assigned
=
l
;
// best of assigned layers
}
}
}
...
...
@@ -357,7 +362,7 @@ public class TexturedModel {
if
(
Double
.
isNaN
(
disparity
[
tile1
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): *1. Disparity is set NaN for tile "
+
tile1
);
}
}
else
if
((
layer1
<
0
)
||
(
connections
[
tile
][
layer
][
dir
][
layer1
]
>
1.0
))
{
// no connections in this direction - add border using same disparity as this tile
}
else
if
((
layer1
<
0
)
||
!(
connections
[
tile
][
layer
][
dir
][
layer1
]
<=
1.0
))
{
// no connections in this direction - add border using same disparity as this tile
if
(
tile_stat
[
tile1
]
==
TILE_EMPTY
)
{
// not yet set (otherwise keep)
tile_stat
[
tile1
]
=
TILE_BORDER_FLOAT
;
//TILE_BORDER;
disparity
[
tile1
]
=
disparity
[
tile
];
...
...
@@ -377,6 +382,7 @@ public class TexturedModel {
}
// }
}
// while (!tile_layer_list.isEmpty())
// finished current cluster, see if it has any tiles
if
(
num_tiles
>
0
)
{
// generate/add new cluster, update
// Create and crop cluster,(update neighbors?)
int
min_x
=
tilesX
,
min_y
=
tilesY
,
max_x
=
0
,
max_y
=
0
;
...
...
@@ -391,6 +397,12 @@ public class TexturedModel {
}
}
}
if
(
sky_cluster
)
{
// increase bounding box for sky cluster
min_y
=
0
;
max_y
+=
blue_sky_below
;
min_x
=
0
;
max_x
=
tilesX
-
1
;
}
int
width
=
max_x
-
min_x
+
1
;
int
height
=
max_y
-
min_y
+
1
;
...
...
@@ -430,7 +442,8 @@ public class TexturedModel {
bounds
,
cluster_list
.
size
(),
// (debug_index? cluster_list.size(): -1),
border_crop
,
disparity_crop
));
disparity_crop
,
sky_cluster
));
// boolean is_sky));
cluster_list
.
add
(
tileCluster
);
// update
}
else
{
...
...
@@ -439,8 +452,8 @@ public class TexturedModel {
}
}
}
// while (true) { - generating clusters
// c
onsolidate clusters "good enough"
// consolidate clusters "good enough", use bounding box intersections, add cluster_gap to grow extra tiles by Gaussian
// c
luster_gap
int
[]
comb_clusters
=
new
int
[
cluster_list
.
size
()];
Arrays
.
fill
(
comb_clusters
,-
1
);
int
this_combo
=
0
;
...
...
@@ -461,7 +474,7 @@ public class TexturedModel {
// check to intersection with all prior clusters in this combo
candidate_cluster:
{
Rectangle
new_bounds
=
cluster_list
.
get
(
index_other
).
getBounds
(
);
Rectangle
new_bounds
=
cluster_list
.
get
(
index_other
).
getBounds
(
cluster_gap
);
// cluster_gap should be 2x
for
(
int
index_already
=
index_first
;
index_already
<
index_other
;
index_already
++)
if
(
comb_clusters
[
index_already
]
==
this_combo
)
{
if
(
cluster_list
.
get
(
index_already
).
getBounds
().
intersects
(
new_bounds
))
{
break
candidate_cluster
;
// intersects - skip it
...
...
@@ -478,7 +491,8 @@ public class TexturedModel {
full_tiles
,
(
debug_index
?
0
:-
1
),
null
,
null
);
null
,
false
);
// boolean is_sky));
}
for
(
int
i
=
0
;
i
<
comb_clusters
.
length
;
i
++)
{
consolidated_clusters
[
comb_clusters
[
i
]].
add
(
cluster_list
.
get
(
i
));
...
...
@@ -526,7 +540,7 @@ public class TexturedModel {
return
consolidated_clusters
;
}
// Starting redoing
public
static
boolean
output3d
(
// USED in lwir
CLTParameters
clt_parameters
,
ColorProcParameters
colorProcParameters
,
...
...
@@ -535,7 +549,6 @@ public class TexturedModel {
// if null - use reference scene
QuadCLT
[]
scenes
,
double
[][]
combo_dsn_final
,
// null OK, will read file
// final int threadsMax, // maximal number of threads to launch
final
boolean
updateStatus
,
final
int
debugLevel
)
{
...
...
@@ -544,6 +557,8 @@ public class TexturedModel {
final
int
ref_index
=
scenes
.
length
-
1
;
final
QuadCLT
ref_scene
=
scenes
[
ref_index
];
final
TileProcessor
tp
=
ref_scene
.
getTileProcessor
();
final
boolean
debug_disp_tri
=
!
batch_mode
&&
(
debugLevel
>
0
);
// TODO: use clt_parameters
if
(
ref_scene
.
image_data
==
null
){
return
false
;
// not used in lwir
}
...
...
@@ -552,16 +567,19 @@ public class TexturedModel {
WavefrontExport
wfOutput
=
null
;
ArrayList
<
TriMesh
>
tri_meshes
=
null
;
long
startStepTime
=
System
.
nanoTime
();
final
int
tilesX
=
tp
.
getTilesX
();
// final int tilesY = tp.getTilesY();
final
int
transform_size
=
tp
.
getTileSize
();
final
double
tex_disp_adiffo
=
clt_parameters
.
tex_disp_adiffo
;
// 0.35; // 0.3; disparity absolute tolerance to connect in ortho directions
final
double
tex_disp_rdiffo
=
clt_parameters
.
tex_disp_rdiffo
;
// 0.12; // 0.1; disparity relative tolerance to connect in ortho directions
final
double
tex_disp_adiffd
=
clt_parameters
.
tex_disp_adiffd
;
// 0.6; // 0.4; disparity absolute tolerance to connect in diagonal directions
final
double
tex_disp_rdiffd
=
clt_parameters
.
tex_disp_rdiffd
;
// 0.18; // 0.12; disparity relative tolerance to connect in diagonal directions
final
double
tex_disp_fof
=
clt_parameters
.
tex_disp_fof
;
// 1.5; // Increase tolerance for friend of a friend
final
double
tex_fg_bg
=
clt_parameters
.
tex_fg_bg
;
// 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
// final double tex_distort = clt_parameters.tex_distort; // 0.1; // Maximal texture distortion to accumulate multiple scenes
final
int
tilesX
=
tp
.
getTilesX
();
final
int
transform_size
=
tp
.
getTileSize
();
final
double
tex_disp_adiffo
=
clt_parameters
.
tex_disp_adiffo
;
// 0.35; // 0.3; disparity absolute tolerance to connect in ortho directions
final
double
tex_disp_rdiffo
=
clt_parameters
.
tex_disp_rdiffo
;
// 0.12; // 0.1; disparity relative tolerance to connect in ortho directions
final
double
tex_disp_adiffd
=
clt_parameters
.
tex_disp_adiffd
;
// 0.6; // 0.4; disparity absolute tolerance to connect in diagonal directions
final
double
tex_disp_rdiffd
=
clt_parameters
.
tex_disp_rdiffd
;
// 0.18; // 0.12; disparity relative tolerance to connect in diagonal directions
final
double
tex_disp_fof
=
clt_parameters
.
tex_disp_fof
;
// 1.5; // Increase tolerance for friend of a friend
final
double
tex_fg_bg
=
clt_parameters
.
tex_fg_bg
;
// 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
final
int
tex_cluster_gap
=
2
;
// gap between clusters Make clt_parameters
final
double
max_disparity_lim
=
100.0
;
// do not allow stray disparities above this
final
double
min_trim_disparity
=
2.0
;
// do not try to trim texture outlines with lower disparities
final
int
width
=
tilesX
*
transform_size
;
// for debug only
final
int
height
=
tp
.
getTilesY
()
*
transform_size
;
// get multi-scene disparity map for FG and BG and filter it
if
(
combo_dsn_final
==
null
)
{
combo_dsn_final
=
scenes
[
ref_index
].
readDoubleArrayFromModelDirectory
(
...
...
@@ -573,7 +591,7 @@ public class TexturedModel {
boolean
[]
sky_invert
=
new
boolean
[
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_BLUE_SKY
].
length
];
for
(
int
i
=
0
;
i
<
sky_tiles
.
length
;
i
++)
{
sky_tiles
[
i
]
=
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_BLUE_SKY
][
i
]
>
0.0
;
sky_invert
[
i
]
=
!
sky_tiles
[
i
];
sky_invert
[
i
]
=
!
sky_tiles
[
i
];
// not used
}
// re-load , should create quadCLTs[ref_index].dsi
double
[][]
dls_fg
=
{
...
...
@@ -581,6 +599,8 @@ public class TexturedModel {
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_LMA
],
combo_dsn_final
[
OpticalFlow
.
COMBO_DSN_INDX_STRENGTH
]
};
// currently conditionInitialDS() zeroes disparity for blue_sky. TODO: allow some FG over blue_sky?
double
[][]
ds_fg
=
OpticalFlow
.
conditionInitialDS
(
true
,
// boolean use_conf, // use configuration parameters, false - use following
clt_parameters
,
// CLTParameters clt_parameters,
...
...
@@ -609,44 +629,42 @@ public class TexturedModel {
ds_fg_bg
[
1
][
i
]
=
Double
.
NaN
;
}
}
int
sky_layer
=
0
;
int
sky_below
=
10
;
// extend sky these tile rows below lowest
// Create data for consolidated textures (multiple texture segments combined in same "passes"
TileCluster
[]
tileClusters
=
clusterizeFgBg
(
// wrong result type, not decided
tilesX
,
// final int tilesX,
ds_fg_bg
,
// final double [][] disparities, // may have more layers
null
,
// sky_invert, // final boolean [] selected, // to remove sky (pre-filter by caller, like for ML?)
tex_disp_adiffo
,
// final double disp_adiffo,
tex_disp_rdiffo
,
// final double disp_rdiffo,
tex_disp_adiffd
,
// final double disp_adiffd,
tex_disp_rdiffd
,
// final double disp_rdiffd,
tex_disp_fof
,
// final double disp_fof, // enable higher difference (scale) for fried of a friend
tilesX
,
// final int tilesX,
ds_fg_bg
,
// final double [][] disparities, // may have more layers
sky_tiles
,
// final boolean blue_sky, // use to expand background by blurring available data?
sky_layer
,
// final int sky_layer,
sky_below
,
// final int blue_sky_below,
null
,
// sky_invert, // final boolean [] selected, // to remove sky (pre-filter by caller, like for ML?)
tex_disp_adiffo
,
// final double disp_adiffo,
tex_disp_rdiffo
,
// final double disp_rdiffo,
tex_disp_adiffd
,
// final double disp_adiffd,
tex_disp_rdiffd
,
// final double disp_rdiffd,
tex_disp_fof
,
// final double disp_fof, // enable higher difference (scale) for friend of a friend
tex_cluster_gap
,
// final int cluster_gap, // gap between clusters
debugLevel
);
//1); // 2); // final int debugLevel)
// double [][] inter_weights = new double [tilesY][tilesX]; // per-tile texture weights for inter-scene accumulation;
// double [][][][] inter_textures= new double [tilesY][tilesX][][]; // [channel][256] - non-overlapping textures
boolean
[]
scenes_sel
=
new
boolean
[
scenes
.
length
];
// for (int i = scenes.length - 10; i < scenes.length; i++) { // start with just one (reference) scene
for
(
int
i
=
0
;
i
<
scenes
.
length
;
i
++)
{
// start with just one (reference) scene
scenes_sel
[
i
]
=
true
;
}
boolean
renormalize
=
true
;
// false - use normalizations from previous scenes to keep consistent colors
// If there is gap between clusters, add extra row of background tiles
int
add_bg_tiles
=
1
;
ImagePlus
[]
combined_textures
=
getInterCombinedTexturesNew
(
// return ImagePlus[] matching tileClusters[], with alpha
clt_parameters
,
// final CLTParameters clt_parameters,
colorProcParameters
,
// ColorProcParameters colorProcParameters,
rgbParameters
,
// EyesisCorrectionParameters.RGBParameters rgbParameters,
parameter_scene
,
// final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences
// if null - use reference scene
scenes
,
// final QuadCLT [] scenes,
scenes_sel
,
// final boolean [] scenes_sel, // null or which scenes to process
null
,
// final boolean [] selection, // may be null, if not null do not process unselected tiles
tileClusters
,
// final TileCluster [] tileClusters, // disparities, borders, selections for texture passes
// final int margin,
renormalize
,
// final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors
debugLevel
);
// final int debug_level)
/*
if (debugLevel > -1000) {
return false;
while
((
add_bg_tiles
--)
>
0
)
{
extendClustersBackground
(
tileClusters
,
// final TileCluster[] tileClusters,
max_disparity_lim
,
// final double max_disparity_lim,
min_trim_disparity
,
// final double min_trim_disparity,
transform_size
,
// final int transform_size,
tilesX
);
// final int tilesX)
}
boolean
renormalize
=
true
;
// false - use normalizations from previous scenes to keep consistent colors
ImagePlus
[]
combined_textures
=
getInterCombinedTextures
(
// return ImagePlus[] matching tileClusters[], with alpha
clt_parameters
,
// final CLTParameters clt_parameters,
colorProcParameters
,
// ColorProcParameters colorProcParameters,
...
...
@@ -659,8 +677,9 @@ public class TexturedModel {
tileClusters
,
// final TileCluster [] tileClusters, // disparities, borders, selections for texture passes
// final int margin,
renormalize
,
// final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors
max_disparity_lim
,
// final double max_disparity_lim, // 100.0; // do not allow stray disparities above this
min_trim_disparity
,
//final double min_trim_disparity, // 2.0; // do not try to trim texture outlines with lower disparities
debugLevel
);
// final int debug_level)
*/
boolean
save_full_textures
=
true
;
// false; // true;
EyesisCorrectionParameters
.
CorrectionParameters
correctionsParameters
=
ref_scene
.
correctionsParameters
;
String
x3d_dir
=
ref_scene
.
getX3dDirectory
();
...
...
@@ -675,11 +694,6 @@ public class TexturedModel {
1
);
//
}
}
// ********************* just for testing ************************************
// if (debugLevel > -1000) {
// return false;
// }
// Maybe will switch to combined textures (less files)
ImagePlus
[]
imp_textures
=
splitCombinedTextures
(
...
...
@@ -696,10 +710,6 @@ public class TexturedModel {
1
);
//
}
// if (debugLevel > -100) {
// return true;
// }
// create x3d file
if
(
clt_parameters
.
output_x3d
)
{
x3dOutput
=
new
X3dOutput
(
...
...
@@ -735,14 +745,29 @@ public class TexturedModel {
// 09.18.2022 - skipping background generation
int
num_clusters
=
-
1
;
for
(
int
ns
cene
=
0
;
nscene
<
tileClusters
.
length
;
nscen
e
++)
{
for
(
int
indx:
tileClusters
[
ns
cen
e
].
getSubIndices
())
{
for
(
int
ns
lice
=
0
;
nslice
<
tileClusters
.
length
;
nslic
e
++)
{
for
(
int
indx:
tileClusters
[
ns
lic
e
].
getSubIndices
())
{
if
(
indx
>
num_clusters
)
num_clusters
=
indx
;
}
}
num_clusters
++;
num_clusters
++;
// was cluster with largest index, became number of clusters
final
double
[][]
dbg_tri_disp
=
debug_disp_tri
?
(
new
double
[
tileClusters
.
length
][
width
*
height
]):
null
;
final
double
[][]
dbg_tri_tri
=
debug_disp_tri
?
(
new
double
[
tileClusters
.
length
][
width
*
height
]):
null
;
for
(
int
nslice
=
0
;
nslice
<
tileClusters
.
length
;
nslice
++){
if
(
dbg_tri_disp
!=
null
)
{
Arrays
.
fill
(
dbg_tri_disp
[
nslice
],
Double
.
NaN
);
}
// keep them all 0, not NaN
// if (dbg_tri_tri != null) {
// Arrays.fill(dbg_tri_tri[nslice], Double.NaN);
// }
final
double
[][]
dbg_disp_tri_slice
=
(
dbg_tri_tri
!=
null
)
?
((
dbg_tri_disp
!=
null
)?
(
new
double
[][]
{
dbg_tri_disp
[
nslice
],
dbg_tri_tri
[
nslice
]}):
(
new
double
[][]
{
dbg_tri_tri
[
nslice
]})
):
null
;
if
(
debugLevel
>
-
1
){
// System.out.println("Generating cluster images (limit is set to "+clt_parameters.max_clusters+") largest, scan #"+scanIndex);
System
.
out
.
println
(
"Generating cluster images from texture slice "
+
nslice
);
...
...
@@ -765,7 +790,6 @@ public class TexturedModel {
boolean
[]
scan_selected
=
tileClusters
[
nslice
].
getSubSelected
(
sub_i
);
// skipping averaging disparity fro a whole cluster (needs strength and does not seem to be useful)
boolean
showTri
=
!
batch_mode
&&
(
debugLevel
>
-
1
)
&&
(
clt_parameters
.
show_triangles
)
&&
(
cluster_index
==
dbg_tri_indx
);
try
{
ref_scene
.
generateClusterX3d
(
// also generates wavefront obj
x3dOutput
,
...
...
@@ -787,7 +811,9 @@ public class TexturedModel {
clt_parameters
.
maxZtoXY
,
// double maxZtoXY, // 10.0. <=0 - do not use
clt_parameters
.
maxZ
,
clt_parameters
.
limitZ
,
dbg_disp_tri_slice
,
// double [][] dbg_disp_tri_slice,
debugLevel
+
1
);
// int debug_level) > 0
//dbg_disp_tri_slice
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
false
;
...
...
@@ -795,10 +821,44 @@ public class TexturedModel {
}
// if (imp_textures[nslice] != null)
}
// for (int nslice = 0; nslice < tileClusters.length; nslice++){
if
(
dbg_tri_disp
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_tri_disp
,
width
,
height
,
true
,
ref_scene
.
getImageName
()+
"-mesh_disparities"
);
}
if
(
dbg_tri_tri
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_tri_tri
,
width
,
height
,
true
,
ref_scene
.
getImageName
()+
"-mesh_triangles"
);
}
if
((
dbg_tri_disp
!=
null
)
&&
(
dbg_tri_tri
!=
null
))
{
double
[][]
dbg_tri
=
new
double
[
2
*
dbg_tri_tri
.
length
][];
String
[]
dbg_titles
=
new
String
[
dbg_tri
.
length
];
for
(
int
i
=
0
;
i
<
dbg_tri_tri
.
length
;
i
++)
{
dbg_titles
[
2
*
i
+
0
]
=
"disparity-"
+
String
.
format
(
"%02d"
,
i
);
dbg_titles
[
2
*
i
+
1
]
=
"triangles-"
+
String
.
format
(
"%02d"
,
i
);
dbg_tri
[
2
*
i
+
0
]
=
dbg_tri_disp
[
i
];
dbg_tri
[
2
*
i
+
1
]
=
dbg_tri_tri
[
i
];
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_tri
,
width
,
height
,
true
,
ref_scene
.
getImageName
()+
"-mesh_disparity_triangles"
,
dbg_titles
);
}
if
((
x3d_dir
!=
null
)
&&
(
x3dOutput
!=
null
)){
x3dOutput
.
generateX3D
(
x3d_dir
+
Prefs
.
getFileSeparator
()
+
ref_scene
.
correctionsParameters
.
getModelName
(
ref_scene
.
getImageName
())+
".x3d"
);
}
if
(
wfOutput
!=
null
){
wfOutput
.
close
();
System
.
out
.
println
(
"Wavefront object file saved to "
+
wfOutput
.
obj_path
);
...
...
@@ -835,237 +895,153 @@ public class TexturedModel {
return
true
;
}
// get multi-scene textures (GPU-only)
public
static
ImagePlus
[]
getInterCombinedTextures
(
// return ImagePlus[] matching tileClusters[], with alpha
final
CLTParameters
clt_parameters
,
ColorProcParameters
colorProcParameters
,
EyesisCorrectionParameters
.
RGBParameters
rgbParameters
,
QuadCLT
parameter_scene
,
// to use for rendering parameters in multi-series sequences
// if null - use reference scene
final
QuadCLT
[]
scenes
,
final
boolean
[]
scenes_sel
,
// null or which scenes to process
final
boolean
[]
selection
,
// may be null, if not null do not process unselected tiles
final
TileCluster
[]
tileClusters
,
// disparities, borders, selections for texture passes
final
boolean
renormalize
,
// false - use normalizations from previous scenes to keep consistent colors
final
int
debug_level
)
{
// TODO: ***** scenes with high motion blur also have high ERS to be corrected ! *****
final
int
ref_index
=
scenes
.
length
-
1
;
final
QuadCLT
ref_scene
=
scenes
[
ref_index
];
if
(
parameter_scene
==
null
)
{
parameter_scene
=
ref_scene
;
public
static
double
[][]
getComboTexture
(
final
double
[][][]
sensor_texture
)
{
final
int
num_slices
=
sensor_texture
.
length
;
final
int
num_sensors
=
sensor_texture
[
0
].
length
;
final
int
img_size
=
sensor_texture
[
0
][
0
].
length
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
double
[][]
combo_texture
=
new
double
[
num_slices
][
img_size
];
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
Arrays
.
fill
(
combo_texture
[
fnslice
],
Double
.
NaN
);
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
indx
=
ai
.
getAndIncrement
();
indx
<
img_size
;
indx
=
ai
.
getAndIncrement
())
if
(!
Double
.
isNaN
(
sensor_texture
[
fnslice
][
0
][
indx
]))
{
double
d
=
0
;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
d
+=
sensor_texture
[
fnslice
][
nsens
][
indx
];
}
combo_texture
[
fnslice
][
indx
]
=
d
/
num_sensors
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
return
combo_texture
;
}
public
static
double
getMaxDisparity
(
double
[][]
slice_disparities
,
double
max_disparity_lim
)
{
final
int
num_slices
=
slice_disparities
.
length
;
final
int
tiles
=
slice_disparities
[
0
].
length
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
th_max_disp
=
new
double
[
threads
.
length
];
final
int
tile_slices
=
tiles
*
num_slices
;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
ti
=
ati
.
getAndIncrement
();
for
(
int
indx
=
ai
.
getAndIncrement
();
indx
<
tile_slices
;
indx
=
ai
.
getAndIncrement
())
{
int
nslice
=
indx
/
tiles
;
int
tile
=
indx
%
tiles
;
if
(!
Double
.
isNaN
(
slice_disparities
[
nslice
][
tile
]))
{
if
((
slice_disparities
[
nslice
][
tile
]
>
th_max_disp
[
ti
])
&&
(
slice_disparities
[
nslice
][
tile
]
<
max_disparity_lim
)){
th_max_disp
[
ti
]
=
slice_disparities
[
nslice
][
tile
];
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
disparity_max
=
0.0
;
for
(
int
i
=
0
;
i
<
th_max_disp
.
length
;
i
++)
{
disparity_max
=
Math
.
max
(
disparity_max
,
th_max_disp
[
i
]);
}
return
disparity_max
;
}
/**
* Extend background edges of clusters - those that have FG tiles in front of them
* There should be gaps between clusters to expand
*/
public
static
void
extendClustersBackground
(
final
TileCluster
[]
tileClusters
,
final
double
max_disparity_lim
,
final
double
min_trim_disparity
,
final
int
transform_size
,
final
int
tilesX
){
final
double
weight_diag
=
0.7
;
final
int
num_slices
=
tileClusters
.
length
;
final
double
[][]
slice_disparities
=
new
double
[
num_slices
][];
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
slice_disparities
[
nslice
]
=
tileClusters
[
nslice
].
getDisparity
();
// disparity in the reference view tiles (Double.NaN - invalid)
}
final
int
earliestScene
=
ref_scene
.
getEarliestScene
(
scenes
);
final
ErsCorrection
ers_reference
=
ref_scene
.
getErsCorrection
();
final
int
tilesX
=
ref_scene
.
getTileProcessor
().
getTilesX
();
final
int
tilesY
=
ref_scene
.
getTileProcessor
().
getTilesY
();
final
int
tiles
=
tilesX
*
tilesY
;
final
int
transform_size
=
ref_scene
.
getTileProcessor
().
getTileSize
();
final
int
num_channels
=
ref_scene
.
isMonochrome
()?
2
:
4
;
//
final
boolean
filter_bg
=
true
;
// make a clt parameter?
final
boolean
mb_en
=
clt_parameters
.
imp
.
mb_en
;
final
double
mb_tau
=
clt_parameters
.
imp
.
mb_tau
;
// 0.008;// time constant, sec
final
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
final
double
max_distortion
=
clt_parameters
.
tex_distort
;
// 0.5; // Maximal texture distortion to accumulate multiple scenes (0 - any)
final
double
tex_mb
=
clt_parameters
.
tex_mb
;
// 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length)
final
boolean
sharp_alpha
=
clt_parameters
.
sharp_alpha
;
final
boolean
is_lwir
=
ref_scene
.
isLwir
();
final
boolean
tex_um
=
clt_parameters
.
tex_um
;
// imp.um_mono; // TODO: add own parameter
final
double
tex_um_sigma
=
clt_parameters
.
tex_um_sigma
;
// imp.um_sigma;
final
double
tex_um_weight
=
clt_parameters
.
tex_um_weight
;
// imp.um_weight;
// TODO: - make texture variants, tex_um_fixed/tex_um_range apply only to unsharp mask, regardless of colors
final
boolean
lwir_autorange
=
is_lwir
&&
clt_parameters
.
tex_lwir_autorange
;
// colorProcParameters.lwir_autorange;
final
boolean
tex_um_fixed
=
clt_parameters
.
tex_um_fixed
;
// imp.mono_fixed; // true; // normalize to fixed range when converting to 8 bits
final
double
tex_um_range
=
clt_parameters
.
tex_um_range
;
// imp.mono_range; // 500.0; // monochrome full-scale range (+/- half)
final
boolean
tex_hist_norm
=
clt_parameters
.
tex_hist_norm
;
// true;
final
double
tex_hist_amount
=
clt_parameters
.
tex_hist_amount
;
// clt_parameters. 0.7;
final
int
tex_hist_bins
=
clt_parameters
.
tex_hist_bins
;
// 1024 ;
final
int
tex_hist_segments
=
clt_parameters
.
tex_hist_segments
;
// 32 ;
final
boolean
tex_color
=
clt_parameters
.
tex_color
;
// true;
final
int
tex_palette
=
clt_parameters
.
tex_palette
;
// 2 ;
final
int
tiles
=
slice_disparities
[
0
].
length
;
final
int
tilesY
=
tiles
/
tilesX
;
final
boolean
[][][]
fg_has_bg
=
get_fg_has_bg_any
(
// {is_fg, has_bg, has_tile}
slice_disparities
,
// final double [][] slice_disparities,
slice_disparities
,
// final double [][] slice_disparities_real, // not extended
max_disparity_lim
,
// final double max_disparity_lim,
min_trim_disparity
,
// final double min_trim_disparity,
transform_size
,
// final int transform_size,
tilesX
);
// final int tilesX)
showDebugDisparities
(
// nop if dbg_prefix== null
slice_disparities
,
// final double [][] slice_disparities,
tilesX
,
// final int tilesX,
"before-extending-disparities"
);
// String prefix);
ImageDtt
image_dtt
;
image_dtt
=
new
ImageDtt
(
ref_scene
.
getNumSensors
(),
// numSens,
transform_size
,
clt_parameters
.
img_dtt
,
ref_scene
.
isAux
(),
ref_scene
.
isMonochrome
(),
ref_scene
.
isLwir
(),
clt_parameters
.
getScaleStrength
(
ref_scene
.
isAux
()),
ref_scene
.
getGPU
());
if
(
ref_scene
.
getGPU
()
!=
null
)
{
ref_scene
.
getGPU
().
setGpu_debug_level
(
debug_level
);
}
image_dtt
.
getCorrelation2d
();
// initiate image_dtt.correlation2d, needed if disparity_map != null
final
int
num_slices
=
tileClusters
.
length
;
double
[][][]
inter_weights
=
new
double
[
num_slices
][
tilesY
][
tilesX
];
// per-tile texture weights for inter-scene accumulation;
double
[][][][][]
inter_textures
=
new
double
[
num_slices
][
tilesY
][
tilesX
][][];
// [channel][256] - non-overlapping textures
/// double [][] scene_pXpYD;
/// final double disparity_corr = 0.00; // (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
/// TpTask[] tp_tasks_ref = null;
double
[][][]
ref_pXpYDs
=
new
double
[
num_slices
][][];
// individual for each slice
int
[][]
cluster_indices
=
(
max_distortion
>
0.0
)
?
(
new
int
[
num_slices
][]):
null
;
boolean
[][]
borders
=
new
boolean
[
num_slices
][];
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
// prepare and measure textures for each combo textures
ref_pXpYDs
[
nslice
]
=
OpticalFlow
.
transformToScenePxPyD
(
// now should work with offset ref_scene
null
,
// fov_tiles, // final Rectangle [] extra_woi, // show larger than sensor WOI (or null)
tileClusters
[
nslice
].
getDisparity
(),
// final double [] disparity_ref, // invalid tiles - NaN in disparity
OpticalFlow
.
ZERO3
,
// final double [] scene_xyz, // camera center in world coordinates
OpticalFlow
.
ZERO3
,
// final double [] scene_atr, // camera orientation relative to world frame
scenes
[
ref_index
],
// final QuadCLT scene_QuadClt,
scenes
[
ref_index
],
// final QuadCLT reference_QuadClt, // now - may be null - for testing if scene is rotated ref
THREADS_MAX
);
// int threadsMax)
borders
[
nslice
]
=
tileClusters
[
nslice
].
getBorder
();
if
(
max_distortion
>
0.0
)
{
cluster_indices
[
nslice
]
=
tileClusters
[
nslice
].
getClusterIndex
();
}
}
showDebugFgBg
(
// nop if dbg_prefix== null
fg_has_bg
,
// boolean [][][] fg_has_bg,
tilesX
,
// final int tilesX,
"before-extending-fgbg"
);
// String prefix);
for
(
int
nscene
=
earliestScene
;
nscene
<
scenes
.
length
;
nscene
++)
if
((
scenes_sel
==
null
)
||
scenes_sel
[
nscene
]){
String
ts
=
scenes
[
nscene
].
getImageName
();
double
[]
scene_xyz
=
OpticalFlow
.
ZERO3
;
double
[]
scene_atr
=
OpticalFlow
.
ZERO3
;
if
(
nscene
!=
ref_index
)
{
scene_xyz
=
ers_reference
.
getSceneXYZ
(
ts
);
scene_atr
=
ers_reference
.
getSceneATR
(
ts
);
if
((
scene_xyz
==
null
)
||
(
scene_atr
==
null
)){
continue
;
// scene is not matched
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
// find all border tiles that are not FG
final
boolean
[][]
seed_tiles
=
new
boolean
[
num_slices
][];
final
TileNeibs
tn
=
new
TileNeibs
(
tilesX
,
tilesY
);
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nslice
=
ai
.
getAndIncrement
();
nslice
<
num_slices
;
nslice
=
ai
.
getAndIncrement
())
{
seed_tiles
[
nslice
]
=
tn
.
getEdgeSelection
(
2
,
// int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
fg_has_bg
[
2
][
nslice
],
// boolean [] tiles,
null
);
// boolean [] prohibit);
for
(
int
i
=
0
;
i
<
seed_tiles
[
nslice
].
length
;
i
++)
{
seed_tiles
[
nslice
][
i
]
&=
!
fg_has_bg
[
0
][
nslice
][
i
];
// keep only those that are not FG
}
}
}
double
[]
scene_ers_xyz_dt
=
ers_reference
.
getSceneErsXYZ_dt
(
ts
);
double
[]
scene_ers_atr_dt
=
ers_reference
.
getSceneErsATR_dt
(
ts
);
scenes
[
nscene
].
getErsCorrection
().
setErsDt
(
scene_ers_xyz_dt
,
// double [] ers_xyz_dt,
scene_ers_atr_dt
);
// double [] ers_atr_dt)(ers_scene_original_xyz_dt);
}
double
[][]
dxyzatr_dt
=
null
;
// should get velocities from HashMap at reference scene from timestamp , not re-calculate.
if
(
mb_en
)
{
// all scenes have the same name/path
// dxyzatr_dt = OpticalFlow.getVelocities( // looks at previous/next scene poses
// scenes, // QuadCLT [] quadCLTs,
// nscene); // int nscene)
dxyzatr_dt
=
new
double
[][]
{
// for all, including ref
scenes
[
nscene
].
getErsCorrection
().
getErsXYZ_dt
(),
scenes
[
nscene
].
getErsCorrection
().
getErsATR_dt
()};
}
scenes
[
nscene
].
saveQuadClt
();
// to re-load new set of Bayer images to the GPU (do nothing for CPU)
boolean
keep_channels
=
false
;
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
// prepare and measure textures for each combo textures
final
double
[]
disparity_ref
=
tileClusters
[
nslice
].
getDisparity
();
// disparity in the reference view tiles (Double.NaN - invalid)
// Motion blur vectors are individual per-slice
// Calculate motion blur vectors - may be used to modify weights of averaged textures
final
double
[][]
motion_blur
=
(
mb_en
&&
(
dxyzatr_dt
!=
null
))?
OpticalFlow
.
getMotionBlur
(
scenes
[
ref_index
],
// QuadCLT ref_scene,
scenes
[
nscene
],
// QuadCLT scene, // can be the same as ref_scene
ref_pXpYDs
[
nslice
],
// double [][] ref_pXpYD, // here it is scene, not reference!
scene_xyz
,
// double [] camera_xyz,
scene_atr
,
// double [] camera_atr,
dxyzatr_dt
[
0
],
// double [] camera_xyz_dt,
dxyzatr_dt
[
1
],
// double [] camera_atr_dt,
0
,
// int shrink_gaps, // will gaps, but not more that grow by this
debug_level
)
:
null
;
// int debug_level)
if
(
debug_level
>
0
)
{
System
.
out
.
println
(
"nscene="
+
nscene
+
", nslice="
+
nslice
+
" will run texturesGPUFromDSI() that needs debug >2"
);
System
.
out
.
print
(
""
);
}
double
[][][][]
slice_texture
=
QuadCLT
.
texturesGPUFromDSI
(
clt_parameters
,
// CLTParameters clt_parameters,
disparity_ref
,
// double [] disparity_ref,
// motion blur compensation
mb_tau
,
// double mb_tau, // 0.008; // time constant, sec
mb_max_gain
,
// double mb_max_gain, // 5.0; // motion blur maximal gain (if more - move second point more than a pixel
motion_blur
,
// double [][] mb_vectors, // now [2][ntiles];
scene_xyz
,
// final double [] scene_xyz, // camera center in world coordinates
scene_atr
,
// final double [] scene_atr, // camera orientation relative to world frame
scenes
[
nscene
],
// final QuadCLT scene,
scenes
[
ref_index
],
// final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
filter_bg
&&
(
nscene
!=
ref_index
),
// final boolean filter_bg, // remove bg tiles (possibly occluded)
max_distortion
,
// final double max_distortion, // maximal neighbor tiles offset as a fraction of tile size (8)
cluster_indices
[
nslice
],
// final int [] cluster_index, //
borders
[
nslice
],
// final boolean [] border, // border tiles
keep_channels
,
// final boolean keep_channels,
debug_level
);
// final int debugLevel);
if
(
slice_texture
!=
null
)
{
// Use MB vectors for texture weights
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
int
fnslice
=
nslice
;
final
double
mb_tau2
=
mb_tau
*
mb_tau
/
tex_mb
/
tex_mb
;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
tiles
;
nTile
=
ai
.
getAndIncrement
())
{
int
tileX
=
nTile
%
tilesX
;
int
tileY
=
nTile
/
tilesX
;
if
(
slice_texture
[
tileY
][
tileX
]
!=
null
)
{
double
w
=
1.0
;
if
(
tex_mb
>
0.0
)
{
double
mb_l2
=
mb_tau2
*
(
motion_blur
[
0
][
nTile
]*
motion_blur
[
0
][
nTile
]
+
// motion_blur == null;
motion_blur
[
1
][
nTile
]*
motion_blur
[
1
][
nTile
]);
if
(
mb_l2
>
1.0
)
{
w
/=
mb_l2
;
// 1/(squared mb)
}
}
if
(
w
>
0
)
{
inter_weights
[
fnslice
][
tileY
][
tileX
]
+=
w
;
if
(
inter_textures
[
fnslice
][
tileY
][
tileX
]
==
null
)
{
// create if it did not exist
inter_textures
[
fnslice
][
tileY
][
tileX
]
=
new
double
[
slice_texture
[
tileY
][
tileX
].
length
][
slice_texture
[
tileY
][
tileX
][
0
].
length
];
}
for
(
int
nchn
=
0
;
nchn
<
inter_textures
[
fnslice
][
tileY
][
tileX
].
length
;
nchn
++)
{
for
(
int
i
=
0
;
i
<
inter_textures
[
fnslice
][
tileY
][
tileX
][
nchn
].
length
;
i
++)
{
inter_textures
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
+=
w
*
slice_texture
[
tileY
][
tileX
][
nchn
][
i
];
}
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
if
(
debug_level
>
-
1
)
{
if
(
nscene
==
ref_index
)
{
System
.
out
.
println
(
"Textures from the reference scene, nslice = "
+
nslice
+((
slice_texture
==
null
)?
" - EMPTY"
:
""
));
}
else
{
System
.
out
.
println
(
"Textures from scene "
+
nscene
+
", slice="
+
nslice
+((
slice_texture
==
null
)?
" - EMPTY"
:
""
));
}
}
}
// for (int nslice = 0; nslice < num_slices; nslice++) {
}
// for (int nscene = 0; nscene < num_scenes; nscene++) {
// Divide accumulated data by weights
double
[][][]
faded_textures
=
new
double
[
num_slices
][][];
final
double
[][]
dbg_weights
=
(
debug_level
>
0
)?(
new
double
[
num_slices
][
tiles
])
:
null
;
final
double
[][]
dbg_overlap
=
(
debug_level
>
0
)?(
new
double
[
num_slices
*
num_channels
][])
:
null
;
};
}
ImageDtt
.
startAndJoin
(
threads
);
showDebugBoolean
(
seed_tiles
,
// boolean [][] selected,
tilesX
,
// final int tilesX,
"seed_tiles"
);
// String prefix)
final
double
[][]
extended_slice_disparities
=
new
double
[
num_slices
][];
final
boolean
[][]
new_tiles
=
new
boolean
[
num_slices
][
tiles
];
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
if
(
dbg_weights
!=
null
)
{
Arrays
.
fill
(
dbg_weights
[
nslice
],
Double
.
NaN
);
}
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
tiles
;
nTile
=
ai
.
getAndIncrement
())
{
int
tileX
=
nTile
%
tilesX
;
int
tileY
=
nTile
/
tilesX
;
if
(
inter_weights
[
fnslice
][
tileY
][
tileX
]
>
0.0
)
{
if
(
dbg_weights
!=
null
)
{
dbg_weights
[
fnslice
][
nTile
]
=
inter_weights
[
fnslice
][
tileY
][
tileX
];
}
double
w
=
1.0
/
inter_weights
[
fnslice
][
tileY
][
tileX
];
for
(
int
nchn
=
0
;
nchn
<
inter_textures
[
fnslice
][
tileY
][
tileX
].
length
;
nchn
++)
{
for
(
int
i
=
0
;
i
<
inter_textures
[
fnslice
][
tileY
][
tileX
][
nchn
].
length
;
i
++)
{
inter_textures
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
*=
w
;
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
seed_tiles
[
fnslice
][
tile
])
{
for
(
int
dir
=
0
;
dir
<
8
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
if
(
tile1
>=
0
)
{
if
(
Double
.
isNaN
(
slice_disparities
[
fnslice
][
tile1
]))
{
new_tiles
[
fnslice
][
tile1
]
=
true
;
// may be concurrent, but that's OK
}
}
}
...
...
@@ -1074,298 +1050,120 @@ public class TexturedModel {
};
}
ImageDtt
.
startAndJoin
(
threads
);
// Process slice of textures: apply borders, convert to color or apply UM, add synthetic mesh, ...
// 2 layers for mono, 4 layers - for color
// First - merge overlapped and apply borders, alpha is the last slice
faded_textures
[
nslice
]
=
getFadedTextures
(
// get image from a single pass, return relative path for x3d // USED in lwir
clt_parameters
,
// CLTParameters clt_parameters,
inter_textures
[
fnslice
],
// final double [][][][] texture_tiles, // array [tilesY][tilesX][4][4*transform_size] or [tilesY][tilesX]{null}
tileClusters
[
fnslice
],
// final TileCluster tileCluster, // disparities, borders, selections for texture passes
sharp_alpha
,
// final boolean sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
transform_size
,
// final int transform_size, //
num_channels
,
// final int num_channels, // 4 for RGBA, 2 for Y (should match textures)
debug_level
);
// final int debugLevel)
if
(
dbg_overlap
!=
null
)
{
double
[][]
non_overlap
=
combineYRBGATiles
(
inter_textures
[
fnslice
],
// final double [][][][] texture_tiles, // array [tilesY][tilesX][4][4*transform_size] or [tilesY][tilesX]{null}
false
,
// final boolean overlap, // when false - output each tile as 16x16, true - overlap to make 8x8
sharp_alpha
,
// final boolean sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
transform_size
,
// final int transform_size, //
num_channels
,
//final int num_channels, // 4 for RGBA, 2 for Y (should match textures)
debug_level
);
// final int debugLevel)
for
(
int
i
=
0
;
i
<
num_channels
;
i
++)
{
dbg_overlap
[
fnslice
*
num_channels
+
i
]
=
non_overlap
[
i
];
}
}
}
if
(
debug_level
>
-
1
)
{
double
[][]
dbg_textures
=
new
double
[
faded_textures
.
length
*
faded_textures
[
0
].
length
][
faded_textures
[
0
][
0
].
length
];
String
[]
dbg_titles
=
new
String
[
dbg_textures
.
length
];
String
[]
dbg_subtitles
=
new
String
[
faded_textures
[
0
].
length
];
for
(
int
i
=
0
;
i
<
dbg_subtitles
.
length
;
i
++)
{
dbg_subtitles
[
i
]
=
(
i
<
(
dbg_subtitles
.
length
-
1
))
?
(
"Y"
+
i
):
"alpha"
;
}
for
(
int
i
=
0
;
i
<
dbg_textures
.
length
;
i
++)
{
dbg_textures
[
i
]
=
faded_textures
[
i
/
faded_textures
[
0
].
length
][
i
%
faded_textures
[
0
].
length
];
dbg_titles
[
i
]
=
dbg_subtitles
[
i
%
dbg_subtitles
.
length
]
+
"-"
+
(
i
/
dbg_subtitles
.
length
);
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures
,
tilesX
*
transform_size
,
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-combined_textures-prenorm-pre_UM"
,
dbg_titles
);
}
// Optionally apply UM (before auto/manual range)
if
(
tex_um
)
{
QuadCLTCPU
.
umTextures
(
faded_textures
,
// final double [][][] textures, // [nslices][nchn][i]
tilesX
*
transform_size
,
// final int width,
tex_um_sigma
,
// final double um_sigma,
tex_um_weight
);
// final double um_weight)
}
if
(
debug_level
>
-
1
)
{
double
[][]
dbg_textures
=
new
double
[
faded_textures
.
length
*
faded_textures
[
0
].
length
][
faded_textures
[
0
][
0
].
length
];
String
[]
dbg_titles
=
new
String
[
dbg_textures
.
length
];
String
[]
dbg_subtitles
=
new
String
[
faded_textures
[
0
].
length
];
for
(
int
i
=
0
;
i
<
dbg_subtitles
.
length
;
i
++)
{
dbg_subtitles
[
i
]
=
(
i
<
(
dbg_subtitles
.
length
-
1
))
?
(
"Y"
+
i
):
"alpha"
;
}
for
(
int
i
=
0
;
i
<
dbg_textures
.
length
;
i
++)
{
dbg_textures
[
i
]
=
faded_textures
[
i
/
faded_textures
[
0
].
length
][
i
%
faded_textures
[
0
].
length
];
dbg_titles
[
i
]
=
dbg_subtitles
[
i
%
dbg_subtitles
.
length
]
+
"-"
+
(
i
/
dbg_subtitles
.
length
);
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures
,
tilesX
*
transform_size
,
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-combined_textures-prenorm"
,
dbg_titles
);
if
(
dbg_overlap
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_overlap
,
2
*
tilesX
*
transform_size
,
2
*
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-non-overlap_textures-prenorm"
,
dbg_titles
);
}
if
(
dbg_weights
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_weights
,
tilesX
,
tilesY
,
true
,
ref_scene
.
getImageName
()+
"-texture_weights-prenorm"
);
}
}
//renormalize
// normalize all slices together if LWIR
// FIXME: Should it be here? Will setColdHot() change photometric calibration ? Or should it be disabled?
double
[]
norm_table
=
null
;
// first try, then make save to properties with cold/hot
if
(
renormalize
)
{
if
(
lwir_autorange
)
{
double
rel_low
;
double
rel_high
;
boolean
force_min_max
=
true
;
if
(!
tex_um
&&
!
force_min_max
)
{
// for UM will use min/max
rel_low
=
colorProcParameters
.
lwir_low
;
rel_high
=
colorProcParameters
.
lwir_high
;
if
(!
Double
.
isNaN
(
parameter_scene
.
getLwirOffset
()))
{
// ref_scene or parameter_scene? Or both?
rel_low
-=
parameter_scene
.
getLwirOffset
();
rel_high
-=
parameter_scene
.
getLwirOffset
();
}
}
else
{
// for UM need to calculate min and max (probably OK for non-UM too !)
double
[]
minmax
=
QuadCLTCPU
.
getMinMaxTextures
(
faded_textures
);
//double [][][] textures // [slices][nchn][i]
rel_low
=
minmax
[
0
];
// absolute min
rel_high
=
minmax
[
1
];
// absolute max
}
double
[]
cold_hot
=
QuadCLTCPU
.
autorangeTextures
(
faded_textures
,
// double [][][] textures, // [nslices][nchn][i]
rel_low
,
// double hard_cold,// matches data, DC (this.lwir_offset) subtracted
rel_high
,
// double hard_hot, // matches data, DC (this.lwir_offset) subtracted
colorProcParameters
.
lwir_too_cold
,
// double too_cold, // pixels per image
colorProcParameters
.
lwir_too_hot
,
// double too_hot, // pixels per image
tex_hist_bins
);
// int num_bins)
if
((
cold_hot
!=
null
)
&&
!
tex_um
&&
!
force_min_max
)
{
if
(!
Double
.
isNaN
(
parameter_scene
.
getLwirOffset
()))
{
cold_hot
[
0
]
+=
parameter_scene
.
getLwirOffset
();
cold_hot
[
1
]
+=
parameter_scene
.
getLwirOffset
();
}
}
parameter_scene
.
setColdHot
(
cold_hot
);
// will be used for shifted images and for texture tiles
}
else
if
(
tex_um
&&
tex_um_fixed
)
{
// apply fixed range, but for UM only (what about RGB?)
parameter_scene
.
setColdHot
(-
0.5
*
tex_um_range
,
0.5
*
tex_um_range
);
}
if
(
tex_hist_norm
)
{
// will normalize (0..1) keeping cold_hot to apply during rendering
// last norm_table element is <=1.0, first >=0;
norm_table
=
QuadCLTCPU
.
getHistogramNormalization
(
faded_textures
,
// double [][][] textures, // [nslices][nchn][i]
parameter_scene
.
getColdHot
(),
// double [] minmax,
tex_hist_bins
,
// int num_bins,
tex_hist_segments
,
//int num_nodes
tex_hist_amount
);
//double hist_normalize_amount // 1.0 - full
}
}
if
(
tex_hist_norm
&&
(
norm_table
!=
null
))
{
// apply histogram normalization
double
[]
cold_hot
=
parameter_scene
.
getColdHot
();
// used in linearStackToColor
double
[]
inverted_table
=
QuadCLTCPU
.
invertHistogramNormalization
(
norm_table
,
// double [] direct_table, // last is <1.0, first > 0
tex_hist_bins
);
// int num_bins)
QuadCLTCPU
.
applyTexturesNormHist
(
faded_textures
,
// final double [][][] textures, // [nslices][nchn][i]
cold_hot
,
// final double [] min_max,
inverted_table
);
// final double [] inv_table)
}
if
(
debug_level
>
-
1
)
{
double
[][]
dbg_textures
=
new
double
[
faded_textures
.
length
*
faded_textures
[
0
].
length
][
faded_textures
[
0
][
0
].
length
];
String
[]
dbg_titles
=
new
String
[
dbg_textures
.
length
];
String
[]
dbg_subtitles
=
new
String
[
faded_textures
[
0
].
length
];
for
(
int
i
=
0
;
i
<
dbg_subtitles
.
length
;
i
++)
{
dbg_subtitles
[
i
]
=
(
i
<
(
dbg_subtitles
.
length
-
1
))
?
(
"Y"
+
i
):
"alpha"
;
}
for
(
int
i
=
0
;
i
<
dbg_textures
.
length
;
i
++)
{
dbg_textures
[
i
]
=
faded_textures
[
i
/
faded_textures
[
0
].
length
][
i
%
faded_textures
[
0
].
length
];
dbg_titles
[
i
]
=
dbg_subtitles
[
i
%
dbg_subtitles
.
length
]
+
"-"
+
(
i
/
dbg_subtitles
.
length
);
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures
,
tilesX
*
transform_size
,
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-combined_textures"
,
dbg_titles
);
if
(
dbg_overlap
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_overlap
,
2
*
tilesX
*
transform_size
,
2
*
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-non-overlap_textures"
,
dbg_titles
);
}
if
(
dbg_weights
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_weights
,
tilesX
,
tilesY
,
true
,
ref_scene
.
getImageName
()+
"-texture_weights"
);
}
}
double
[]
minmax
=
parameter_scene
.
getColdHot
();
// used in linearStackToColor
ImagePlus
[]
imp_tex
=
new
ImagePlus
[
num_slices
];
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
String
title
=
String
.
format
(
"%s-combo%03d-texture"
,
ref_scene
.
getImageName
(),
nslice
);
imp_tex
[
nslice
]
=
QuadCLTCPU
.
linearStackToColorLWIR
(
clt_parameters
,
// CLTParameters clt_parameters,
tex_palette
,
// int lwir_palette, // <0 - do not convert
minmax
,
// double [] minmax,
title
,
// String name,
""
,
// String suffix, // such as disparity=...
tex_color
,
// boolean toRGB,
faded_textures
[
nslice
],
// double [][] texture_data,
tilesX
*
transform_size
,
// int width, // int tilesX,
tilesY
*
transform_size
,
// int height, // int tilesY,
debug_level
);
// int debugLevel )
// Add synthetic mesh only with higher resolution? or just any by a specified period?what king of mesh - vertical random, ...
// Split and save as png
}
// Process accumulated textures: average, apply borders, convert to color or apply UM, add synthetic mesh, ...
return
imp_tex
;
// ImagePlus[] ? with alpha, to be split into png and saved with alpha.
}
public
static
double
[][]
getComboTexture
(
final
double
[][][]
sensor_texture
)
{
final
int
num_slices
=
sensor_texture
.
length
;
final
int
num_sensors
=
sensor_texture
[
0
].
length
;
final
int
img_size
=
sensor_texture
[
0
][
0
].
length
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
double
[][]
combo_texture
=
new
double
[
num_slices
][
img_size
];
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
Arrays
.
fill
(
combo_texture
[
fnslice
],
Double
.
NaN
);
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
indx
=
ai
.
getAndIncrement
();
indx
<
img_size
;
indx
=
ai
.
getAndIncrement
())
if
(!
Double
.
isNaN
(
sensor_texture
[
fnslice
][
0
][
indx
]))
{
double
d
=
0
;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
d
+=
sensor_texture
[
fnslice
][
nsens
][
indx
];
extended_slice_disparities
[
fnslice
]
=
slice_disparities
[
fnslice
].
clone
();
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
new_tiles
[
fnslice
][
tile
])
{
double
sw
=
0
,
swd
=
0.0
;
for
(
int
dir
=
0
;
dir
<
8
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
if
((
tile1
>=
0
)
&&
!
Double
.
isNaN
(
slice_disparities
[
fnslice
][
tile1
]))
{
// only average old tiles
double
w
=
((
dir
&
1
)
!=
0
)?
weight_diag
:
1.0
;
sw
+=
w
;
swd
+=
slice_disparities
[
fnslice
][
tile1
]
*
w
;
}
combo_texture
[
fnslice
][
indx
]
=
d
/
num_sensors
;
}
extended_slice_disparities
[
fnslice
][
tile
]
=
swd
/
sw
;
// weighted average, sw should not be 0 here
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
return
combo_texture
;
}
public
static
double
getMaxDisparity
(
double
[][]
slice_disparities
,
double
max_disparity_lim
)
{
final
int
num_slices
=
slice_disparities
.
length
;
final
int
tiles
=
slice_disparities
[
0
].
length
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
th_max_disp
=
new
double
[
threads
.
length
];
final
int
tile_slices
=
tiles
*
num_slices
;
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
showDebugBoolean
(
new_tiles
,
// boolean [][] selected,
tilesX
,
// final int tilesX,
"new_tiles"
);
// String prefix)
showDebugDisparities
(
// nop if dbg_prefix== null
extended_slice_disparities
,
// final double [][] slice_disparities,
tilesX
,
// final int tilesX,
"all-extended-disparities"
);
// String prefix);
final
boolean
[][][]
fg_has_bg_ext
=
get_fg_has_bg_any
(
// {is_fg, has_bg, has_tile}
extended_slice_disparities
,
// final double [][] slice_disparities,
slice_disparities
,
// final double [][] slice_disparities_real, // not extended
max_disparity_lim
,
// final double max_disparity_lim,
min_trim_disparity
,
// final double min_trim_disparity,
transform_size
,
// final int transform_size,
tilesX
);
// final int tilesX)
showDebugFgBg
(
// nop if dbg_prefix== null
fg_has_bg_ext
,
// boolean [][][] fg_has_bg,
tilesX
,
// final int tilesX,
"all-extended-fgbg"
);
// String prefix);
// Now find which tiles are FG, but only compare with old tiles
// need to modify get_fg_has_bg_any() and make sure that if two disparities are equal, both tiles are FG, DONE
// but none is count as BG for the other.
// Now update TileCluster[] tileClusters to include new tiles
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
new_tiles
[
fnslice
][
tile
])
{
if
(
fg_has_bg_ext
[
0
][
fnslice
][
tile
])
{
// new is foreground - remove
extended_slice_disparities
[
fnslice
][
tile
]
=
Double
.
NaN
;
new_tiles
[
fnslice
][
tile
]
=
false
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
showDebugDisparities
(
// nop if dbg_prefix== null
extended_slice_disparities
,
// final double [][] slice_disparities,
tilesX
,
// final int tilesX,
"trimmed-extended-disparities"
);
// String prefix);
// update tileClusters[fnslice]
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
ti
=
ati
.
getAndIncrement
();
for
(
int
indx
=
ai
.
getAndIncrement
();
indx
<
tile_slices
;
indx
=
ai
.
getAndIncrement
())
{
int
nslice
=
indx
/
tiles
;
int
tile
=
indx
%
tiles
;
if
(!
Double
.
isNaN
(
slice_disparities
[
nslice
][
tile
]))
{
if
((
slice_disparities
[
nslice
][
tile
]
>
th_max_disp
[
ti
])
&&
(
slice_disparities
[
nslice
][
tile
]
<
max_disparity_lim
)){
th_max_disp
[
ti
]
=
slice_disparities
[
nslice
][
tile
];
}
for
(
int
nslice
=
ai
.
getAndIncrement
();
nslice
<
num_slices
;
nslice
=
ai
.
getAndIncrement
())
{
tileClusters
[
nslice
].
setDisparity
(
extended_slice_disparities
[
nslice
]);
tileClusters
[
nslice
].
increaseBounds
();
// increase bounds by 1 tile each side
tileClusters
[
nslice
].
resetClusterIndex
();
// will rebuild next time tileClusters[nslice].getClusterIndex() will be called
// tileClusters[nslice].getClusterIndex();
/*
Rectangle [] sub_bounds = tileClusters[nslice].getSubBounds();
for (int nsub = 0; nsub < sub_bounds.length; nsub++) {
double [] cluster_disparity = TileNeibs.getDoubleWindow(
sub_bounds[nsub], // Rectangle window,
extended_slice_disparities[nslice], // double [] data,
tilesX); // int data_width)
tileClusters[nslice].setSubDisparity(
nsub, // int indx,
cluster_disparity); // double [] sub_disparity)
}
*/
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
disparity_max
=
0.0
;
for
(
int
i
=
0
;
i
<
th_max_disp
.
length
;
i
++)
{
disparity_max
=
Math
.
max
(
disparity_max
,
th_max_disp
[
i
]);
}
return
disparity_max
;
return
;
}
public
static
boolean
[][][]
get_fg_has_bg_any
(
final
double
[][]
slice_disparities
,
final
double
[][]
slice_disparities_real
,
// not extended
final
double
max_disparity_lim
,
final
double
min_trim_disparity
,
final
int
transform_size
,
...
...
@@ -1374,9 +1172,10 @@ public class TexturedModel {
final
int
num_slices
=
slice_disparities
.
length
;
final
int
tiles
=
slice_disparities
[
0
].
length
;
final
int
tilesY
=
tiles
/
tilesX
;
final
boolean
[][]
is_fg_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
has_bg_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
has_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
is_fg_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
has_bg_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
has_tile
=
new
boolean
[
num_slices
][
tiles
];
final
boolean
[][]
border_tiles
=
new
boolean
[
num_slices
][
tiles
];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
double
disparity_max
=
getMaxDisparity
(
...
...
@@ -1397,10 +1196,49 @@ public class TexturedModel {
System
.
out
.
println
(
"fnslice="
+
fnslice
+
", tile="
+
tile
);
}
has_tile
[
fnslice
][
tile
]
=
true
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
has_tile
[
fnslice
][
tile
]){
for
(
int
dir
=
0
;
dir
<
8
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
if
((
tile1
<
0
)
||
!
has_tile
[
fnslice
][
tile1
])
{
border_tiles
[
fnslice
][
tile
]
=
true
;
break
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
int
fnslice
=
nslice
;
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
has_tile
[
fnslice
][
tile
]){
// may be a FG tile that needs trimming (not considering yet tiles that both can be obscured and obscure).
if
((
fnslice
==
-
6
)
&&
(
tile
==
2333
))
{
System
.
out
.
println
(
"fnslice="
+
fnslice
+
", tile="
+
tile
);
System
.
out
.
println
(
"fnslice="
+
fnslice
+
", tile="
+
tile
);
}
if
(
slice_disparities
[
fnslice
][
tile
]
>
min_trim_disparity
)
{
is_fg_tile
[
fnslice
][
tile
]
=
true
;
for
(
int
ns
=
0
;
ns
<
num_slices
;
ns
++)
if
((
ns
!=
fnslice
)
&&
if
(
(
ns
!=
fnslice
)
&&
!
border_tiles
[
ns
][
tile
]
&&
// do not count border BG - it will be semi-transparent
(
slice_disparities
[
ns
][
tile
]
<
slice_disparities
[
fnslice
][
tile
]))
{
has_bg_tile
[
fnslice
][
tile
]
=
true
;
break
;
...
...
@@ -1415,7 +1253,7 @@ public class TexturedModel {
if
(
tile1
>=
0
)
{
double
dd
=
(
Math
.
sqrt
(
dty
*
dty
+
dtx
*
dtx
)
+
0.0
)*
transform_size
+
slice_disparities
[
fnslice
][
tile
];
// is it correct?
for
(
int
ns
=
0
;
ns
<
num_slices
;
ns
++)
if
((
ns
!=
fnslice
)
||
(
dty
!=
0
)
||
(
dtx
!=
0
))
{
if
(
slice_disparities
[
ns
][
tile1
]
>
dd
)
{
if
(
slice_disparities
_real
[
ns
][
tile1
]
>
dd
)
{
// ignore extended tiles
is_fg_tile
[
fnslice
][
tile
]
=
false
;
break
search_obscuring
;
}
...
...
@@ -1429,8 +1267,27 @@ public class TexturedModel {
};
}
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
// calculate total number of connections (w/o fof) by combining opposite directions
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
if
(
has_tile
[
fnslice
][
tile
]){
for
(
int
dir
=
0
;
dir
<
8
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
if
((
tile1
<
0
)
||
!
has_tile
[
fnslice
][
tile1
])
{
border_tiles
[
fnslice
][
tile
]
=
true
;
break
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
return
new
boolean
[][][]
{
is_fg_tile
,
has_bg_tile
,
has_tile
};
return
new
boolean
[][][]
{
is_fg_tile
,
has_bg_tile
,
has_tile
,
border_tiles
};
}
//final double [][] slice_disparities,
...
...
@@ -1489,6 +1346,37 @@ public class TexturedModel {
}
}
public
static
void
showDebugBoolean
(
boolean
[][]
selected
,
final
int
tilesX
,
String
prefix
)
{
if
(
prefix
!=
null
)
{
final
int
num_slices
=
selected
.
length
;
final
int
tiles
=
selected
[
0
].
length
;
final
int
tilesY
=
tiles
/
tilesX
;
String
[]
dbg_titles
=
new
String
[
num_slices
];
for
(
int
i
=
0
;
i
<
dbg_titles
.
length
;
i
++)
{
dbg_titles
[
i
]
=
String
.
format
(
"slice-%02d"
,
i
);
}
double
[][]
dbg_selected
=
new
double
[
num_slices
][
tiles
];
for
(
int
ns
=
0
;
ns
<
num_slices
;
ns
++)
{
Arrays
.
fill
(
dbg_selected
[
ns
],
Double
.
NaN
);
for
(
int
tile
=
0
;
tile
<
tiles
;
tile
++)
{
dbg_selected
[
ns
][
tile
]
=
(
selected
[
ns
][
tile
]?
1
:
0
);
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_selected
,
tilesX
,
tilesY
,
true
,
prefix
+
"-boolean"
,
dbg_titles
);
}
}
public
static
double
[][][]
getVariances
(
...
...
@@ -1886,6 +1774,237 @@ public class TexturedModel {
}
ImageDtt
.
startAndJoin
(
threads
);
}
public
static
double
[][]
combineTextureAlpha
(
final
double
alpha_threshold
,
final
double
[][]
textures
,
final
double
[][]
alphas
)
{
final
double
[][]
masked_textures
=
new
double
[
textures
.
length
][];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nslice
=
ai
.
getAndIncrement
();
nslice
<
textures
.
length
;
nslice
=
ai
.
getAndIncrement
())
{
masked_textures
[
nslice
]
=
textures
[
nslice
].
clone
();
for
(
int
i
=
0
;
i
<
textures
[
nslice
].
length
;
i
++)
{
if
(
alphas
[
nslice
][
i
]
<
alpha_threshold
)
{
masked_textures
[
nslice
][
i
]
=
Double
.
NaN
;
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
masked_textures
;
}
public
static
void
extendBlueSKy
(
final
TileCluster
[]
tileClusters
,
final
double
[][][]
faded_textures
,
final
int
shrink_sky_tiles
,
final
int
width
,
final
int
transform_size
)
{
// final int img_size = faded_textures[0].length;
// final int tilesX = width/transform_size;
// final int tilesY = img_size/width/transform_size;
// final int tiles = tilesX * tilesY;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
int
sky_slice
=
-
1
;
int
sky_subindex
=
-
1
;
for
(
int
i
=
0
;
i
<
tileClusters
.
length
;
i
++)
{
sky_subindex
=
tileClusters
[
i
].
getSkyClusterIndex
();
if
(
sky_subindex
>=
0
)
{
sky_slice
=
i
;
break
;
}
}
if
(
sky_slice
>=
0
)
{
Rectangle
sky_tiles_bounds
=
tileClusters
[
sky_slice
].
getSubBounds
(
sky_subindex
);
Rectangle
sky_pixels_bounds
=
new
Rectangle
(
sky_tiles_bounds
.
x
*
transform_size
,
sky_tiles_bounds
.
y
*
transform_size
,
sky_tiles_bounds
.
width
*
transform_size
,
sky_tiles_bounds
.
height
*
transform_size
);
final
double
[]
sky_disparity
=
tileClusters
[
sky_slice
].
getSubDisparity
(
sky_subindex
);
final
int
num_sky_tiles
=
sky_disparity
.
length
;
final
TileNeibs
tn_sky_tiles
=
new
TileNeibs
(
sky_tiles_bounds
.
width
,
sky_tiles_bounds
.
height
);
// final TileNeibs tn_sky_pixels = new TileNeibs(sky_pixels_bounds.width, sky_pixels_bounds.height);
final
boolean
[]
sky_sel
=
new
boolean
[
sky_disparity
.
length
];
for
(
int
i
=
0
;
i
<
sky_sel
.
length
;
i
++)
{
sky_sel
[
i
]
=
!
Double
.
isNaN
(
sky_disparity
[
i
]);
}
final
boolean
[]
reliable_sky
=
sky_sel
.
clone
();
final
double
[]
sky_pixels
=
TileNeibs
.
getDoubleWindow
(
sky_pixels_bounds
,
// Rectangle window,
faded_textures
[
sky_slice
][
0
],
// double [] data,
width
);
// int data_width)
if
(
shrink_sky_tiles
>
0
)
{
tn_sky_tiles
.
shrinkSelection
(
shrink_sky_tiles
,
reliable_sky
,
null
);
for
(
int
i
=
0
;
i
<
reliable_sky
.
length
;
i
++)
if
(!
reliable_sky
[
i
]){
sky_disparity
[
i
]
=
Double
.
NaN
;
}
// erase corresponding texture pixels
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
sky_tile
=
ai
.
getAndIncrement
();
sky_tile
<
num_sky_tiles
;
sky_tile
=
ai
.
getAndIncrement
())
{
if
(
sky_sel
[
sky_tile
]
&&
!
reliable_sky
[
sky_tile
])
{
int
sky_tileX
=
sky_tile
%
sky_tiles_bounds
.
width
;
int
sky_tileY
=
sky_tile
/
sky_tiles_bounds
.
width
;
int
pixX
=
sky_tileX
*
transform_size
;
int
pixY
=
sky_tileY
*
transform_size
;
int
pix_indx0
=
pixY
*
sky_pixels_bounds
.
width
+
pixX
;
for
(
int
row
=
0
;
row
<
transform_size
;
row
++)
{
int
pix_indx
=
pix_indx0
+
row
*
sky_pixels_bounds
.
width
;
Arrays
.
fill
(
sky_pixels
,
pix_indx
,
// int fromIndex,
pix_indx
+
transform_size
,
// int toIndex,
Double
.
NaN
);
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
// now fill gaps in disparity and pixels
double
[]
sky_disparity_filled
=
TileProcessor
.
fillNaNs
(
// multithreaded
sky_disparity
,
// final double [] data,
sky_tiles_bounds
.
width
,
// int width,
2
*
Math
.
max
(
sky_tiles_bounds
.
width
,
sky_tiles_bounds
.
height
),
// 16, // final int grow,
0.7
,
// double diagonal_weight, // relative to ortho
100
,
// int num_passes,
THREADS_MAX
);
// final int threadsMax) // maximal number of threads to launch
tileClusters
[
sky_slice
].
setSubDisparity
(
sky_subindex
,
sky_disparity_filled
);
double
[]
sky_pixels_filled
=
TileProcessor
.
fillNaNs
(
// multithreaded
sky_pixels
,
// final double [] data,
sky_pixels_bounds
.
width
,
// int width,
3
*
Math
.
min
(
sky_pixels_bounds
.
width
,
sky_pixels_bounds
.
height
)
/
2
,
// 16, // final int grow,
0.7
,
// double diagonal_weight, // relative to ortho
100
,
// int num_passes,
THREADS_MAX
);
// final int threadsMax) // maximal number of threads to launch
TileNeibs
.
setDoubleWindow
(
sky_pixels_bounds
,
// Rectangle window,
sky_pixels_filled
,
// double [] window_data,
faded_textures
[
sky_slice
][
0
],
// double [] data,
width
);
// int data_width)
double
[]
sky_alpha
=
new
double
[
sky_pixels
.
length
];
Arrays
.
fill
(
sky_alpha
,
1.0
);
TileNeibs
.
setDoubleWindow
(
sky_pixels_bounds
,
// Rectangle window,
sky_alpha
,
// double [] window_data,
faded_textures
[
sky_slice
][
1
],
// double [] data,
width
);
// int data_width)
}
return
;
}
public
static
void
fixAlphaSameDisparity
(
final
TileCluster
[]
tileClusters
,
final
double
[][][]
faded_textures
,
final
double
alphaOverlapTolerance
,
// 0 - require exact match
final
int
width
,
final
int
transform_size
)
{
final
int
num_slices
=
tileClusters
.
length
;
final
int
img_size
=
faded_textures
[
0
][
0
].
length
;
final
int
tilesX
=
width
/
transform_size
;
final
int
tilesY
=
img_size
/
width
/
transform_size
;
final
int
tiles
=
tilesX
*
tilesY
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
double
[][]
tile_disparity
=
new
double
[
num_slices
][];
for
(
int
nslice
=
0
;
nslice
<
tileClusters
.
length
;
nslice
++)
{
tile_disparity
[
nslice
]
=
tileClusters
[
nslice
].
getDisparity
();
}
final
double
min_disparity
=
2.0
;
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
double
[]
disparities
=
new
double
[
num_slices
];
int
group
[]
=
new
int
[
num_slices
];
int
[][]
members
=
new
int
[
num_slices
][];
int
[]
group_members
=
new
int
[
num_slices
];
for
(
int
tile
=
ai
.
getAndIncrement
();
tile
<
tiles
;
tile
=
ai
.
getAndIncrement
())
{
int
num_tiles
=
0
;
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
disparities
[
nslice
]
=
tile_disparity
[
nslice
][
tile
];
if
(!
Double
.
isNaN
(
disparities
[
nslice
]))
{
num_tiles
++;
}
}
if
(
num_tiles
>
1
)
{
Arrays
.
fill
(
group
,
-
1
);
int
ngroup
=
0
;
for
(
int
i
=
0
;
i
<
(
num_slices
-
1
);
i
++)
if
((
group
[
i
]
<
0
)
&&
!
Double
.
isNaN
(
disparities
[
i
])){
int
nsame
=
0
;
group_members
[
nsame
++]
=
i
;
double
max_diff
=
Math
.
max
(
disparities
[
i
],
min_disparity
)
*
alphaOverlapTolerance
;
for
(
int
j
=
i
+
1
;
j
<
num_slices
;
j
++)
if
((
group
[
j
]
<
0
)
&&
!
Double
.
isNaN
(
disparities
[
j
])){
boolean
same
=
(
alphaOverlapTolerance
==
0
)
?
(
disparities
[
j
]
==
disparities
[
i
])
:
(
Math
.
abs
(
disparities
[
j
]
-
disparities
[
i
])
<
max_diff
);
if
(
same
)
{
group
[
j
]
=
ngroup
;
group_members
[
nsame
++]
=
j
;
}
}
if
(
nsame
>
1
)
{
members
[
ngroup
]=
new
int
[
nsame
];
group
[
i
]
=
ngroup
;
for
(
int
j
=
0
;
j
<
nsame
;
j
++)
{
members
[
ngroup
][
j
]
=
group_members
[
j
];
}
ngroup
++;
}
}
if
(
ngroup
>
0
)
{
int
y0
=
(
tile
/
tilesX
)
*
transform_size
;
int
x0
=
(
tile
%
tilesX
)
*
transform_size
;
int
indx0
=
y0
*
width
+
x0
;
for
(
int
ng
=
0
;
ng
<
ngroup
;
ng
++)
{
for
(
int
dy
=
0
;
dy
<
transform_size
;
dy
++)
{
int
indx1
=
indx0
+
dy
*
width
;
for
(
int
dx
=
0
;
dx
<
transform_size
;
dx
++)
{
int
indx
=
indx1
+
dx
;
double
a
=
faded_textures
[
members
[
ng
][
0
]][
1
][
indx
];
for
(
int
j
=
1
;
j
<
members
[
ng
].
length
;
j
++)
{
a
=
Math
.
max
(
a
,
faded_textures
[
members
[
ng
][
j
]][
1
][
indx
]);
}
for
(
int
j
=
0
;
j
<
members
[
ng
].
length
;
j
++)
{
faded_textures
[
members
[
ng
][
j
]][
1
][
indx
]
=
a
;
}
}
}
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
;
}
...
...
@@ -2329,6 +2448,11 @@ public class TexturedModel {
final
double
[][]
slice_disparities
,
final
double
[][][]
sensor_texture
,
// per-sensor texture value
final
double
[][]
combo_texture_in
,
// average texture value
final
TileCluster
[]
tileClusters
,
// to process blue_sky?
// final boolean extend_sky,
// final int shrink_sky_tiles,
final
double
max_disparity_lim
,
// = 100.0; // do not allow stray disparities above this
final
double
min_trim_disparity
,
// = 2.0; // do not try to trim texture outlines with lower disparities
final
String
dbg_prefix
)
{
final
double
var_radius
=
3.5
;
// for variance filter of the combo disparity
final
double
dir_radius
=
1.5
;
// averaging inter-sensor variance to view behind obstacles
...
...
@@ -2337,9 +2461,7 @@ public class TexturedModel {
final
int
dir_num_restart
=
5
;
// restart (from best direction) with this number of consecutive sensors
final
double
dir_worsen_rel
=
0.15
;
// add more sensors until variance grows by this relative
final
double
dir_var_max
=
15.0
;
// do not add more sensors if the variance would exceed this
final
double
max_disparity_lim
=
100.0
;
// do not allow stray disparities above this
final
double
min_trim_disparity
=
2.0
;
// do not try to trim texture outlines with lower disparities
final
double
fg_max_inter
=
40.0
;
// Trim FG tile if inter variance exceeds
final
double
fg_max_inter
=
200
;
// temporary disable 40.0; // Trim FG tile if inter variance exceeds
final
double
fg_max_rel
=
2.0
;
// Trim FG tile if inter variance to same variance exceeds
final
double
min_edge_variance
=
20.0
;
// minimal FG edge variance (trim outside)
final
int
min_neibs
=
2
;
// remove pixel clusters with less neighbors
...
...
@@ -2366,6 +2488,7 @@ public class TexturedModel {
final
boolean
[][][]
fg_has_bg
=
get_fg_has_bg_any
(
slice_disparities
,
// final double [][] slice_disparities,
slice_disparities
,
// final double [][] slice_disparities_real, // not extended
max_disparity_lim
,
// final double max_disparity_lim,
min_trim_disparity
,
// final double min_trim_disparity,
transform_size
,
// final int transform_size,
...
...
@@ -2395,12 +2518,12 @@ public class TexturedModel {
width
,
// final int width,
trim_edge
);
// final int trim_edge)
final
boolean
[][]
texture_fg_filt
=
filterFgByVariances
(
final
boolean
[][]
texture_fg_filt
=
filterFgByVariances
(
// OK if fg_has_bg[0,1] is for non-existing tile
gcombo_texture
,
// final double [][] combo_texture,
texture_on
,
// final boolean [][] texture_on, // if null will rely on NaN in combo_texture
vars
[
0
],
// final double [][] vars_same,
vars
[
1
],
// final double [][] vars_inter,
fg_has_bg
[
0
],
// final boolean [][] is_fg_tile,
fg_has_bg
[
0
],
// final boolean [][] is_fg_tile,
fg_has_bg
[
1
],
// final boolean [][] has_bg_tile,
fg_max_inter
,
// final double fg_max_inter,
fg_max_rel
,
// final double fg_max_rel,
...
...
@@ -2609,15 +2732,26 @@ public class TexturedModel {
width
,
height
,
true
,
dbg_prefix
+
"-out_textures"
);
dbg_prefix
+
"-out_textures"
);
ShowDoubleFloatArrays
.
showArrays
(
alphas
,
width
,
height
,
true
,
dbg_prefix
+
"-alphas"
);
dbg_prefix
+
"-alphas"
);
double
[][]
masked_textures
=
combineTextureAlpha
(
0.5
,
// final double alpha_threshold,
out_textures
,
// final double [][] textures,
alphas
);
// final double [][] alphas
ShowDoubleFloatArrays
.
showArrays
(
masked_textures
,
width
,
height
,
true
,
dbg_prefix
+
"-masked_textures"
);
}
double
[][][]
textures_alphas
=
new
double
[
num_slices
][][];
...
...
@@ -2628,7 +2762,7 @@ public class TexturedModel {
}
public
static
ImagePlus
[]
getInterCombinedTextures
New
(
// return ImagePlus[] matching tileClusters[], with alpha
public
static
ImagePlus
[]
getInterCombinedTextures
(
// return ImagePlus[] matching tileClusters[], with alpha
final
CLTParameters
clt_parameters
,
ColorProcParameters
colorProcParameters
,
EyesisCorrectionParameters
.
RGBParameters
rgbParameters
,
...
...
@@ -2639,6 +2773,8 @@ public class TexturedModel {
final
boolean
[]
selection
,
// may be null, if not null do not process unselected tiles
final
TileCluster
[]
tileClusters
,
// disparities, borders, selections for texture passes
final
boolean
renormalize
,
// false - use normalizations from previous scenes to keep consistent colors
final
double
max_disparity_lim
,
// 100.0; // do not allow stray disparities above this
final
double
min_trim_disparity
,
// 2.0; // do not try to trim texture outlines with lower disparities
final
int
debug_level
)
{
// TODO: ***** scenes with high motion blur also have high ERS to be corrected ! *****
...
...
@@ -2682,6 +2818,11 @@ public class TexturedModel {
final
boolean
tex_color
=
clt_parameters
.
tex_color
;
// true;
final
int
tex_palette
=
clt_parameters
.
tex_palette
;
// 2 ;
// final boolean extend_sky = true;
final
int
shrink_sky_tiles
=
4
;
// 2; sum of 2 +bg extend
final
boolean
grow_sky
=
true
;
final
boolean
alphaOverlapFix
=
true
;
// if multiple tiles have the same (+/-?) disparity, make alpha max of them
final
double
alphaOverlapTolerance
=
0.0
;
// compare same disparity with tolerance (relative to disparity? make absolute meters?)
ImageDtt
image_dtt
;
image_dtt
=
new
ImageDtt
(
...
...
@@ -2788,7 +2929,11 @@ public class TexturedModel {
max_distortion
,
// final double max_distortion, // maximal neighbor tiles offset as a fraction of tile size (8)
cluster_indices
[
nslice
],
// final int [] cluster_index, //
borders
[
nslice
],
// final boolean [] border, // border tiles
true
,
//keep_channels, // final boolean keep_channels,
// without the following uniform sky develops horizontal lines caused by image edge tiles on scenes where
// they are over clear part of the reference scene window
10
,
// final int discard_frame_edges, // do not use tiles that have pixels closer to the frame margins
1
,
// final int keep_frame_tiles, // do not discard pixels for border tiles in reference frame
true
,
// keep_channels, // final boolean keep_channels,
debug_level
);
// final int debugLevel);
if
(
slice_texture88
!=
null
)
{
// will just accumulate
...
...
@@ -2840,10 +2985,9 @@ public class TexturedModel {
}
}
// for (int nslice = 0; nslice < num_slices; nslice++) {
}
// for (int nscene = 0; nscene < num_scenes; nscene++) {
// Divide accumulated data by weights
/// double [][][] faded_textures = new double [num_slices][][];
final
double
[][]
dbg_weights
=
(
debug_level
>
0
)?(
new
double
[
num_slices
][
tiles
])
:
null
;
final
double
[][]
dbg_overlap
=
(
debug_level
>
0
)?(
new
double
[
num_slices
*(
num_colors
+
1
)][])
:
null
;
final
int
width
=
tilesX
*
transform_size
;
final
int
height
=
tilesY
*
transform_size
;
final
int
y_color
=
num_colors
-
1
;
...
...
@@ -2905,7 +3049,6 @@ public class TexturedModel {
combo_textures
[
fnslice
]
,
// dbg_textures[n],
(
tileY
*
transform_size
+
row
)
*
width
+
(
tileX
*
transform_size
),
transform_size
);
}
}
}
...
...
@@ -2914,26 +3057,25 @@ public class TexturedModel {
}
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
}
// for (int nslice = 0; nslice < num_slices; nslice++) {
final
double
[][]
slice_disparities
=
new
double
[
num_slices
][];
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
slice_disparities
[
nslice
]
=
tileClusters
[
nslice
].
getDisparity
();
// disparity in the reference view tiles (Double.NaN - invalid)
}
double
[][][]
faded_textures
=
processTexture
(
//[slice]{texture, alpha}
clt_parameters
,
// final CLTParameters clt_parameters,
tilesX
,
// final int tilesX,
slice_disparities
,
// final double [][] slice_disparities,
sensor_textures
,
// final double [][] sensor_texture, // per-sensor texture value
null
,
// combo_textures, // null, // final double [] combo_texture_in, // average texture value
clt_parameters
,
// final CLTParameters clt_parameters,
tilesX
,
// final int tilesX,
slice_disparities
,
// final double [][] slice_disparities,
sensor_textures
,
// final double [][] sensor_texture, // per-sensor texture value
null
,
// combo_textures, // null, // final double [] combo_texture_in, // average texture value
tileClusters
,
// final TileCluster[] tileClusters, // to process blue_sky?
// extend_sky, // final boolean extend_sky,
// shrink_sky_tiles, // final int shrink_sky_tiles,
max_disparity_lim
,
// final double max_disparity_lim, // do not allow stray disparities above this
min_trim_disparity
,
// final double min_trim_disparity, // do not try to trim texture outlines with lower disparities
ref_scene
.
getImageName
());
// null); // ref_scene.getImageName()); // final String dbg_prefix);
// if (debug_level > -1000) {
// return null;
// }
if
(
debug_level
>
-
1
)
{
double
[][]
dbg_textures
=
new
double
[
faded_textures
.
length
*
faded_textures
[
0
].
length
][
faded_textures
[
0
][
0
].
length
];
String
[]
dbg_titles
=
new
String
[
dbg_textures
.
length
];
...
...
@@ -2955,8 +3097,31 @@ public class TexturedModel {
ref_scene
.
getImageName
()+
"-combined_textures-prenorm-pre_UM"
,
dbg_titles
);
}
}
// boolean grow_sky = true;
//int shrink_sky_tiles = 2;
// Grow sky
if
(
grow_sky
)
{
extendBlueSKy
(
tileClusters
,
// final TileCluster [] tileClusters,
faded_textures
,
// final double [][][] faded_textures,
shrink_sky_tiles
,
// final int shrink_sky_tiles,
width
,
// final int width,
transform_size
);
// final int transform_size);
}
// fix alpha
if
(
alphaOverlapFix
)
{
fixAlphaSameDisparity
(
tileClusters
,
// final TileCluster [] tileClusters,
faded_textures
,
// final double [][][] faded_textures,
alphaOverlapTolerance
,
// final int alphaOverlapTolerance, // 0 - require exact match
width
,
// final int width,
transform_size
);
// final int transform_size)
}
// Is it needed here? Or move to processTexture()? - Slow
for
(
int
nslice
=
0
;
nslice
<
faded_textures
.
length
;
nslice
++)
{
faded_textures
[
nslice
][
0
]
=
TileProcessor
.
fillNaNs
(
faded_textures
[
nslice
][
0
],
// final double [] data,
...
...
@@ -2989,9 +3154,6 @@ public class TexturedModel {
dbg_titles
);
}
// Optionally apply UM (before auto/manual range)
if
(
tex_um
)
{
QuadCLTCPU
.
umTextures
(
...
...
@@ -3021,16 +3183,6 @@ public class TexturedModel {
true
,
ref_scene
.
getImageName
()+
"-combined_textures-prenorm"
,
dbg_titles
);
if
(
dbg_overlap
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_overlap
,
2
*
tilesX
*
transform_size
,
2
*
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-non-overlap_textures-prenorm"
,
dbg_titles
);
}
if
(
dbg_weights
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_weights
,
...
...
@@ -3125,16 +3277,6 @@ public class TexturedModel {
true
,
ref_scene
.
getImageName
()+
"-combined_textures"
,
dbg_titles
);
if
(
dbg_overlap
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_overlap
,
2
*
tilesX
*
transform_size
,
2
*
tilesY
*
transform_size
,
true
,
ref_scene
.
getImageName
()+
"-non-overlap_textures"
,
dbg_titles
);
}
if
(
dbg_weights
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_weights
,
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileCluster.java
View file @
164444fe
...
...
@@ -32,15 +32,19 @@ class TileCluster{
double
[]
disparity
;
// all and only unused - NaN
int
[]
cluster_index
=
null
;
// for debug purposes, index of the source cluster
int
index
=
-
1
;
boolean
is_sky
=
false
;
ArrayList
<
IndexedRectanle
>
clust_list
;
class
IndexedRectanle
{
int
index
;
Rectangle
bounds
;
boolean
is_sky
;
IndexedRectanle
(
int
index
,
Rectangle
bounds
){
Rectangle
bounds
,
boolean
is_sky
){
this
.
index
=
index
;
this
.
bounds
=
bounds
;
this
.
is_sky
=
is_sky
;
}
}
// to use cluster_index - set index >= 0, <0 - do not use.
...
...
@@ -48,9 +52,11 @@ class TileCluster{
Rectangle
bounds
,
int
index
,
// <0 to skip
boolean
[]
border
,
double
[]
disparity
){
double
[]
disparity
,
boolean
is_sky
){
this
.
bounds
=
bounds
;
this
.
index
=
index
;
this
.
index
=
index
;
this
.
is_sky
=
is_sky
;
/**
if (index >= 0) {
this.cluster_index = new int [bounds.width * bounds.height];
...
...
@@ -72,10 +78,31 @@ class TileCluster{
}
this
.
disparity
=
disparity
;
}
public
boolean
isSky
()
{
return
is_sky
;
}
public
int
getSkyClusterIndex
()
{
if
(
clust_list
==
null
)
{
return
-
2
;
}
for
(
int
i
=
0
;
i
<
clust_list
.
size
();
i
++)
{
if
(
clust_list
.
get
(
i
).
is_sky
)
{
return
i
;
}
}
return
-
1
;
}
public
Rectangle
getBounds
()
{
return
bounds
;}
public
Rectangle
getBounds
()
{
return
bounds
;
}
public
Rectangle
getBounds
(
int
gap
)
{
return
new
Rectangle
(
bounds
.
x
-
gap
,
bounds
.
y
-
gap
,
bounds
.
width
+
2
*
gap
,
bounds
.
height
+
2
*
gap
);
}
public
boolean
[]
getBorder
()
{
return
border
;}
public
double
[]
getDisparity
()
{
return
disparity
;}
public
void
setDisparity
(
double
[]
disparity
)
{
this
.
disparity
=
disparity
;}
public
double
[]
getSubDisparity
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
null
;
...
...
@@ -94,6 +121,32 @@ class TileCluster{
}
return
sub_disparity
;
}
public
void
setSubDisparity
(
int
indx
,
double
[]
sub_disparity
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
;
}
Rectangle
sub_bounds
=
clust_list
.
get
(
indx
).
bounds
;
int
src_x
=
sub_bounds
.
x
-
bounds
.
x
;
for
(
int
dst_y
=
0
;
dst_y
<
sub_bounds
.
height
;
dst_y
++)
{
int
src_y
=
dst_y
+
sub_bounds
.
y
-
bounds
.
y
;
System
.
arraycopy
(
sub_disparity
,
dst_y
*
sub_bounds
.
width
,
disparity
,
src_y
*
bounds
.
width
+
src_x
,
sub_bounds
.
width
);
}
}
public
boolean
isSubSky
(
int
indx
)
{
if
(
clust_list
==
null
)
{
return
false
;
}
return
clust_list
.
get
(
indx
).
is_sky
;
}
public
boolean
[]
getSubBorder
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
...
...
@@ -113,7 +166,7 @@ class TileCluster{
}
return
sub_border
;
}
// returns selected for all non-NAN, so it is possible to use NEGATIVE_INFINITY for non-NaN
public
boolean
[]
getSubSelected
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
null
;
...
...
@@ -141,6 +194,15 @@ class TileCluster{
return
selected
;
}
public
Rectangle
getSubBounds
(
int
indx
)
{
if
(
clust_list
==
null
)
{
return
null
;
}
else
{
Rectangle
sub_bounds
=
clust_list
.
get
(
indx
).
bounds
;
return
sub_bounds
;
}
}
public
Rectangle
[]
getSubBounds
()
{
if
(
clust_list
==
null
)
{
return
null
;
...
...
@@ -163,6 +225,9 @@ class TileCluster{
return
sub_indices
;
}
}
public
void
resetClusterIndex
()
{
// to rebuild cluster index from disparity
this
.
cluster_index
=
null
;
}
public
int
[]
getClusterIndex
()
{
// (Now not) just a debug feature, no need to optimize?
if
(
clust_list
==
null
)
{
return
null
;
...
...
@@ -183,6 +248,36 @@ class TileCluster{
}
}
return
cluster_index
;
}
public
void
increaseBounds
()
{
int
num_subs
=
getSubBounds
().
length
;
for
(
int
indx
=
0
;
indx
<
num_subs
;
indx
++)
{
increaseBounds
(
indx
);
}
}
public
void
increaseBounds
(
int
sub_index
)
{
Rectangle
bounds
=
getSubBounds
(
sub_index
);
Rectangle
ext_bounds
=
new
Rectangle
(
bounds
.
x
-
1
,
bounds
.
y
-
1
,
bounds
.
width
+
2
,
bounds
.
height
+
2
);
if
(
ext_bounds
.
x
<
0
)
{
ext_bounds
.
width
+=
ext_bounds
.
x
;
ext_bounds
.
x
=
0
;
}
if
((
ext_bounds
.
x
+
ext_bounds
.
width
)
>
this
.
bounds
.
width
)
{
ext_bounds
.
width
=
this
.
bounds
.
width
-
ext_bounds
.
x
;
}
if
(
ext_bounds
.
y
<
0
)
{
ext_bounds
.
height
+=
ext_bounds
.
y
;
ext_bounds
.
y
=
0
;
}
if
((
ext_bounds
.
y
+
ext_bounds
.
height
)
>
this
.
bounds
.
height
)
{
ext_bounds
.
height
=
this
.
bounds
.
height
-
ext_bounds
.
y
;
}
bounds
.
x
=
ext_bounds
.
x
;
bounds
.
y
=
ext_bounds
.
y
;
bounds
.
width
=
ext_bounds
.
width
;
bounds
.
height
=
ext_bounds
.
height
;
}
...
...
@@ -194,7 +289,7 @@ class TileCluster{
if
(
clust_list
==
null
)
{
clust_list
=
new
ArrayList
<
IndexedRectanle
>();
}
clust_list
.
add
(
new
IndexedRectanle
(
tileCluster
.
index
,
tileCluster
.
bounds
));
clust_list
.
add
(
new
IndexedRectanle
(
tileCluster
.
index
,
tileCluster
.
bounds
,
tileCluster
.
isSky
()
));
int
dst_x
=
tileCluster
.
bounds
.
x
-
bounds
.
x
;
for
(
int
src_y
=
0
;
src_y
<
tileCluster
.
bounds
.
height
;
src_y
++)
{
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileNeibs.java
View file @
164444fe
package
com
.
elphel
.
imagej
.
tileprocessor
;
import
java.awt.Rectangle
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
...
...
@@ -526,6 +527,37 @@ public class TileNeibs{
return
bound_shape
;
}
public
static
double
[]
getDoubleWindow
(
Rectangle
window
,
double
[]
data
,
int
data_width
)
{
double
[]
window_data
=
new
double
[
window
.
width
*
window
.
height
];
for
(
int
row
=
0
;
row
<
window
.
height
;
row
++)
{
System
.
arraycopy
(
data
,
(
window
.
y
+
row
)
*
data_width
+
window
.
x
,
window_data
,
row
*
window
.
width
,
window
.
width
);
}
return
window_data
;
}
public
static
void
setDoubleWindow
(
Rectangle
window
,
double
[]
window_data
,
double
[]
data
,
int
data_width
)
{
for
(
int
row
=
0
;
row
<
window
.
height
;
row
++)
{
System
.
arraycopy
(
window_data
,
row
*
window
.
width
,
data
,
(
window
.
y
+
row
)
*
data_width
+
window
.
x
,
window
.
width
);
}
}
public
int
[]
distanceFromEdge
(
boolean
[]
tiles
)
{
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileProcessor.java
View file @
164444fe
...
...
@@ -8991,13 +8991,14 @@ ImageDtt.startAndJoin(threads);
static
int
iSign
(
int
a
)
{
return
(
a
>
0
)
?
1
:
((
a
<
0
)?
-
1
:
0
);}
public
void
testTriangles
(
String
texturePath
,
String
texturePath
,
// if not null - will show
Rectangle
bounds
,
boolean
[]
selected
,
double
[]
disparity
,
int
tile_size
,
int
[][]
indices
,
int
[][]
triangles
)
int
[][]
triangles
,
double
[][]
debug_triangles
)
// if not null - should be [2][width* height], will mark disparity and triangles
{
String
[]
titles
=
{
"disparity"
,
"triangles"
};
double
[][]
dbg_img
=
new
double
[
titles
.
length
][
tilesX
*
tilesY
*
tile_size
*
tile_size
];
...
...
@@ -9053,12 +9054,30 @@ ImageDtt.startAndJoin(threads);
}
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
tilesX
*
tile_size
,
tilesY
*
tile_size
,
true
,
"triangles-"
+
texturePath
,
titles
);
if
(
texturePath
!=
null
)
{
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
tilesX
*
tile_size
,
tilesY
*
tile_size
,
true
,
"triangles-"
+
texturePath
,
titles
);
}
if
(
debug_triangles
!=
null
)
{
int
indx_tri
=
(
debug_triangles
.
length
>
1
)
?
1
:
0
;
for
(
int
i
=
0
;
i
<
debug_triangles
[
indx_tri
].
length
;
i
++)
{
if
(
dbg_img
[
1
][
i
]
>
0
)
{
debug_triangles
[
indx_tri
][
i
]
=
dbg_img
[
1
][
i
];
// 10.0 to have the same scale as disparity
}
}
if
(
indx_tri
>
0
)
{
for
(
int
i
=
0
;
i
<
debug_triangles
[
indx_tri
].
length
;
i
++)
{
if
(!
Double
.
isNaN
(
dbg_img
[
0
][
i
]))
{
debug_triangles
[
0
][
i
]
=
dbg_img
[
0
][
i
];
// disparity if not NaN
}
}
}
}
}
...
...
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