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
57fb1ef9
Commit
57fb1ef9
authored
Nov 19, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updating textures together with GPU code
parent
7ccf095c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
662 additions
and
388 deletions
+662
-388
GPUTileProcessor.java
src/main/java/com/elphel/imagej/gpu/GPUTileProcessor.java
+6
-3
GpuQuad.java
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
+3
-65
QuadCLT.java
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
+2
-2
TexturedModel.java
...n/java/com/elphel/imagej/tileprocessor/TexturedModel.java
+650
-317
TileNeibs.java
src/main/java/com/elphel/imagej/tileprocessor/TileNeibs.java
+1
-1
No files found.
src/main/java/com/elphel/imagej/gpu/GPUTileProcessor.java
View file @
57fb1ef9
...
...
@@ -134,17 +134,19 @@ public class GPUTileProcessor {
// static int TPTASK_SIZE = 1+ 1+ NUM_CAMS * 2 + 1 + NUM_CAMS * 4 ; // tp_task structure size in floats
static
int
CLTEXTRA_SIZE
=
8
;
static
int
CORR_SIZE
=
(
2
*
DTT_SIZE
-
1
)
*
(
2
*
DTT_SIZE
-
1
);
// 15x15
public
static
int
CORR_NTILE_SHIFT
=
8
;
// also for texture tiles list
public
static
int
CORR_NTILE_SHIFT
=
8
;
// also for texture tiles list
- not anymore 11/18/2022
// FIXME: CORR_PAIRS_MASK will not work !!!
public
static
int
CORR_PAIRS_MASK
=
0x3f
;
// lower bits used to address correlation pair for the selected tile
public
static
int
CORR_TEXTURE_BIT
=
7
;
// bit 7 used to request texture for the tile
// public static int CORR_TEXTURE_BIT = 7; // bit 7 used to request texture for the tile GET RID !!!
public
static
int
TASK_CORR_BITS
=
4
;
// start of pair mask
public
static
int
TASK_TEXTURE_N_BIT
=
0
;
// Texture with North neighbor
public
static
int
TASK_TEXTURE_E_BIT
=
1
;
// Texture with East neighbor
public
static
int
TASK_TEXTURE_S_BIT
=
2
;
// Texture with South neighbor
public
static
int
TASK_TEXTURE_W_BIT
=
3
;
// Texture with West neighbor
// public static int TASK_TEXTURE_BIT = 3; // bit to request texture calculation int task field of struct tp_task
public
static
int
LIST_TEXTURE_BIT
=
7
;
// bit to request texture calculation
public
static
int
TEXT_NTILE_SHIFT
=
8
;
// split from CORR_NTILE_SHIFT
// public static int CORR_OUT_RAD = 4; // output radius of the correlations (implemented)
public
static
double
FAT_ZERO_WEIGHT
=
0.0001
;
// add to port weights to avoid nan
...
...
@@ -226,13 +228,14 @@ public class GPUTileProcessor {
"#define IMCLT_TILES_PER_BLOCK "
+
IMCLT_TILES_PER_BLOCK
+
"\n"
+
"#define CORR_NTILE_SHIFT "
+
CORR_NTILE_SHIFT
+
"\n"
+
// "#define CORR_PAIRS_MASK " + CORR_PAIRS_MASK+"\n"+
"#define CORR_TEXTURE_BIT "
+
CORR_TEXTURE_BIT
+
"\n"
+
//
"#define CORR_TEXTURE_BIT " + CORR_TEXTURE_BIT+"\n"+
"#define TASK_CORR_BITS "
+
TASK_CORR_BITS
+
"\n"
+
"#define TASK_TEXTURE_N_BIT "
+
TASK_TEXTURE_N_BIT
+
"\n"
+
"#define TASK_TEXTURE_E_BIT "
+
TASK_TEXTURE_E_BIT
+
"\n"
+
"#define TASK_TEXTURE_S_BIT "
+
TASK_TEXTURE_S_BIT
+
"\n"
+
"#define TASK_TEXTURE_W_BIT "
+
TASK_TEXTURE_W_BIT
+
"\n"
+
"#define LIST_TEXTURE_BIT "
+
LIST_TEXTURE_BIT
+
"\n"
+
"#define TEXT_NTILE_SHIFT "
+
TEXT_NTILE_SHIFT
+
"\n"
+
// "#define CORR_OUT_RAD " + CORR_OUT_RAD+"\n" +
"#define FAT_ZERO_WEIGHT "
+
FAT_ZERO_WEIGHT
+
"\n"
+
"#define THREADS_DYNAMIC_BITS "
+
THREADS_DYNAMIC_BITS
+
"\n"
+
...
...
src/main/java/com/elphel/imagej/gpu/GpuQuad.java
View file @
57fb1ef9
...
...
@@ -1303,68 +1303,6 @@ public class GpuQuad{ // quad camera description
return
tp_tasks
;
}
/**
* Prepare contents pointers for calculation of the correlation pairs
* @param tp_tasks array of tasks that contain masks of the required pairs
* @return each element has (tile_number << 8) | (pair_number & 0xff)
*/
@Deprecated
public
int
[]
getCorrTasks
(
TpTask
[]
tp_tasks
)
{
int
tilesX
=
img_width
/
GPUTileProcessor
.
DTT_SIZE
;
int
num_corr
=
0
;
int
num_pairs
=
Correlation2d
.
getNumPairs
(
quadCLT
.
getNumSensors
());
int
task_mask
=
(
1
<<
num_pairs
)
-
1
;
for
(
TpTask
tt:
tp_tasks
)
{
int
pm
=
(
tt
.
task
>>
GPUTileProcessor
.
TASK_CORR_BITS
)
&
task_mask
;
if
(
pm
!=
0
)
{
for
(
int
b
=
0
;
b
<
num_pairs
;
b
++)
if
((
pm
&
(
1
<<
b
))
!=
0
)
{
num_corr
++;
}
}
}
int
[]
iarr
=
new
int
[
num_corr
];
num_corr
=
0
;
for
(
TpTask
tt:
tp_tasks
)
{
int
pm
=
(
tt
.
task
>>
GPUTileProcessor
.
TASK_CORR_BITS
)
&
task_mask
;
if
(
pm
!=
0
)
{
int
tile
=
(
tt
.
ty
*
tilesX
+
tt
.
tx
);
for
(
int
b
=
0
;
b
<
num_pairs
;
b
++)
if
((
pm
&
(
1
<<
b
))
!=
0
)
{
iarr
[
num_corr
++]
=
(
tile
<<
GPUTileProcessor
.
CORR_NTILE_SHIFT
)
|
b
;
}
}
}
return
iarr
;
}
/**
* Prepare contents pointers for calculation of the texture tiles (RGBA, 16x16)
* @param tp_tasks array of tasks that contain masks of the required pairs
* @return each element has (tile_number << 8) | (1 << LIST_TEXTURE_BIT)
*/
@Deprecated
public
int
[]
getTextureTasks
(
TpTask
[]
tp_tasks
)
{
int
tilesX
=
img_width
/
GPUTileProcessor
.
DTT_SIZE
;
int
num_textures
=
0
;
for
(
TpTask
tt:
tp_tasks
)
{
if
((
tt
.
task
&
GPUTileProcessor
.
TASK_TEXTURE_BITS
)
!=
0
)
{
num_textures
++;
}
}
int
[]
iarr
=
new
int
[
num_textures
];
num_textures
=
0
;
int
b
=
(
1
<<
GPUTileProcessor
.
LIST_TEXTURE_BIT
);
for
(
TpTask
tt:
tp_tasks
)
{
if
((
tt
.
task
&
GPUTileProcessor
.
TASK_TEXTURE_BITS
)
!=
0
)
{
int
tile
=
(
tt
.
ty
*
tilesX
+
tt
.
tx
);
iarr
[
num_textures
++]
=
(
tile
<<
GPUTileProcessor
.
CORR_NTILE_SHIFT
)
|
b
;
}
}
return
iarr
;
}
/**
* Calculate rotation matrices and their derivatives
...
...
@@ -3284,8 +3222,8 @@ public class GpuQuad{ // quad camera description
int
tilesY
=
img_height
/
GPUTileProcessor
.
DTT_SIZE
;
float
[][]
extra
=
new
float
[
num_tile_extra
][
tilesX
*
tilesY
];
for
(
int
i
=
0
;
i
<
texture_indices
.
length
;
i
++)
{
if
(((
texture_indices
[
i
]
>>
GPUTileProcessor
.
CORR
_TEXTURE_BIT
)
&
1
)
!=
0
)
{
int
ntile
=
(
texture_indices
[
i
]
>>
GPUTileProcessor
.
CORR
_NTILE_SHIFT
);
if
(((
texture_indices
[
i
]
>>
GPUTileProcessor
.
LIST
_TEXTURE_BIT
)
&
1
)
!=
0
)
{
int
ntile
=
(
texture_indices
[
i
]
>>
GPUTileProcessor
.
TEXT
_NTILE_SHIFT
);
for
(
int
l
=
0
;
l
<
num_tile_extra
;
l
++)
{
extra
[
l
][
ntile
]
=
diff_rgb_combo
[
i
*
num_tile_extra
+
l
];
}
...
...
@@ -3439,7 +3377,7 @@ public class GpuQuad{ // quad camera description
// double [][][][] textures = new double [woi.height][woi.width][num_slices][texture_slice_size];
for
(
int
indx
=
0
;
indx
<
indices
.
length
;
indx
++)
if
((
indices
[
indx
]
&
(
1
<<
GPUTileProcessor
.
LIST_TEXTURE_BIT
))
!=
0
){
int
tile
=
(
indices
[
indx
]
>>
GPUTileProcessor
.
CORR
_NTILE_SHIFT
);
int
tile
=
(
indices
[
indx
]
>>
GPUTileProcessor
.
TEXT
_NTILE_SHIFT
);
int
tileX
=
tile
%
full_width
;
int
tileY
=
tile
/
full_width
;
int
wtileX
=
tileX
-
woi
.
x
;
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLT.java
View file @
57fb1ef9
...
...
@@ -1782,7 +1782,7 @@ public class QuadCLT extends QuadCLTCPU {
final
QuadCLT
ref_scene
,
// now - may be null - for testing if scene is rotated ref
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
,
//
final
int
[]
cluster_index
,
//
[tilesX*tilesY]
final
boolean
[]
border
,
// border tiles
final
boolean
keep_channels
,
final
int
debugLevel
){
...
...
@@ -3386,7 +3386,7 @@ public class QuadCLT extends QuadCLTCPU {
if
(
debugLevel
>
-
1
)
{
for
(
int
indx
=
0
;
indx
<
texture_indices
.
length
;
indx
++)
if
((
texture_indices
[
indx
]
&
(
1
<<
GPUTileProcessor
.
LIST_TEXTURE_BIT
))
!=
0
){
int
tile
=
texture_indices
[
indx
]
>>
GPUTileProcessor
.
CORR
_NTILE_SHIFT
;
int
tile
=
texture_indices
[
indx
]
>>
GPUTileProcessor
.
TEXT
_NTILE_SHIFT
;
int
tileX
=
tile
%
tilesX
;
int
tileY
=
tile
/
tilesX
;
if
((
tileY
==
clt_parameters
.
tileY
)
&&
(
tileX
==
clt_parameters
.
tileX
))
{
...
...
src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java
View file @
57fb1ef9
...
...
@@ -1299,6 +1299,561 @@ public class TexturedModel {
}
public
static
double
[][]
processTexture
(
final
CLTParameters
clt_parameters
,
final
int
tilesX
,
final
double
[][]
slice_disparities
,
final
double
[][][]
sensor_texture
,
// per-sensor texture value
final
double
[][]
combo_texture_in
,
// average texture value
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
final
double
try_dir_var
=
20.0
;
// try directional if the intersensor variance exceeds this value
final
int
dir_num_start
=
7
;
// start with this number of consecutive sensors
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_rel
=
2.0
;
// Trim FG tile if inter variance to same variance exceeds
final
int
trim_shrink
=
2
;
final
int
trim_grow
=
2
;
final
int
trim_shrink2
=
2
;
final
int
trim_edge
=
9
;
final
int
num_slices
=
sensor_texture
.
length
;
final
int
ivar_radius
=
(
int
)
Math
.
floor
(
var_radius
);
final
int
idir_radius
=
(
int
)
Math
.
floor
(
dir_radius
);
final
double
[][]
var_weights
=
new
double
[
ivar_radius
+
1
][
ivar_radius
+
1
];
final
double
[][]
dir_weights
=
new
double
[
idir_radius
+
1
][
idir_radius
+
1
];
for
(
int
i
=
0
;
i
<
var_weights
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
var_weights
[
i
].
length
;
j
++)
{
var_weights
[
i
][
j
]
=
Math
.
cos
(
0.5
*
Math
.
PI
*
i
/
var_radius
)
*
Math
.
cos
(
0.5
*
Math
.
PI
*
j
/
var_radius
);
}
}
for
(
int
i
=
0
;
i
<
dir_weights
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
dir_weights
[
i
].
length
;
j
++)
{
dir_weights
[
i
][
j
]
=
Math
.
cos
(
0.5
*
Math
.
PI
*
i
/
dir_radius
)
*
Math
.
cos
(
0.5
*
Math
.
PI
*
j
/
dir_radius
);
}
}
final
int
transform_size
=
clt_parameters
.
transform_size
;
final
int
width
=
tilesX
*
transform_size
;
final
int
img_size
=
sensor_texture
[
0
][
0
].
length
;
final
int
height
=
img_size
/
width
;
final
int
tilesY
=
height
/
transform_size
;
final
int
tiles
=
tilesX
*
tilesY
;
final
int
offset_tile_center
=
transform_size
*
transform_size
/
2
;
final
int
num_sensors
=
sensor_texture
[
0
].
length
;
final
double
[][]
gcombo_texture
=
(
combo_texture_in
!=
null
)
?
combo_texture_in
:
new
double
[
num_slices
][
img_size
];
final
double
[][]
gvars_same
=
new
double
[
num_slices
][];
final
double
[][]
gvars_inter
=
new
double
[
num_slices
][];
final
double
[][]
out_textures
=
new
double
[
num_slices
][];
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
if
(
combo_texture_in
==
null
)
{
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
Arrays
.
fill
(
gcombo_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
];
}
gcombo_texture
[
fnslice
][
indx
]
=
d
/
num_sensors
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
}
// get max disparity
final
TileNeibs
tn
=
new
TileNeibs
(
tilesX
,
tilesY
);
final
double
[]
th_max_disp
=
new
double
[
threads
.
length
];
final
int
tile_slices
=
tiles
*
num_slices
;
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
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
()
{
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_max0
=
0.0
;
for
(
int
i
=
0
;
i
<
th_max_disp
.
length
;
i
++)
{
disparity_max0
=
Math
.
max
(
disparity_max0
,
th_max_disp
[
i
]);
}
final
double
disparity_max
=
disparity_max0
;
// int getNeibIndex(int indx, int dx, int dy) {
final
boolean
[][]
is_fg_tile
=
new
boolean
[
num_slices
][
tiles
];
// nothing obscures this
final
boolean
[][]
has_bg_tile
=
new
boolean
[
num_slices
][
tiles
];
// has tiles behind (at least directly)
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
(
slice_disparities
[
fnslice
][
tile
]
>
min_trim_disparity
){
// checks for NaN too !
// 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
);
}
is_fg_tile
[
fnslice
][
tile
]
=
true
;
for
(
int
ns
=
0
;
ns
<
num_slices
;
ns
++)
if
((
ns
!=
fnslice
)
&&
(
slice_disparities
[
ns
][
tile
]
<
slice_disparities
[
fnslice
][
tile
]))
{
has_bg_tile
[
fnslice
][
tile
]
=
true
;
break
;
}
search_obscuring:
{
int
tile_range
=
(
int
)
Math
.
ceil
((
disparity_max
-
slice_disparities
[
fnslice
][
tile
])/
Math
.
sqrt
(
2
)/
transform_size
);
for
(
int
dty
=
-
tile_range
;
dty
<=
tile_range
;
dty
++)
{
for
(
int
dtx
=
-
tile_range
;
dtx
<=
tile_range
;
dtx
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dtx
,
dty
);
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
)
{
is_fg_tile
[
fnslice
][
tile
]
=
false
;
break
search_obscuring
;
}
}
}
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
}
if
(
dbg_prefix
!=
null
)
{
String
[]
dbg_titles
=
new
String
[
num_slices
];
for
(
int
i
=
0
;
i
<
dbg_titles
.
length
;
i
++)
{
dbg_titles
[
i
]
=
String
.
format
(
"slice-%02d"
,
i
);
}
ShowDoubleFloatArrays
.
showArrays
(
slice_disparities
,
tilesX
,
tilesY
,
true
,
dbg_prefix
+
"-slice_disparities"
,
dbg_titles
);
double
[][]
dbg_fgbg
=
new
double
[
num_slices
][
tiles
];
for
(
int
ns
=
0
;
ns
<
num_slices
;
ns
++)
{
Arrays
.
fill
(
dbg_fgbg
[
ns
],
Double
.
NaN
);
for
(
int
tile
=
0
;
tile
<
tiles
;
tile
++)
{
dbg_fgbg
[
ns
][
tile
]
=
(
is_fg_tile
[
ns
][
tile
]?
2
:
0
)
+
(
has_bg_tile
[
ns
][
tile
]?
1
:
0
);
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_fgbg
,
tilesX
,
tilesY
,
true
,
dbg_prefix
+
"-fgbg"
,
dbg_titles
);
}
/*
final boolean [] is_bg = (is_bg_in != null) ? is_bg_in : new boolean [img_size];
if (is_bg_in == null) { Arrays.fill(is_bg, true);}
final boolean [] is_fg = (is_fg_in != null) ? is_fg_in : new boolean [img_size];
if (is_fg_in == null) { Arrays.fill(is_fg, true);}
final double [][] gvars_same = new double [num_slices][];
final double [][] gvars_inter = new double [num_slices][];
*/
final
TileNeibs
pn
=
new
TileNeibs
(
width
,
height
);
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
final
int
fnslice
=
nslice
;
gvars_same
[
fnslice
]
=
new
double
[
img_size
];
gvars_inter
[
fnslice
]
=
new
double
[
img_size
];
final
double
[]
combo_texture
=
gcombo_texture
[
fnslice
];
final
double
[]
vars_same
=
gvars_same
[
fnslice
];
// new double [img_size];
final
double
[]
vars_inter
=
gvars_inter
[
fnslice
];
// new double [img_size];
final
double
[]
vars_ratio
=
new
double
[
img_size
];
final
double
[]
vars_dir_initial
=
new
double
[
img_size
];
final
double
[]
dirs_initial
=
new
double
[
img_size
];
final
double
[]
vars_dir_final
=
new
double
[
img_size
];
final
double
[]
dirs_final
=
new
double
[
img_size
];
final
double
[]
dirs_len
=
new
double
[
img_size
];
final
double
[]
vars_dir_ratio
=
new
double
[
img_size
];
final
double
[]
dirs_avg
=
new
double
[
img_size
];
final
double
[]
dbg_is_fg
=
(
dbg_prefix
!=
null
)
?
new
double
[
img_size
]
:
null
;
System
.
arraycopy
(
combo_texture
,
0
,
dirs_avg
,
0
,
img_size
);
Arrays
.
fill
(
vars_same
,
Double
.
NaN
);
Arrays
.
fill
(
vars_inter
,
Double
.
NaN
);
Arrays
.
fill
(
vars_ratio
,
Double
.
NaN
);
System
.
arraycopy
(
vars_inter
,
0
,
vars_dir_initial
,
0
,
img_size
);
Arrays
.
fill
(
dirs_initial
,
Double
.
NaN
);
Arrays
.
fill
(
dirs_final
,
Double
.
NaN
);
Arrays
.
fill
(
dirs_len
,
Double
.
NaN
);
if
(
dbg_is_fg
!=
null
)
Arrays
.
fill
(
dbg_is_fg
,
Double
.
NaN
);
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
cindx
=
ai
.
getAndIncrement
();
cindx
<
img_size
;
cindx
=
ai
.
getAndIncrement
())
if
(!
Double
.
isNaN
(
combo_texture
[
cindx
]))
{
int
y0
=
cindx
/
width
;
int
x0
=
cindx
%
width
;
double
var_same
=
Double
.
NaN
;
double
var_inter
=
Double
.
NaN
;
// calculate weighted variance
double
sw
=
0.0
,
swd
=
0.0
,
swd2
=
0.0
;
for
(
int
dvy
=
-
ivar_radius
;
dvy
<=
ivar_radius
;
dvy
++)
{
for
(
int
dvx
=
-
ivar_radius
;
dvx
<=
ivar_radius
;
dvx
++)
{
int
indx
=
pn
.
getIndex
(
x0
+
dvx
,
y0
+
dvy
);
if
((
indx
>=
0
)
&&
!
Double
.
isNaN
(
combo_texture
[
indx
]))
{
double
w
=
var_weights
[
Math
.
abs
(
dvy
)][
Math
.
abs
(
dvx
)];
// 1.0;
double
d
=
combo_texture
[
indx
];
sw
+=
w
;
swd
+=
w
*
d
;
swd2
+=
w
*
d
*
d
;
}
}
}
if
(
sw
>
0.0
)
{
// always
double
avg
=
swd
/
sw
;
double
avg2
=
swd2
/
sw
;
var_same
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
vars_same
[
cindx
]
=
var_same
;
}
// calculate inter-sensor variance (add local normalization?)
sw
=
0.0
;
swd
=
0.0
;
swd2
=
0.0
;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
double
w
=
1.0
;
double
d
=
sensor_texture
[
fnslice
][
nsens
][
cindx
];
sw
+=
w
;
swd
+=
w
*
d
;
swd2
+=
w
*
d
*
d
;
}
if
(
sw
>
0.0
)
{
// always
double
avg
=
swd
/
sw
;
double
avg2
=
swd2
/
sw
;
var_inter
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
vars_inter
[
cindx
]
=
var_inter
;
}
vars_ratio
[
cindx
]
=
var_same
/
var_inter
;
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
System
.
arraycopy
(
vars_inter
,
0
,
vars_dir_final
,
0
,
img_size
);
System
.
arraycopy
(
vars_ratio
,
0
,
vars_dir_ratio
,
0
,
img_size
);
final
int
dir_samples
=
(
2
*
idir_radius
+
1
)
*
(
2
*
idir_radius
+
1
);
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
double
[]
dirvar
=
new
double
[
num_sensors
];
double
[]
sw
=
new
double
[
dir_samples
];
double
[]
swd
=
new
double
[
dir_samples
];
double
[]
swd2
=
new
double
[
dir_samples
];
for
(
int
cindx
=
ai
.
getAndIncrement
();
cindx
<
img_size
;
cindx
=
ai
.
getAndIncrement
())
// is_fg_tile[fnslice][tile]
if
(!
Double
.
isNaN
(
combo_texture
[
cindx
]))
{
int
y0
=
cindx
/
width
;
int
x0
=
cindx
%
width
;
int
tileX
=
x0
/
transform_size
;
int
tileY
=
y0
/
transform_size
;
int
tile
=
tileX
+
tilesX
*
tileY
;
if
(
dbg_is_fg
!=
null
)
{
dbg_is_fg
[
cindx
]
=
(
is_fg_tile
[
fnslice
][
tile
]?
2
:
0
)
+
(
has_bg_tile
[
fnslice
][
tile
]?
1
:
0
);
}
// only trim if nothing obscures this and has some BG
if
(
is_fg_tile
[
fnslice
][
tile
]
&&
has_bg_tile
[
fnslice
][
tile
])
{
if
(
dbg_is_fg
!=
null
)
{
dbg_is_fg
[
cindx
]
=
1000.0
;
}
if
(
vars_inter
[
cindx
]
>
fg_max_inter
)
{
dirs_avg
[
cindx
]
=
Double
.
NaN
;
}
}
else
if
(
vars_inter
[
cindx
]
>
try_dir_var
)
{
// try obscuring by others
Arrays
.
fill
(
sw
,
0.0
);
Arrays
.
fill
(
swd
,
0.0
);
Arrays
.
fill
(
swd2
,
0.0
);
for
(
int
dvy
=
-
idir_radius
;
dvy
<=
idir_radius
;
dvy
++)
{
for
(
int
dvx
=
-
idir_radius
;
dvx
<=
idir_radius
;
dvx
++)
{
int
pindx
=
pn
.
getIndex
(
x0
+
dvx
,
y0
+
dvy
);
if
((
pindx
>=
0
)
&&
!
Double
.
isNaN
(
combo_texture
[
pindx
]))
{
int
vindx
=
(
dvy
+
idir_radius
)
*
(
2
*
idir_radius
+
1
)
+
(
dvx
+
idir_radius
);
for
(
int
nsens
=
0
;
nsens
<
dir_num_start
;
nsens
++)
{
double
w
=
1.0
;
double
d
=
sensor_texture
[
fnslice
][
nsens
][
pindx
];
sw
[
vindx
]
+=
w
;
swd
[
vindx
]
+=
w
*
d
;
swd2
[
vindx
]
+=
w
*
d
*
d
;
}
}
}
}
double
svw
=
0.0
,
svwd
=
0.0
;
for
(
int
start_dir
=
0
;
start_dir
<
num_sensors
;
start_dir
++)
{
for
(
int
dvy
=
-
idir_radius
;
dvy
<=
idir_radius
;
dvy
++)
{
for
(
int
dvx
=
-
idir_radius
;
dvx
<=
idir_radius
;
dvx
++)
{
int
vindx
=
(
dvy
+
idir_radius
)
*
(
2
*
idir_radius
+
1
)
+
(
dvx
+
idir_radius
);
if
(
sw
[
vindx
]
>
0.0
)
{
double
avg
=
swd
[
vindx
]/
sw
[
vindx
];
double
avg2
=
swd2
[
vindx
]/
sw
[
vindx
];
double
v
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
double
w
=
dir_weights
[
Math
.
abs
(
dvy
)][
Math
.
abs
(
dvx
)];
svw
+=
w
;
svwd
+=
w
*
v
;
}
}
}
dirvar
[
start_dir
]
=
svwd
/
svw
;
// weighted
if
(
start_dir
==
(
num_sensors
-
1
))
{
break
;
}
// remove previous values pointed by start_dir
// and add new values pointed by start_dir+dir_num_start
for
(
int
dvy
=
-
idir_radius
;
dvy
<=
idir_radius
;
dvy
++)
{
for
(
int
dvx
=
-
idir_radius
;
dvx
<=
idir_radius
;
dvx
++)
{
int
pindx
=
pn
.
getIndex
(
x0
+
dvx
,
y0
+
dvy
);
if
((
pindx
>=
0
)
&&
!
Double
.
isNaN
(
combo_texture
[
pindx
]))
{
int
vindx
=
(
dvy
+
idir_radius
)
*
(
2
*
idir_radius
+
1
)
+
(
dvx
+
idir_radius
);
double
w0
=
1.0
;
double
d0
=
sensor_texture
[
fnslice
][
start_dir
][
pindx
];
sw
[
vindx
]
-=
w0
;
swd
[
vindx
]
-=
w0
*
d0
;
swd2
[
vindx
]
-=
w0
*
d0
*
d0
;
int
dir1
=
(
start_dir
+
dir_num_start
)
%
num_sensors
;
double
w1
=
1.0
;
sw
[
vindx
]
+=
w1
;
double
d1
=
sensor_texture
[
fnslice
][
dir1
][
pindx
];
swd
[
vindx
]
+=
w1
*
d1
;
swd2
[
vindx
]
+=
w1
*
d1
*
d1
;
}
}
}
}
// find best direction
int
best_dir
=
0
;
for
(
int
dir
=
1
;
dir
<
num_sensors
;
dir
++)
{
if
(
dirvar
[
dir
]
<
dirvar
[
best_dir
])
{
best_dir
=
dir
;
}
}
double
center_dir
=
best_dir
+
0.5
*
(
dir_num_start
-
1
);
if
(
center_dir
>=
num_sensors
)
{
center_dir
-=
num_sensors
;
}
vars_dir_initial
[
cindx
]
=
dirvar
[
best_dir
];
dirs_initial
[
cindx
]
=
center_dir
;
// recalculate variance for the same direction but maybe different number of sensors
// dir_num_restart
// Use only center pixel, do not average variance
int
dir_start
=
(
int
)
Math
.
round
(
center_dir
-
0.5
*
(
dir_num_restart
-
1
));
if
(
dir_start
<
0
)
{
dir_start
+=
num_sensors
;
}
double
scw
=
0.0
,
scwd
=
0.0
,
scwd2
=
0.0
;
for
(
int
i
=
0
;
i
<
dir_num_restart
;
i
++)
{
int
dir
=
dir_start
+
i
;
if
(
dir
>=
num_sensors
)
{
dir
-=
num_sensors
;
}
double
w
=
1.0
;
double
d
=
sensor_texture
[
fnslice
][
dir
][
cindx
];
scw
+=
w
;
scwd
+=
w
*
d
;
scwd2
+=
w
*
d
*
d
;
}
double
avg
=
scwd
/
scw
;
double
avg2
=
scwd2
/
scw
;
double
dir_var
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
double
max_var
=
Math
.
min
(
dir_var_max
,
dir_var
*(
1.0
+
dir_worsen_rel
));
// add sensors from both ends (which is better) while variance stays below max_var
int
dir_len
;
for
(
dir_len
=
dir_num_start
;
dir_len
<
num_sensors
;
dir_len
++)
{
// try CCW
int
nsens0
=
dir_start
-
1
;
//) % num_sensors;
if
(
nsens0
<
0
)
{
nsens0
+=
num_sensors
;
}
double
w
=
1.0
;
double
d
=
sensor_texture
[
fnslice
][
nsens0
][
cindx
];
double
sw_0
=
scw
+
w
;
double
swd_0
=
scwd
+
w
*
d
;
double
swd2_0
=
scwd2
+
w
*
d
*
d
;
avg
=
swd_0
/
sw_0
;
avg2
=
swd2_0
/
sw_0
;
double
var_0
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
// try CW
int
nsens1
=
dir_start
+
dir_len
;
if
(
nsens1
>=
num_sensors
)
{
nsens1
-=
num_sensors
;
}
w
=
1.0
;
d
=
sensor_texture
[
fnslice
][
nsens1
][
cindx
];
double
sw_1
=
scw
+
w
;
double
swd_1
=
scwd
+
w
*
d
;
double
swd2_1
=
scwd2
+
w
*
d
*
d
;
avg
=
swd_1
/
sw_1
;
avg2
=
swd2_1
/
sw_1
;
double
var_1
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
if
(
Math
.
min
(
var_0
,
var_1
)
>
max_var
)
{
break
;
}
if
(
var_0
<
var_1
)
{
dir_start
=
nsens0
;
scw
=
sw_0
;
scwd
=
swd_0
;
scwd2
=
swd2_0
;
dir_var
=
var_0
;
}
else
{
// dir_start stays the same
scw
=
sw_1
;
scwd
=
swd_1
;
scwd2
=
swd2_1
;
dir_var
=
var_1
;
}
}
double
dir_avg
=
scwd
/
scw
;
double
ddir
=
dir_start
+
0.5
*
(
dir_len
-
1
);
if
(
ddir
>=
num_sensors
)
{
ddir
-=
num_sensors
;
}
// fill arrays
dirs_final
[
cindx
]
=
ddir
;
dirs_len
[
cindx
]
=
dir_len
;
vars_dir_final
[
cindx
]
=
dir_var
;
vars_dir_ratio
[
cindx
]
=
vars_same
[
cindx
]/
dir_var
;
dirs_avg
[
cindx
]
=
dir_avg
;
}
// } else if (vars_inter[cindx] > try_dir_var) { // try obscuring by others
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
if
(
dbg_prefix
!=
null
)
{
double
[][]
dbg_img
=
{
vars_same
,
vars_inter
,
vars_dir_initial
,
vars_dir_final
,
dirs_initial
,
dirs_final
,
dirs_len
,
vars_ratio
,
vars_dir_ratio
,
dbg_is_fg
,
combo_texture
,
dirs_avg
,
sensor_texture
[
fnslice
][
0
],
sensor_texture
[
fnslice
][
1
],
sensor_texture
[
fnslice
][
2
],
sensor_texture
[
fnslice
][
3
],
sensor_texture
[
fnslice
][
4
],
sensor_texture
[
fnslice
][
5
],
sensor_texture
[
fnslice
][
6
],
sensor_texture
[
fnslice
][
7
],
sensor_texture
[
fnslice
][
8
],
sensor_texture
[
fnslice
][
9
],
sensor_texture
[
fnslice
][
10
],
sensor_texture
[
fnslice
][
11
],
sensor_texture
[
fnslice
][
12
],
sensor_texture
[
fnslice
][
13
],
sensor_texture
[
fnslice
][
14
],
sensor_texture
[
fnslice
][
15
]
};
String
[]
dbg_titles
=
{
"VAR_SAME"
,
"VAR_INTER"
,
"VAR_DIR_INITIAL"
,
"VAR_DIR_FINAL"
,
"DIR_INITIAL"
,
"DIR_FINAL"
,
"LEN"
,
"VAR_RATIO"
,
"DIR_RATIO"
,
"IS_FG"
,
"COMBO_TEXTURE"
,
"OUT_TEXTURE"
,
"T00"
,
"T01"
,
"T02"
,
"T03"
,
"T04"
,
"T05"
,
"T06"
,
"T07"
,
"T08"
,
"T09"
,
"T10"
,
"T11"
,
"T12"
,
"T13"
,
"T14"
,
"T15"
};
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
width
,
height
,
true
,
dbg_prefix
+
"-textures-"
+
fnslice
,
dbg_titles
);
}
out_textures
[
fnslice
]
=
dirs_avg
;
}
return
out_textures
;
}
public
static
ImagePlus
[]
getInterCombinedTexturesNew
(
// return ImagePlus[] matching tileClusters[], with alpha
final
CLTParameters
clt_parameters
,
...
...
@@ -1371,12 +1926,10 @@ public class TexturedModel {
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
// weighted sum
double
[][][][][]
inter_textures_wd
=
new
double
[
num_slices
][
tilesY
][
tilesX
][][];
// [channel][64] - overlapping textures
// weighted sum of squares
double
[][][][][]
inter_textures_wd2
=
new
double
[
num_slices
][
tilesY
][
tilesX
][][];
// [channel][64] - overlapping textures
/// double [][][][][] inter_textures_wd2= new double [num_slices][tilesY][tilesX][][]; // [channel][64] - overlapping textures
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
][];
...
...
@@ -1396,8 +1949,10 @@ public class TexturedModel {
}
final
int
num_sensors
=
parameter_scene
.
getNumSensors
();
final
int
num_colors
=
parameter_scene
.
isMonochrome
()?
1
:
3
;
final
int
num_colors
=
parameter_scene
.
isMonochrome
()?
1
:
3
;
final
double
[][][]
sensor_textures
=
new
double
[
num_slices
][
num_sensors
][];
final
double
[][]
combo_textures
=
new
double
[
num_slices
][];
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
;
...
...
@@ -1466,7 +2021,7 @@ public class TexturedModel {
true
,
//keep_channels, // final boolean keep_channels,
debug_level
);
// final int debugLevel);
if
(
slice_texture88
!=
null
)
{
if
(
slice_texture88
!=
null
)
{
// will just accumulate
// Use MB vectors for texture weights
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
...
...
@@ -1491,13 +2046,13 @@ public class TexturedModel {
inter_weights
[
fnslice
][
tileY
][
tileX
]
+=
w
;
if
(
inter_textures_wd
[
fnslice
][
tileY
][
tileX
]
==
null
)
{
// create if it did not exist
inter_textures_wd
[
fnslice
][
tileY
][
tileX
]
=
new
double
[
slice_texture88
[
tileY
][
tileX
].
length
+
num_colors
][
slice_texture88
[
tileY
][
tileX
][
0
].
length
];
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
]
=
new
double
[
slice_texture88
[
tileY
][
tileX
].
length
+
num_colors
][
slice_texture88
[
tileY
][
tileX
][
0
].
length
];
///
inter_textures_wd2[fnslice][tileY][tileX] = new double [slice_texture88[tileY][tileX].length + num_colors][slice_texture88[tileY][tileX][0].length];
}
for
(
int
nchn
=
0
;
nchn
<
slice_texture88
[
tileY
][
tileX
].
length
;
nchn
++)
{
for
(
int
i
=
0
;
i
<
slice_texture88
[
tileY
][
tileX
][
nchn
].
length
;
i
++)
{
double
d
=
slice_texture88
[
tileY
][
tileX
][
nchn
][
i
];
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
+=
w
*
d
;
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
+=
w
*
d
*
d
;
///
inter_textures_wd2[fnslice][tileY][tileX][nchn][i] += w * d *d;
}
}
}
...
...
@@ -1521,13 +2076,25 @@ public class TexturedModel {
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
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
(
THREADS_MAX
);
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
nslice
=
0
;
nslice
<
num_slices
;
nslice
++)
{
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
sensor_textures
[
nslice
][
nsens
]
=
new
double
[
width
*
height
];
Arrays
.
fill
(
sensor_textures
[
nslice
][
nsens
],
Double
.
NaN
);
}
combo_textures
[
nslice
]
=
new
double
[
width
*
height
];
Arrays
.
fill
(
combo_textures
[
nslice
],
Double
.
NaN
);
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
);
// 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
()
{
...
...
@@ -1542,38 +2109,54 @@ public class TexturedModel {
for
(
int
nchn
=
0
;
nchn
<
inter_textures_wd
[
fnslice
][
tileY
][
tileX
].
length
-
num_colors
;
nchn
++)
{
for
(
int
i
=
0
;
i
<
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
nchn
].
length
;
i
++)
{
double
d
=
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
*
w
;
// average
double
d2
=
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
*
w
;
// average of squared
///
double d2= inter_textures_wd2[fnslice][tileY][tileX][nchn][i] * w; // average of squared
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
=
d
;
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
nchn
][
i
]
=
Math
.
sqrt
(
d2
-
d
*
d
);
///
inter_textures_wd2[fnslice][tileY][tileX][nchn][i] = Math.sqrt(d2- d * d);
}
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
int
navg
=
inter_textures_wd
[
fnslice
][
tileY
][
tileX
].
length
-
num_colors
+
ncol
;
for
(
int
i
=
0
;
i
<
tile_len
;
i
++)
{
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
navg
][
i
]
=
0
;
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
navg
][
i
]
=
0
;
///
inter_textures_wd2[fnslice][tileY][tileX][navg][i] = 0;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
navg
][
i
]
+=
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
1
+
(
nsens
+
1
)
*
num_colors
][
i
]/
num_sensors
;
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
navg
][
i
]
+=
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
1
+
(
nsens
+
1
)
*
num_colors
][
i
]/
num_sensors
;
///
inter_textures_wd2[fnslice][tileY][tileX][navg][i] +=
///
inter_textures_wd2[fnslice][tileY][tileX][1 + (nsens + 1) * num_colors][i]/num_sensors;
}
}
}
// important that texture is not overlapped here!
for
(
int
row
=
0
;
row
<
transform_size
;
row
++)
{
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
System
.
arraycopy
(
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
num_colors
*
(
nsens
+
1
)
+
1
+
y_color
],
row
*
transform_size
,
sensor_textures
[
fnslice
][
nsens
]
,
// dbg_textures[n],
(
tileY
*
transform_size
+
row
)
*
width
+
(
tileX
*
transform_size
),
transform_size
);
}
int
navg
=
inter_textures_wd
[
fnslice
][
tileY
][
tileX
].
length
-
num_colors
+
y_color
;
System
.
arraycopy
(
inter_textures_wd
[
fnslice
][
tileY
][
tileX
][
navg
],
row
*
transform_size
,
combo_textures
[
fnslice
]
,
// dbg_textures[n],
(
tileY
*
transform_size
+
row
)
*
width
+
(
tileX
*
transform_size
),
transform_size
);
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
/*
// debug-display this slice here
if (debug_level > -10) {
int
var_radius
=
3
;
double
try_dir_var
=
30.0
;
// try directional if the intersensor variance exceeds this value
int
dir_num_start
=
5
;
// start with this number of consecutive sensors
double
dir_worsen_rel
=
0.15
;
// add more sensors until variance grows by this relative
double
dir_var_max
=
20.0
;
// do not add more sensors if the variance would exceed this
int dbg_slices = num_colors + 1 +num_colors*num_sensors + num_colors;
int dbg_width = tilesX * transform_size;
int dbg_height = tilesY * transform_size;
...
...
@@ -1611,313 +2194,63 @@ public class TexturedModel {
dbg_textures[n],
(tileY * transform_size + row) * dbg_width + (tileX * transform_size),
transform_size);
System
.
arraycopy
(
inter_textures_wd2
[
fnslice
][
tileY
][
tileX
][
n
],
row
*
transform_size
,
dbg_textures2
[
n
],
(
tileY
*
transform_size
+
row
)
*
dbg_width
+
(
tileX
*
transform_size
),
transform_size
);
///
System.arraycopy(
///
inter_textures_wd2[fnslice][tileY][tileX][n],
///
row*transform_size,
///
dbg_textures2[n],
///
(tileY * transform_size + row) * dbg_width + (tileX * transform_size),
///
transform_size);
}
}
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures
,
dbg_width
,
dbg_height
,
true
,
ref_scene
.
getImageName
()+
"-combined_textures88-"
+
String
.
format
(
"%02d"
,
nslice
),
dbg_titles
);
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures2
,
dbg_width
,
dbg_height
,
true
,
ref_scene
.
getImageName
()+
"-combined_textures88-rmse-"
+
String
.
format
(
"%02d"
,
nslice
),
dbg_titles
);
// get variance-same, variance-inter, variance-seme/variance-inter
tindx
=
0
;
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"C"
+
ncol
;
}
dbg_titles_v
[
tindx
++]
=
"ALPHA"
;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"T"
+
nsens
+((
num_colors
>
1
)?(
":"
+
ncol
):
""
);
}
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"AVG"
+((
num_colors
>
1
)?(
ncol
):
""
);
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"VAR_SAME"
+((
num_colors
>
1
)?(
ncol
):
""
);
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"VAR_INTER"
+((
num_colors
>
1
)?(
ncol
):
""
);
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"VAR_RATIO"
+((
num_colors
>
1
)?(
ncol
):
""
);
}
// debugging BG pixels obscured by the FG ones
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"DIR"
+((
num_colors
>
1
)?(
ncol
):
""
);
// direction (center, step 0.5)
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"LEN"
+((
num_colors
>
1
)?(
ncol
):
""
);
// number of consecutive sensors
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"DIRTEX"
+((
num_colors
>
1
)?(
ncol
):
""
);
// average texture value with subset of sensors
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"DIRVAR"
+((
num_colors
>
1
)?(
ncol
):
""
);
// variance for the subset of sensors
}
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
dbg_titles_v
[
tindx
++]
=
"DIRRATIO"
+((
num_colors
>
1
)?(
ncol
):
""
);
// ratio of space variance to directional variance
}
for
(
int
n
=
0
;
n
<
dbg_slices
;
n
++)
{
dbg_textures_v
[
n
]
=
dbg_textures
[
n
];
}
for
(
int
n
=
dbg_slices
;
n
<
dbg_slices_v
;
n
++)
{
dbg_textures_v
[
n
]
=
new
double
[
dbg_width
*
dbg_height
];
Arrays
.
fill
(
dbg_textures_v
[
n
],
Double
.
NaN
);
}
final
TileNeibs
pn
=
new
TileNeibs
(
tilesX
*
transform_size
,
tilesY
*
transform_size
);
for
(
int
ncol
=
0
;
ncol
<
num_colors
;
ncol
++)
{
final
int
indx_mean
=
num_colors
+
1
+
num_sensors
*
num_colors
;
// average of channels // ncol; //
final
int
indx_chn0
=
num_colors
+
1
+
ncol
;
// + nsens*num_colors
final
int
indx_var_same
=
num_colors
+
1
+
num_sensors
*
num_colors
+
1
+
ncol
;
final
int
indx_var_inter
=
indx_var_same
+
num_colors
;
final
int
indx_var_ratio
=
indx_var_inter
+
num_colors
;
final
int
indx_dir
=
indx_var_ratio
+
1
*
num_colors
;
final
int
indx_len
=
indx_var_ratio
+
2
*
num_colors
;
final
int
indx_dir_tex
=
indx_var_ratio
+
3
*
num_colors
;
final
int
indx_dir_var
=
indx_var_ratio
+
4
*
num_colors
;
final
int
indx_dir_ratio
=
indx_var_ratio
+
5
*
num_colors
;
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
;
for
(
int
dy
=
0
;
dy
<
transform_size
;
dy
++)
{
int
y0
=
tileY
*
transform_size
+
dy
;
for
(
int
dx
=
0
;
dx
<
transform_size
;
dx
++)
{
int
x0
=
tileX
*
transform_size
+
dx
;
int
indx0
=
pn
.
getIndex
(
x0
,
y0
);
double
var_same
=
Double
.
NaN
;
double
var_inter
=
Double
.
NaN
;
if
((
indx0
>=
0
)
&&
!
Double
.
isNaN
(
dbg_textures_v
[
indx_mean
][
indx0
]))
{
// calculate unweighted variance
double
sw
=
0.0
,
swd
=
0.0
,
swd2
=
0.0
;
for
(
int
dvy
=
-
var_radius
;
dvy
<=
var_radius
;
dvy
++)
{
for
(
int
dvx
=
-
var_radius
;
dvx
<=
var_radius
;
dvx
++)
{
int
indx
=
pn
.
getIndex
(
x0
+
dvx
,
y0
+
dvy
);
if
((
indx
>=
0
)
&&
!
Double
.
isNaN
(
dbg_textures_v
[
indx_mean
][
indx
]))
{
double
w
=
1.0
;
double
d
=
dbg_textures_v
[
indx_mean
][
indx
];
sw
+=
w
;
swd
+=
w
*
d
;
swd2
+=
w
*
d
*
d
;
}
}
}
if
(
sw
>
0.0
)
{
// always
double
avg
=
swd
/
sw
;
double
avg2
=
swd2
/
sw
;
var_same
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
dbg_textures_v
[
indx_var_same
][
indx0
]
=
var_same
;
}
// calculate inter-sensor variance (add local normalization?)
sw
=
0.0
;
swd
=
0.0
;
swd2
=
0.0
;
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
double
w
=
1.0
;
double
d
=
dbg_textures_v
[
indx_chn0
+
nsens
*
num_colors
][
indx0
];
sw
+=
w
;
swd
+=
w
*
d
;
swd2
+=
w
*
d
*
d
;
}
if
(
sw
>
0.0
)
{
// always
double
avg
=
swd
/
sw
;
double
avg2
=
swd2
/
sw
;
var_inter
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
dbg_textures_v
[
indx_var_inter
][
indx0
]
=
var_inter
;
}
dbg_textures_v
[
indx_var_ratio
][
indx0
]
=
var_same
/
var_inter
;
// try to improve var_inter for BG tiles by selecting sensor to look behind from one side
dbg_textures_v
[
indx_dir_tex
][
indx0
]
=
dbg_textures_v
[
indx_mean
][
indx0
];
dbg_textures_v
[
indx_dir_var
][
indx0
]
=
var_inter
;
dbg_textures_v
[
indx_dir_ratio
][
indx0
]
=
var_same
/
var_inter
;
double
[]
dirvar
=
new
double
[
num_sensors
];
// extract to a separate method
// move color to outer cycle
// pass color-dependent array of relevant slices
// calculate array of variances dependent on dir_start and
// dir_len, and mix them according to neighbor weights, then find
// the best dir and length. Then use only for the center pixel.
// For BG tiles - only change Y, keep alpha = 1.0, for FG - cut transparent and maybe remove texture tiles at all?
if
(
var_inter
>
try_dir_var
)
{
sw
=
0.0
;
swd
=
0.0
;
swd2
=
0.0
;
for
(
int
i
=
0
;
i
<
dir_num_start
;
i
++)
{
double
w
=
1.0
;
double
d
=
dbg_textures_v
[
indx_chn0
+
i
*
num_colors
][
indx0
];
sw
+=
w
;
swd
+=
w
*
d
;
swd2
+=
w
*
d
*
d
;
}
double
[]
sw_dir
=
new
double
[
num_sensors
];
double
[]
swd_dir
=
new
double
[
num_sensors
];
double
[]
swd2_dir
=
new
double
[
num_sensors
];
for
(
int
nsens
=
0
;
nsens
<
num_sensors
;
nsens
++)
{
double
avg
=
swd
/
sw
;
double
avg2
=
swd2
/
sw
;
dirvar
[
nsens
]
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
sw_dir
[
nsens
]
=
sw
;
swd_dir
[
nsens
]
=
swd
;
swd2_dir
[
nsens
]
=
swd2
;
double
w0
=
1.0
;
double
d0
=
dbg_textures_v
[
indx_chn0
+
nsens
*
num_colors
][
indx0
];
sw
-=
w0
;
swd
-=
w0
*
d0
;
swd2
-=
w0
*
d0
*
d0
;
int
nsens1
=
(
nsens
+
dir_num_start
)
%
num_sensors
;
double
w1
=
1.0
;
double
d1
=
dbg_textures_v
[
indx_chn0
+
nsens1
*
num_colors
][
indx0
];
sw
+=
w1
;
swd
+=
w1
*
d1
;
swd2
+=
w1
*
d1
*
d1
;
}
int
dir_best
=
0
;
// start of consecutive sensor numbers
for
(
int
i
=
1
;
i
<
num_sensors
;
i
++)
{
if
(
dirvar
[
i
]
<
dirvar
[
dir_best
])
{
dir_best
=
i
;
}
}
// now try to increase number of averaged sensors
// try forward and backward, select best, verify it fits.
double
dir_var
=
dirvar
[
dir_best
];
double
max_var
=
Math
.
min
(
dir_var_max
,
dir_var
*(
1.0
+
dir_worsen_rel
));
sw
=
sw_dir
[
dir_best
];
swd
=
swd_dir
[
dir_best
];
swd2
=
swd2_dir
[
dir_best
];
int
dir_start
=
dir_best
;
int
dir_len
;
for
(
dir_len
=
dir_num_start
;
dir_len
<
num_sensors
;
dir_len
++)
{
int
nsens0
=
dir_start
-
1
;
//) % num_sensors;
if
(
nsens0
<
0
)
{
nsens0
+=
num_sensors
;
}
double
w
=
1.0
;
double
d
=
dbg_textures_v
[
indx_chn0
+
nsens0
*
num_colors
][
indx0
];
double
sw_0
=
sw
+
w
;
double
swd_0
=
swd
+
w
*
d
;
double
swd2_0
=
swd2
+
w
*
d
*
d
;
double
avg
=
swd_0
/
sw_0
;
double
avg2
=
swd2_0
/
sw_0
;
double
var_0
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
int
nsens1
=
dir_start
+
dir_len
;
if
(
nsens1
>=
num_sensors
)
{
nsens1
-=
num_sensors
;
}
w
=
1.0
;
d
=
dbg_textures_v
[
indx_chn0
+
nsens1
*
num_colors
][
indx0
];
double
sw_1
=
sw
+
w
;
double
swd_1
=
swd
+
w
*
d
;
double
swd2_1
=
swd2
+
w
*
d
*
d
;
avg
=
swd_1
/
sw_1
;
avg2
=
swd2_1
/
sw_1
;
double
var_1
=
Math
.
sqrt
(
avg2
-
avg
*
avg
);
if
(
Math
.
min
(
var_0
,
var_1
)
>
max_var
)
{
break
;
}
if
(
var_0
<
var_1
)
{
dir_start
=
nsens0
;
sw
=
sw_0
;
swd
=
swd_0
;
swd2
=
swd2_0
;
dir_var
=
var_0
;
}
else
{
// dir_start stays the same
sw
=
sw_1
;
swd
=
swd_1
;
swd2
=
swd2_1
;
dir_var
=
var_1
;
}
}
double
dir_avg
=
swd
/
sw
;
double
ddir
=
dir_start
+
0.5
*
(
dir_len
-
1
);
if
(
ddir
>=
num_sensors
)
{
ddir
-=
num_sensors
;
}
// fill arrays
dbg_textures_v
[
indx_dir
][
indx0
]
=
ddir
;
dbg_textures_v
[
indx_len
][
indx0
]
=
dir_len
;
dbg_textures_v
[
indx_dir_tex
][
indx0
]
=
dir_avg
;
dbg_textures_v
[
indx_dir_var
][
indx0
]
=
dir_var
;
dbg_textures_v
[
indx_dir_ratio
][
indx0
]
=
var_same
/
dir_var
;
}
}
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
ShowDoubleFloatArrays
.
showArrays
(
dbg_textures_v
,
dbg_width
,
dbg_height
,
true
,
ref_scene
.
getImageName
()+
"-textures88-variances-"
+
String
.
format
(
"%02d"
,
nslice
),
dbg_titles_v
);
}
}
// 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_colors+1), // 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_colors+1), //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_colors+1)+i] = non_overlap[i];
int ncol = 0; // 2 for color
double [][] sensor_texture = new double [num_sensors][];
for (int nsens = 0; nsens < num_sensors; nsens++){
sensor_texture[nsens] = dbg_textures[num_colors + 1 + ncol + nsens * num_colors];
}
// nslice
double [] processed_texture = processTexture(
clt_parameters, // final CLTParameters clt_parameters,
tilesX, // final int tilesX,
sensor_texture, // final double [][] sensor_texture, // per-sensor texture value
null, // final double [] combo_texture_in, // average texture value
null, // final boolean [] is_bg_in, // pixel may be background - try to look from one side
null, // final boolean [] is_fg_in, // pixel is foreground - generate transparency (just NaN here?)
ref_scene.getImageName()+"-"+nslice); // final String dbg_prefix);
}
*/
}
// 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)
}
/*
for (int nslice = 0; nslice < num_slices; nslice++) {
final double [] disparity_ref = tileClusters[nslice].getDisparity(); // disparity in the reference view tiles (Double.NaN - invalid)
double [] processed_texture = processTexture(
clt_parameters, // final CLTParameters clt_parameters,
tilesX, // final int tilesX,
sensor_textures[nslice], // final double [][] sensor_texture, // per-sensor texture value
combo_textures[nslice], // null, // final double [] combo_texture_in, // average texture value
null, // final boolean [] is_bg_in, // pixel may be background - try to look from one side
null, // final boolean [] is_fg_in, // pixel is foreground - generate transparency (just NaN here?)
ref_scene.getImageName()+"-"+nslice); // final String dbg_prefix);
}
*/
double
[][]
processed_textures
=
processTexture
(
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
combo_textures
,
// null, // final double [] combo_texture_in, // average texture value
ref_scene
.
getImageName
());
// final String dbg_prefix);
if
(
debug_level
>
-
1000
)
{
return
null
;
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileNeibs.java
View file @
57fb1ef9
...
...
@@ -117,7 +117,7 @@ public class TileNeibs{
}
/**
* Get
2d element index after step N, NE, ... NW. Returns -1 if leaving array
* Get
element index offset by dx and dy from the indx
* @param indx start index
* @param dx offset in x direction
* @param dy offset in y direction
...
...
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