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
29e261ef
Commit
29e261ef
authored
Mar 26, 2024
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding filtering by absolute contrast
parent
6cbc4b32
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
273 additions
and
4 deletions
+273
-4
ObjectLocation.java
...in/java/com/elphel/imagej/orthomosaic/ObjectLocation.java
+1
-1
OrthoMap.java
src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java
+244
-0
OrthoMapsCollection.java
...va/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java
+28
-3
No files found.
src/main/java/com/elphel/imagej/orthomosaic/ObjectLocation.java
View file @
29e261ef
...
@@ -777,7 +777,7 @@ public class ObjectLocation {
...
@@ -777,7 +777,7 @@ public class ObjectLocation {
}
}
// min_weight = 10.0
// min_weight = 10.0
// Starting from very center remove farthe
r
st (first or last) pixel,
// Starting from very center remove farthest (first or last) pixel,
// until remaining weight drops below min_weight or sw0[]*(1-frac_outliers).
// until remaining weight drops below min_weight or sw0[]*(1-frac_outliers).
// weight of the previous radius may fall also, but likely not too much
// weight of the previous radius may fall also, but likely not too much
for
(
int
nr
=
1
;
nr
<
sw
.
length
;
nr
++)
{
for
(
int
nr
=
1
;
nr
<
sw
.
length
;
nr
++)
{
...
...
src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java
View file @
29e261ef
...
@@ -18,6 +18,8 @@ import java.time.LocalDateTime;
...
@@ -18,6 +18,8 @@ import java.time.LocalDateTime;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Properties
;
...
@@ -1855,6 +1857,248 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
...
@@ -1855,6 +1857,248 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return
convolved
;
return
convolved
;
}
}
/**
* Calculate absolute contrast of the pattern
* @param data extracted square image with the object exactly
* in the center
* @param ipattern square pattern array corresponding to data. 1 means
* average (w/o outliers) and add, 2 - average and subtract
* @param outliers_frac - fraction of outliers to remove while averaging
* @param debug show debug images
* @return difference between average in-pattern (1) and outside (2) average
* values
*/
public
static
double
getAbsoluteContrast
(
double
[]
data
,
int
[]
ipattern
,
double
outliers_frac
,
boolean
debug
)
{
if
(
debug
)
{
int
size
=
(
int
)
Math
.
sqrt
(
data
.
length
);
ShowDoubleFloatArrays
.
showArrays
(
data
,
size
,
size
,
"extracted_data"
);
}
ArrayList
<
ArrayList
<
Integer
>>
lists
=
new
ArrayList
<
ArrayList
<
Integer
>>();
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
lists
.
add
(
new
ArrayList
<
Integer
>());
}
double
[]
swd
=
new
double
[
2
],
sw
=
new
double
[
2
],
avg
=
new
double
[
2
],
fracw
=
new
double
[
2
];
for
(
int
n
=
0
;
n
<
swd
.
length
;
n
++)
{
ArrayList
<
Integer
>
list
=
lists
.
get
(
n
);
int
n1
=
n
+
1
;
for
(
int
i
=
0
;
i
<
ipattern
.
length
;
i
++)
if
(
ipattern
[
i
]
==
n1
){
sw
[
n
]
+=
1
;
swd
[
n
]+=
data
[
i
];
list
.
add
(
i
);
}
avg
[
n
]
=
swd
[
n
]/
sw
[
n
];
fracw
[
n
]
=
(
1.0
-
outliers_frac
)
*
sw
[
n
];
}
if
(
debug
)
{
System
.
out
.
println
(
"getAbsoluteContrast() before outliers: avg[0] ="
+
avg
[
0
]+
", avg[1]="
+
avg
[
1
]+
", avg[0]-avg[1]="
+(
avg
[
0
]-
avg
[
1
]));
}
if
(
outliers_frac
>
0
)
{
for
(
int
n
=
0
;
n
<
swd
.
length
;
n
++)
{
ArrayList
<
Integer
>
list
=
lists
.
get
(
n
);
Collections
.
sort
(
list
,
new
Comparator
<
Integer
>()
{
@Override
public
int
compare
(
Integer
lhs
,
Integer
rhs
)
{
double
rhsd
=
data
[
rhs
];
double
lhsd
=
data
[
lhs
];
return
(
rhsd
>
lhsd
)
?
-
1
:
(
rhsd
<
lhsd
)
?
1
:
0
;
}
});
while
(
sw
[
n
]
>=
fracw
[
n
])
{
int
indx_first
=
list
.
get
(
0
);
int
indx_last
=
list
.
get
(
list
.
size
()-
1
);
boolean
remove_first
=
Math
.
abs
(
data
[
indx_first
]
-
avg
[
n
])
>
Math
.
abs
(
data
[
indx_last
]
-
avg
[
n
]);
int
indx_worst
=
remove_first
?
indx_first
:
indx_last
;
double
d
=
data
[
indx_worst
];
double
sw_new
=
sw
[
n
]
-
1.0
;
avg
[
n
]
=
(
avg
[
n
]
*
sw
[
n
]
-
d
)/
sw_new
;
sw
[
n
]
=
sw_new
;
list
.
remove
(
remove_first
?
0
:
list
.
size
()-
1
);
}
}
}
if
(
debug
)
{
int
[]
ipattern1
=
new
int
[
ipattern
.
length
];
for
(
int
n
=
0
;
n
<
lists
.
size
();
n
++)
{
ArrayList
<
Integer
>
list
=
lists
.
get
(
n
);
for
(
Integer
i:
list
)
{
ipattern1
[
i
]
=
n
+
1
;
}
}
int
[][]
ipatterns
=
{
ipattern
,
ipattern1
};
double
[][]
dbg_img
=
new
double
[
2
][
ipattern
.
length
];
for
(
int
n
=
0
;
n
<
ipatterns
.
length
;
n
++)
{
for
(
int
i
=
0
;
i
<
ipatterns
[
n
].
length
;
i
++)
if
(
ipatterns
[
n
][
i
]
!=
0
){
switch
(
ipatterns
[
n
][
i
])
{
case
1
:
dbg_img
[
n
][
i
]
=
1.0
;
break
;
case
2
:
dbg_img
[
n
][
i
]
=
-
1.0
;
break
;
}
}
}
int
size
=
(
int
)
Math
.
sqrt
(
ipattern
.
length
);
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
size
,
size
,
true
,
"integer_patterns_before_after"
);
}
if
(
debug
)
{
System
.
out
.
println
(
"getAbsoluteContrast() after outliers: avg[0] ="
+
avg
[
0
]+
", avg[1]="
+
avg
[
1
]+
", avg[0]-avg[1]="
+(
avg
[
0
]-
avg
[
1
]));
}
return
avg
[
0
]-
avg
[
1
];
}
/**
* From existing pattern (only for simple dark main scene)
* create two zones to calculate average (w/o outliers) inside
* the pattern and around it. Mark inner with 1, outer - 2, keep
* other 0. Then later find 2 averages (removing outliers) and their
* difference - absolute contrast.
* @param patterns set of square patterns, first [0] for full pattern,
* others - for half-patterns cut in different directions.
* @param edge_frac consider in-pattern if normalized value (normalized by
* the value with maximal absolute value) is above
* 1-edge_frac, completely out if it is below edge_frac.
* @param oversize scale patterns by this value to create outer area (marked 2)
* @param debug show debug images
* @return integer array corresponding to the original patterns. 1 means
* "in-patter" (average w/o outliers and add), 2 means "around pattern"-
* average w/o outliers and subtract.
*/
public
static
int
[][]
getIntPatterns
(
double
[][]
patterns
,
double
edge_frac
,
// 0.15
double
oversize
,
boolean
debug
)
{
double
low_thresh
=
edge_frac
;
double
high_thresh
=
1.0
-
edge_frac
;
int
size
=
(
int
)
Math
.
sqrt
(
patterns
[
0
].
length
);
double
xc
=
size
/
2
;
double
yc
=
size
/
2
;
int
[][]
ipatterns
=
new
int
[
patterns
.
length
][
patterns
[
0
].
length
];
double
amax
=
0
;
double
absmax
=
0
;
for
(
int
i
=
0
;
i
<
patterns
[
0
].
length
;
i
++)
{
double
d
=
patterns
[
0
][
i
];
double
ad
=
Math
.
abs
(
d
);
if
(
ad
>
absmax
)
{
absmax
=
ad
;
amax
=
d
;
}
}
double
scale
=
1.0
/
amax
;
double
[][]
npatterns
=
new
double
[
patterns
.
length
][
patterns
[
0
].
length
];
for
(
int
n
=
0
;
n
<
patterns
.
length
;
n
++)
{
for
(
int
i
=
0
;
i
<
patterns
[
n
].
length
;
i
++)
{
npatterns
[
n
][
i
]
=
patterns
[
n
][
i
]
*
scale
;
}
}
// create full pattern first
int
num_1
=
0
,
num_2
=
0
;
for
(
int
y
=
0
;
y
<
size
;
y
++)
{
double
ys
=
yc
+
(
y
-
yc
)/
oversize
;
for
(
int
x
=
0
;
x
<
size
;
x
++)
{
int
indx
=
y
*
size
+
x
;
if
(
npatterns
[
0
][
indx
]
>
high_thresh
)
{
ipatterns
[
0
][
indx
]
=
1
;
num_1
++;
}
else
if
(
npatterns
[
0
][
indx
]
<=
low_thresh
)
{
// interpolate scaled version, between - keep zero
double
xs
=
xc
+
(
x
-
xc
)/
oversize
;
// interpolate
int
iys
=
(
int
)
Math
.
floor
(
ys
);
double
fys
=
ys
-
iys
;
int
ixs
=
(
int
)
Math
.
floor
(
xs
);
double
fxs
=
xs
-
ixs
;
int
sindx
=
iys
*
size
+
ixs
;
double
sd0
=
(
1
-
fys
)*(
1
-
fxs
)*
npatterns
[
0
][
sindx
]
+
(
1
-
fys
)*(
fxs
)*
npatterns
[
0
][
sindx
+
1
]
+
(
fys
)*(
1
-
fxs
)*
npatterns
[
0
][
sindx
+
size
]
+
(
fys
)*(
fxs
)*
npatterns
[
0
][
sindx
+
size
+
1
];
if
(
sd0
>
high_thresh
)
{
ipatterns
[
0
][
indx
]
=
2
;
num_2
++;
}
}
}
}
if
((
num_1
==
0
)
||
(
num_2
==
0
))
{
System
.
out
.
println
(
"getIntPatterns(): wrong pattern or parameters: num_1="
+
num_1
+
", num2="
+
num_2
);
return
null
;
}
// Other patterns
for
(
int
n
=
1
;
n
<
npatterns
.
length
;
n
++)
{
for
(
int
y
=
0
;
y
<
size
;
y
++)
{
double
ys
=
yc
+
(
y
-
yc
)/
oversize
;
for
(
int
x
=
0
;
x
<
size
;
x
++)
{
int
indx
=
y
*
size
+
x
;
if
(
ipatterns
[
0
][
indx
]
==
1
)
{
if
(
npatterns
[
n
][
indx
]/
npatterns
[
0
][
indx
]
>
0.5
)
{
ipatterns
[
n
][
indx
]
=
ipatterns
[
0
][
indx
];
//= 1
}
}
else
if
(
ipatterns
[
0
][
indx
]
==
2
)
{
double
xs
=
xc
+
(
x
-
xc
)/
oversize
;
// interpolate
int
iys
=
(
int
)
Math
.
floor
(
ys
);
double
fys
=
ys
-
iys
;
int
ixs
=
(
int
)
Math
.
floor
(
xs
);
double
fxs
=
xs
-
ixs
;
int
sindx
=
iys
*
size
+
ixs
;
double
sd0
=
(
1
-
fys
)*(
1
-
fxs
)*
npatterns
[
0
][
sindx
]
+
(
1
-
fys
)*(
fxs
)*
npatterns
[
0
][
sindx
+
1
]
+
(
fys
)*(
1
-
fxs
)*
npatterns
[
0
][
sindx
+
size
]
+
(
fys
)*(
fxs
)*
npatterns
[
0
][
sindx
+
size
+
1
];
double
sdn
=
(
1
-
fys
)*(
1
-
fxs
)*
npatterns
[
n
][
sindx
]
+
(
1
-
fys
)*(
fxs
)*
npatterns
[
n
][
sindx
+
1
]
+
(
fys
)*(
1
-
fxs
)*
npatterns
[
n
][
sindx
+
size
]
+
(
fys
)*(
fxs
)*
npatterns
[
n
][
sindx
+
size
+
1
];
if
(
sdn
/
sd0
>
0.5
)
{
ipatterns
[
n
][
indx
]
=
ipatterns
[
0
][
indx
];
// =2
}
}
}
}
}
if
(
debug
)
{
ShowDoubleFloatArrays
.
showArrays
(
npatterns
,
size
,
size
,
true
,
"normalized_patterns"
);
double
[][]
dbg_img
=
new
double
[
ipatterns
.
length
][
ipatterns
[
0
].
length
];
for
(
int
n
=
0
;
n
<
ipatterns
.
length
;
n
++)
{
for
(
int
i
=
0
;
i
<
ipatterns
[
n
].
length
;
i
++)
if
(
ipatterns
[
n
][
i
]
!=
0
){
switch
(
ipatterns
[
n
][
i
])
{
case
1
:
dbg_img
[
n
][
i
]
=
1.0
;
break
;
case
2
:
dbg_img
[
n
][
i
]
=
-
1.0
;
break
;
}
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_img
,
size
,
size
,
true
,
"integer_patterns"
);
}
return
ipatterns
;
}
public
static
double
[]
extractKernel
(
public
static
double
[]
extractKernel
(
double
[]
data
,
double
[]
data
,
int
kernel_radius
,
int
kernel_radius
,
...
...
src/main/java/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java
View file @
29e261ef
...
@@ -1976,6 +1976,8 @@ public class OrthoMapsCollection implements Serializable{
...
@@ -1976,6 +1976,8 @@ public class OrthoMapsCollection implements Serializable{
double
[][][]
corrs_out
=
new
double
[
indices
.
length
][][];
double
[][][]
corrs_out
=
new
double
[
indices
.
length
][][];
double
[][][]
convolve_out
=
new
double
[
indices
.
length
][][];
double
[][][]
convolve_out
=
new
double
[
indices
.
length
][][];
double
[][][]
corr_patterns
=
new
double
[
indices
.
length
][][];
double
[][][]
corr_patterns
=
new
double
[
indices
.
length
][][];
int
[][][]
icorr_patterns
=
new
int
[
indices
.
length
][][];
// will only be used for main !
double
[][][]
filtered_corrs
=
new
double
[
indices
.
length
][][];
double
[][][]
filtered_corrs
=
new
double
[
indices
.
length
][][];
int
[]
zoomout
=
new
int
[
indices
.
length
];
int
[]
zoomout
=
new
int
[
indices
.
length
];
ImagePlus
[]
imp_corrs
=
new
ImagePlus
[
indices
.
length
];
ImagePlus
[]
imp_corrs
=
new
ImagePlus
[
indices
.
length
];
...
@@ -2066,8 +2068,17 @@ public class OrthoMapsCollection implements Serializable{
...
@@ -2066,8 +2068,17 @@ public class OrthoMapsCollection implements Serializable{
kernels_all
[
scene_num
],
// final double [] kernel,
kernels_all
[
scene_num
],
// final double [] kernel,
corr_size
);
// final int width)
corr_size
);
// final int width)
}
}
}
}
if
(
scene_num
==
0
)
{
double
oversize
=
1.8
;
double
edge_frac
=
0.25
;
icorr_patterns
[
scene_num
]
=
OrthoMap
.
getIntPatterns
(
corr_patterns
[
scene_num
],
// double [][] patterns,
edge_frac
,
// double edge_frac, // 0.15
oversize
,
// double oversize,
true
);
// boolean debug);
}
}
}
// Splitting - above done for both scenes, below - just for the main one
// Splitting - above done for both scenes, below - just for the main one
for
(
int
scene_num
=
0
;
scene_num
<
indices
.
length
;
scene_num
++)
{
// will probably just use first one, second - derivative
for
(
int
scene_num
=
0
;
scene_num
<
indices
.
length
;
scene_num
++)
{
// will probably just use first one, second - derivative
...
@@ -2200,6 +2211,7 @@ public class OrthoMapsCollection implements Serializable{
...
@@ -2200,6 +2211,7 @@ public class OrthoMapsCollection implements Serializable{
num_non_overlap
++;
num_non_overlap
++;
}
}
}
}
if
(
num_non_overlap
>
0
)
{
if
(
num_non_overlap
>
0
)
{
System
.
out
.
println
(
"Removed "
+
num_non_overlap
+
" objects outside of the scenes overlap, "
+
match_sort
.
size
()+
" remain"
);
System
.
out
.
println
(
"Removed "
+
num_non_overlap
+
" objects outside of the scenes overlap, "
+
match_sort
.
size
()+
" remain"
);
}
}
...
@@ -2226,6 +2238,7 @@ public class OrthoMapsCollection implements Serializable{
...
@@ -2226,6 +2238,7 @@ public class OrthoMapsCollection implements Serializable{
System
.
out
.
print
(
","
);
System
.
out
.
print
(
","
);
}
}
}
}
}
}
// boolean remove_dc = true;
// boolean remove_dc = true;
if
(
scene_num
==
0
)
{
if
(
scene_num
==
0
)
{
...
@@ -2353,6 +2366,18 @@ public class OrthoMapsCollection implements Serializable{
...
@@ -2353,6 +2366,18 @@ public class OrthoMapsCollection implements Serializable{
imps_extracted_corr
,
// ImagePlus[] imps_extracted_corr, // may be null - will not be displayed
imps_extracted_corr
,
// ImagePlus[] imps_extracted_corr, // may be null - will not be displayed
imps_extracted_corr_half
);
// ImagePlus[] imps_extracted_corr_half
imps_extracted_corr_half
);
// ImagePlus[] imps_extracted_corr_half
}
}
double
[]
abs_contrast
=
new
double
[
match_sort
.
size
()];
double
outliers_frac
=
0.3
;
for
(
int
i
=
0
;
i
<
match_sort
.
size
();
i
++)
{
int
indx
=
match_sort
.
get
(
i
);
ItemMatch
match
=
matches_list
.
get
(
indx
);
int
best_patt
=
match
.
getPatternMatch
(
gops
[
scene_num
]).
getBestSub
();
abs_contrast
[
i
]
=
OrthoMap
.
getAbsoluteContrast
(
extracted_objects
[
scene_num
][
i
],
// double [] data,
icorr_patterns
[
scene_num
][
best_patt
-
1
],
//int [] ipattern,
outliers_frac
,
// double outliers_frac,
true
);
// boolean debug);
}
// Correlate second scene only for selected fragments
// Correlate second scene only for selected fragments
for
(
int
scene_other
=
1
;
scene_other
<
indices
.
length
;
scene_other
++)
{
// normally just 1
for
(
int
scene_other
=
1
;
scene_other
<
indices
.
length
;
scene_other
++)
{
// normally just 1
filter_data
[
scene_other
]
=
new
double
[
match_sort
.
size
()][
2
][];
// [scene][max][0-full, 1 - half][0- max, 1 - area, 2 - distance]
filter_data
[
scene_other
]
=
new
double
[
match_sort
.
size
()][
2
][];
// [scene][max][0-full, 1 - half][0- max, 1 - area, 2 - distance]
...
...
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