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
24a92f5c
Commit
24a92f5c
authored
Feb 22, 2024
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Testing DATI
parent
b3e9f364
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
732 additions
and
94 deletions
+732
-94
ComboMatch.java
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java
+133
-18
OrthoMap.java
src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java
+112
-2
OrthoMapsCollection.java
...va/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java
+480
-68
ImageDtt.java
src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java
+7
-6
No files found.
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java
View file @
24a92f5c
...
...
@@ -42,12 +42,43 @@ public class ComboMatch {
public
static
boolean
openTestPairGps
(
CLTParameters
clt_parameters
,
GPUTileProcessor
gpu_tile_processor
,
// initialized by the caller
final
int
debugLevel
)
{
int
debugLevel
)
{
GPU_TILE_PROCESSOR
=
gpu_tile_processor
;
// find -L /media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-b/ -type f -name "*-GCORR-GEO.tiff" | sort > GCORR-GEO.list
String
files_list_path
=
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_03_short.list"
;
String
orthoMapsCollection_path
=
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/ortho_maps_collection.data"
;
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_03_short.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/ortho_maps_collection.data";
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_04_short_20min.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_04_short_20min.data";
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_05_short_27.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_05_short_27.data";
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_07_short_27.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_07_short_27.data";
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_08_november.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_08_november.data";
// String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_10_short.list";
// String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_10_short.data";
String
files_list_path
=
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13.list"
;
String
orthoMapsCollection_path
=
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13.data"
;
//maps_19_sep13.list
//maps_09_short.list
//maps_08_november.list
// int [] gpu_ipair = {1,2};
// int [] gpu_ipair = {4,9}; //-> {4,24}
// int [] gpu_ipair = {4,18};
// String [] gpu_spair = {"1697877420_556997", "1697877527_942766"}; // 1697877564_888405"}; //58, 220
// String [] gpu_spair = {"1697877419_940125", "1697877527_942766"}; // 1697877564_888405"}; //58, 220
// String [] gpu_spair = {"1697877412_004148", "1697877522_274211"}; // 1697877564_888405"}; //58, 220
// String [] gpu_spair = {"1697877409_353265", "1697877518_773045"};
// String [] gpu_spair = {"1697877465_672024", "1697877563_587972"};
// String [] gpu_spair = {"1697877465_672024", "1697878995_797332"};
// String [] gpu_spair = {"1697877465_672024", "1697877528_776377"};
// String [] gpu_spair = {"1694564245_111645", "1694564701_230240"}; // Morning Sep, 13
// String [] gpu_spair = {"1694564245_111645", "1694564822_637346"}; // Morning Sep, 13
String
[]
gpu_spair
=
{
"1694564248_145989"
,
"1694564819_336247"
};
// Morning Sep, 13
//
double
[][][]
image_enuatr
=
{{{
0
,
0
,
0
},{
0
,
0
,
0
}},{{
0
,
0
,
0
},{
0
,
0
,
0
}}};
int
gpu_width
=
clt_parameters
.
imp
.
rln_gpu_width
;
// 3008;
...
...
@@ -58,6 +89,7 @@ public class ComboMatch {
boolean
use_saved_collection
=
true
;
// false;
boolean
save_collection
=
true
;
boolean
process_correlation
=
true
;
// use false to save new version of data
boolean
restore_temp
=
true
;
GenericJTabbedDialog
gd
=
new
GenericJTabbedDialog
(
"Set image pair"
,
1200
,
800
);
gd
.
addStringField
(
"Image list full path"
,
files_list_path
,
180
,
"Image list full path."
);
gd
.
addStringField
(
"Maps collection save path"
,
orthoMapsCollection_path
,
180
,
"Save path for serialized map collection data."
);
...
...
@@ -87,6 +119,8 @@ public class ComboMatch {
"GPU image height"
);
gd
.
addCheckbox
(
"Show transformation centers"
,
show_centers
,
"Mark verticals from the UAS on the ground."
);
gd
.
addCheckbox
(
"Process altitude images"
,
use_alt
,
"Load and process altitude maps."
);
gd
.
addStringField
(
"First matching timestamp"
,
gpu_spair
[
0
],
20
,
"First GPU-matching timestamp with '_' for decimal point."
);
gd
.
addStringField
(
"Second matching timestamp"
,
gpu_spair
[
1
],
20
,
"First GPU-matching timestamp with '_' for decimal point."
);
gd
.
showDialog
();
if
(
gd
.
wasCanceled
())
return
false
;
...
...
@@ -113,6 +147,10 @@ public class ComboMatch {
show_centers
=
gd
.
getNextBoolean
();
use_alt
=
gd
.
getNextBoolean
();
gpu_spair
[
0
]
=
gd
.
getNextString
();
gpu_spair
[
1
]
=
gd
.
getNextString
();
OrthoMapsCollection
maps_collection
=
null
;
if
(
use_saved_collection
)
{
try
{
...
...
@@ -125,9 +163,14 @@ public class ComboMatch {
maps_collection
=
new
OrthoMapsCollection
(
files_list_path
);
// should have ".list" extensiohn
}
String
[]
names
=
maps_collection
.
getNames
();
//getTemperature()
// get all temperatures
maps_collection
.
getAllTemperatures
();
// which pair to compare
int
[]
gpu_pair
=
{
1
,
2
};
String
[]
gpu_spair
=
{
names
[
gpu_pair
[
0
]],
names
[
gpu_pair
[
1
]]};
// String [] gpu_spair = {names[gpu_ipair[0]],names[gpu_ipair[1]]};
int
[]
origin
=
new
int
[
2
];
ImagePlus
imp_img
=
maps_collection
.
renderMulti
(
"multi_"
+
zoom_lev
,
// String title,
...
...
@@ -165,14 +208,73 @@ public class ComboMatch {
}
double
[][]
affine0
=
{{
1
,
0
,
0
},{
0
,
1
,
0
}};
// will always stay the same
double
[][]
affine1
=
{{
1
,
0
,
0
},{
0
,
1
,
0
}};
// will be variable // here in meters, relative to vertical point
// double [][] affine1 = {
// {1,0,-1.47336},
// {0,1,-3.46664}}; // will be variable // here in meters, relative to vertical point
//1697877414_404948 - 4 (0)
//1697879062_336162 - 9 (1)
// double [][] affine1 = {
// {1.0002226408872814, -0.007965644488589378, -1.512310157498787},
// {0.006494702666097521, 1.0002691922354188, -3.4553628872407023}};
// double [][] affine1 = {{1,0,0},{0,1,0}}; // will always stay the same
// [[1.0001698416441531, 0.0035703780078751575, 1.3965061354976767],
// [0.005158652079706154, 1.0014361052510927, 1.204551528740014]]]
// double [][] affine1 = {{1,0,1.33},
// {0,1,1.227}};
double
[][]
affine1
=
{
{
1
,
0
,
0
},
{
0
,
1
,
0
}};
// affine1[0][2] = 0.64; affine1[1][2] = 1.253; // {"1697877412_004148", "1697877522_274211"}; //
// (346.250-348.000)/12.5,(277.000-269.250)/12.5 = (-0.14, 0.62)
// affine1[0][2] = -0.14; affine1[1][2] = 0.62; // {"1697877409_353265", "1697877518_773045"}; //
// affine1[0][2] = -1.44; affine1[1][2] = 1.653; //"1697877465_672024", "1697877563_587972"
// affine1[0][2] = -0.25; affine1[1][2] = -1.627; //{"1697877465_672024", "1697878995_797332"};
// affine1[0][2] = -1.08; affine1[1][2] = 3.267; //{"1697877465_672024", "1697877528_776377"};
// affine1[0][2] = -1.2; affine1[1][2] = -0.9066; //{"1694564245_111645", "1694564701_230240"};
// affine1[0][2] = 0.933; affine1[1][2] = -2.2667; //{"1694564245_111645", "1694564822_637346"};
affine1
[
0
][
2
]
=
2.08
;
affine1
[
1
][
2
]
=
-
0.093
;
//{"1694564248_145989", "1694564819_336247"};
double
[][][]
affines
=
{
affine0
,
affine1
};
int
[]
gpu_pair
=
new
int
[
gpu_spair
.
length
];
for
(
int
i
=
0
;
i
<
gpu_pair
.
length
;
i
++)
{
gpu_pair
[
i
]
=
maps_collection
.
getIndex
(
gpu_spair
[
i
]);
}
int
[]
zooms
=
{-
3
,-
1
,
1000
,
1000
};
debugLevel
=
0
;
boolean
batch_mode
=
true
;
for
(
int
zi
=
0
;
zi
<
zooms
.
length
;
zi
++)
{
zoom_lev
=
zooms
[
zi
];
if
(
zoom_lev
>=
1000
)
{
break
;
}
// will modify affines[1], later add jtj, weight, smth. else?
double
[][]
corr_pair_rslt
=
maps_collection
.
correlateOrthoPair
(
clt_parameters
,
// CLTParameters clt_parameters,
gpu_spair
,
// String [] gpu_spair,
batch_mode
,
// boolean batch_mode,
gpu_pair
,
// String [] gpu_spair,
affines
,
// double [][][] affines, // on top of GPS offsets
zoom_lev
,
// int zoom_lev,
debugLevel
);
// final int debugLevel)
int
render_zoom_lev
=
maps_collection
.
ortho_maps
[
gpu_pair
[
0
]].
getOriginalZoomLevel
();
ImagePlus
imp_img_pair
=
maps_collection
.
renderMulti
(
"multi_"
+
gpu_spair
[
0
]+
"-"
+
gpu_spair
[
1
]+
"-zoom_"
+
render_zoom_lev
+
"_"
+
zoom_lev
,
// String title,
false
,
// boolean use_alt,
gpu_pair
,
// int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
affines
,
// double [][][] affines, // null or [indices.length][2][3]
show_centers
,
// boolean show_centers,
render_zoom_lev
,
// int zoom_level,
origin
);
// int [] origin){
imp_img_pair
.
show
();
System
.
out
.
println
(
"Done"
);
if
(
debugLevel
>-
4
)
{
System
.
out
.
println
(
"adjusted affines[1] for a pair: "
+
gpu_spair
[
0
]+
"/"
+
gpu_spair
[
1
]);
System
.
out
.
println
(
"[["
+
affines
[
1
][
0
][
0
]+
","
+
affines
[
1
][
0
][
1
]+
","
+
affines
[
1
][
0
][
2
]+
"],"
);
System
.
out
.
println
(
" ["
+
affines
[
1
][
1
][
0
]+
","
+
affines
[
1
][
1
][
1
]+
","
+
affines
[
1
][
1
][
2
]+
"]]"
);
System
.
out
.
println
();
}
}
}
if
(
save_collection
)
{
try
{
...
...
@@ -188,6 +290,20 @@ public class ComboMatch {
return
true
;
}
/*
adjusted affines[1] for a pair: 1697877465_672024/1697877563_587972 RMS= 0.14511264718699468 (0.14577676900752629)
[[1.0065661054211072,0.009234141675959222,-1.4706666954418992],
[-0.004304610680434175,1.0012437786888277,1.6394608778426498]]
adjusted affines[1] for a pair: 1694564245_111645/1694564701_230240
[[1.021246208683918,0.006667337255903127,-1.0137566435443375],
[-0.010035351748801541,1.0294363088409202,-0.8395952637299295]]
adjusted affines[1] for a pair: 1694564245_111645/1694564822_637346
[[1.0148318094351692,0.01611699521114023,1.1534804399270817],
[-0.025584298199020607,1.0182605131307008,-2.157143969635918]]
*
*
double [] offset_xy_second = {0,0};
double [][] corr_pair_rslt = maps_collection. correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters,
...
...
@@ -438,10 +554,10 @@ public class ComboMatch {
clt_parameters
.
gpu_sigma_b
,
// final double gpu_sigma_b, // 0.9, 1.1
clt_parameters
.
gpu_sigma_g
,
// final double gpu_sigma_g, // 0.6, 0.7
clt_parameters
.
gpu_sigma_m
,
// final double gpu_sigma_m, // = 0.4; // 0.7;
debugLevel
);
// final int globalDebugLevel)
batch_mode
?
-
3
:
debugLevel
);
// final int globalDebugLevel)
int
tilesX
=
img_width
/
GPUTileProcessor
.
DTT_SIZE
;
int
tilesY
=
wh
[
1
]/
GPUTileProcessor
.
DTT_SIZE
;
if
(
debugLevel
>
1
)
{
if
(
!
batch_mode
&&
(
debugLevel
>
1
)
)
{
renderFromTD
(
true
,
// boolean use_reference,
"ref"
);
//String suffix
...
...
@@ -453,6 +569,7 @@ public class ComboMatch {
final
double
gpu_sigma_log_corr
=
clt_parameters
.
getGpuCorrLoGSigma
(
image_dtt
.
isMonochrome
());
image_dtt
.
interRectilinearCorrTD
(
clt_parameters
.
img_dtt
,
//final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
batch_mode
,
// final boolean batch_mode,
erase_clt
,
// final int erase_clt,
fpixels
[
1
],
// final float [] fpixels,
wh
,
// final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels
...
...
@@ -518,10 +635,8 @@ public class ComboMatch {
rln_cent_radius
,
// final double centroid_radius, // 0 - all same weight, > 0 cosine(PI/2*sqrt(dx^2+dy^2)/rad)
rln_n_recenter
);
// final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
}
boolean
show_vector_field
=
true
;
boolean
show_2d_correlations
=
true
;
boolean
show_vector_field
=
(
debugLevel
>
100
);
// true;
boolean
show_2d_correlations
=
(
debugLevel
>
0
);
// true;
final
int
corr_size
=
2
*
GPUTileProcessor
.
DTT_SIZE
-
1
;
if
(
show_2d_correlations
)
{
double
[][]
dbg_2d_corrs
=
ImageDtt
.
corr_partial_dbg
(
// not used in lwir
...
...
src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java
View file @
24a92f5c
...
...
@@ -27,6 +27,7 @@ import com.elphel.imagej.common.ShowDoubleFloatArrays;
import
com.elphel.imagej.gpu.TpTask
;
import
com.elphel.imagej.ims.Imx5
;
import
com.elphel.imagej.readers.ElphelTiffReader
;
import
com.elphel.imagej.readers.ImagejJp4Tiff
;
import
com.elphel.imagej.tileprocessor.ImageDtt
;
import
com.elphel.imagej.tileprocessor.IntersceneMatchParameters
;
import
com.elphel.imagej.tileprocessor.QuadCLT
;
...
...
@@ -41,6 +42,7 @@ import ij.plugin.filter.GaussianBlur;
import
ij.process.FloatProcessor
;
import
ij.process.ImageConverter
;
import
ij.process.ImageProcessor
;
import
loci.formats.FormatException
;
public
class
OrthoMap
implements
Comparable
<
OrthoMap
>,
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
...
...
@@ -55,6 +57,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public
transient
String
name
;
// timestamp
public
transient
double
ts
;
public
transient
String
path
;
// full path to the model directory (including /vXX?)
public
transient
String
scenes_path
;
// full path to the model directory (including /vXX?)
public
double
[]
lla
;
// lat/long/alt
public
LocalDateTime
dt
;
// affine convert (input) rectified coordinates (meters) relative to vert_meters to source image
...
...
@@ -69,6 +72,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public
int
orig_zoom_level
;
public
boolean
orig_zoom_valid
;
public
double
need_extra_zoom
;
public
double
averageRawPixel
=
Double
.
NaN
;
// measure of scene temperature
public
transient
double
averageImagePixel
=
Double
.
NaN
;
// average image pixel value (to combine with raw)
transient
HashMap
<
Integer
,
FloatImageData
>
images
;
HashMap
<
Double
,
PairwiseOrthoMatch
>
pairwise_matches
;
...
...
@@ -76,6 +81,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
private
void
writeObject
(
ObjectOutputStream
oos
)
throws
IOException
{
oos
.
defaultWriteObject
();
oos
.
writeObject
(
path
);
oos
.
writeObject
(
scenes_path
);
// lla is not transient
// dt is not transient
// affine is not transient
...
...
@@ -97,6 +103,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
path
=
(
String
)
ois
.
readObject
();
name
=
getNameFromPath
(
path
);
ts
=
Double
.
parseDouble
(
name
.
replace
(
"_"
,
"."
));
scenes_path
=
(
String
)
ois
.
readObject
();
// lla is not transient
// dt is not transient
// affine is not transient
...
...
@@ -107,6 +114,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
// orig_image was not saved
// alt_image was not saved
images
=
new
HashMap
<
Integer
,
FloatImageData
>();
// field images was not saved
averageImagePixel
=
Double
.
NaN
;
// average image pixel value (to combine with raw)
// pairwise_matches is not transient
// pairwise_matches = new HashMap<Double, PairwiseOrthoMatch>();
}
...
...
@@ -129,11 +138,14 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public
int
getHeight
()
{
return
orig_height
;
}
public
int
getOriginalZoomLevel
()
{
return
orig_zoom_level
;
}
// Generate ALT image path from the GEO
public
static
String
getAltPath
(
String
path
)
{
int
p1
=
path
.
lastIndexOf
(
"."
);
return
path
.
substring
(
0
,
p1
)+
ALT_SUFFIX
+
".tiff"
;
}
public
static
String
getNameFromPath
(
String
path
)
{
int
p1
=
path
.
lastIndexOf
(
Prefs
.
getFileSeparator
());
...
...
@@ -143,8 +155,65 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return
path
.
substring
(
p1
+
1
,
p2
);
}
public
OrthoMap
(
String
path
)
{
/**
* Gets average pixel value of all sensors of the reference scene
* @return
*/
public
double
getTemperature
()
{
if
(
Double
.
isNaN
(
averageRawPixel
))
{
final
String
TIFF_EXT
=
".tiff"
;
final
File
[]
raw_files
=
(
new
File
(
scenes_path
)).
listFiles
();
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
avg_arr
=
new
double
[
threads
.
length
];
final
double
[]
npix_arr
=
new
double
[
threads
.
length
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
thread_num
=
ati
.
getAndIncrement
();
ImagejJp4Tiff
imagejJp4Tiff
=
new
ImagejJp4Tiff
();
for
(
int
iFile
=
ai
.
getAndIncrement
();
iFile
<
raw_files
.
length
;
iFile
=
ai
.
getAndIncrement
())
{
if
(
raw_files
[
iFile
].
getName
().
endsWith
(
TIFF_EXT
))
{
ImagePlus
imp
=
null
;
String
spath
=
raw_files
[
iFile
].
toString
();
try
{
imp
=
imagejJp4Tiff
.
readTiffJp4
(
spath
);
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"getImagesMultithreaded IOException "
+
spath
);
}
catch
(
FormatException
e
)
{
System
.
out
.
println
(
"getImagesMultithreaded FormatException "
+
spath
);
}
if
(
imp
!=
null
)
{
npix_arr
[
thread_num
]
=
imp
.
getWidth
()*
imp
.
getHeight
();
float
[]
fpixels
=
(
float
[])
imp
.
getProcessor
().
getPixels
();
for
(
int
i
=
0
;
i
<
fpixels
.
length
;
i
++)
{
avg_arr
[
thread_num
]
+=
fpixels
[
i
];
}
avg_arr
[
thread_num
]
/=
npix_arr
[
thread_num
];
}
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
avg
=
0
,
num
=
0
;
for
(
int
i
=
0
;
i
<
avg_arr
.
length
;
i
++)
{
avg
+=
avg_arr
[
i
]*
npix_arr
[
i
];
num
+=
npix_arr
[
i
];
}
averageRawPixel
=
avg
/
num
;
}
return
averageRawPixel
;
}
public
OrthoMap
(
String
path
,
String
scenes_path
)
{
this
.
path
=
path
;
this
.
scenes_path
=
scenes_path
;
name
=
getNameFromPath
(
path
);
ts
=
Double
.
parseDouble
(
name
.
replace
(
"_"
,
"."
));
Properties
imp_prop
=
null
;
...
...
@@ -171,6 +240,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
need_extra_zoom
=
FloatImageData
.
needZoomIn
(
orig_pix_meters
);
images
=
new
HashMap
<
Integer
,
FloatImageData
>();
pairwise_matches
=
new
HashMap
<
Double
,
PairwiseOrthoMatch
>();
averageRawPixel
=
Double
.
NaN
;
// measure of scene temperature
averageImagePixel
=
Double
.
NaN
;
// average image pixel value (to combine with raw)
}
...
...
@@ -221,6 +292,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
if
(
orig_image
==
null
)
{
readImageData
();
}
getAveragePixel
();
return
orig_image
;
}
public
FloatImageData
getAltData
()
{
...
...
@@ -246,9 +318,47 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
if
(
orig_zoom_valid
)
{
images
.
put
(
orig_zoom_level
,
orig_image
);
}
averageImagePixel
=
Double
.
NaN
;
return
true
;
}
public
double
getAveragePixel
()
{
if
(
Double
.
isNaN
(
averageImagePixel
))
{
if
(
orig_image
==
null
)
{
readImageData
();
}
final
float
[]
pixels
=
orig_image
.
data
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[]
avg_arr
=
new
double
[
threads
.
length
];
final
double
[]
npix_arr
=
new
double
[
threads
.
length
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
thread_num
=
ati
.
getAndIncrement
();
for
(
int
ipix
=
ai
.
getAndIncrement
();
ipix
<
pixels
.
length
;
ipix
=
ai
.
getAndIncrement
())
{
float
p
=
pixels
[
ipix
];
if
(!
Float
.
isNaN
(
p
))
{
avg_arr
[
thread_num
]
+=
p
;
npix_arr
[
thread_num
]
+=
1
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
avg
=
0
,
num
=
0
;
for
(
int
i
=
0
;
i
<
avg_arr
.
length
;
i
++)
{
avg
+=
avg_arr
[
i
];
// *npix_arr[i];
num
+=
npix_arr
[
i
];
}
averageImagePixel
=
avg
/
num
;
}
return
averageImagePixel
;
}
private
boolean
readAltData
()
{
// assuming the same scale as main image
ImagePlus
imp
=
new
ImagePlus
(
getAltPath
(
path
));
int
width
=
imp
.
getWidth
();
...
...
src/main/java/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java
View file @
24a92f5c
...
...
@@ -33,7 +33,7 @@ import ij.gui.PointRoi;
public
class
OrthoMapsCollection
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
public
static
final
String
[]
KEY_DIRS
=
{
"rootDirectory"
,
// from EyesisCorrectionParameters
"sourceDirectory"
,
"linkedModels"
,
"videoDirectory"
,
"x3dDirectory"
,
"resultsDirectory"
};
"sourceDirectory"
,
"linkedModels"
,
"videoDirectory"
,
"x3dDirectory"
,
"resultsDirectory"
,
"scenesDirectory"
};
OrthoMap
[]
ortho_maps
;
transient
HashMap
<
Double
,
Integer
>
map_index
;
transient
HashMap
<
String
,
Integer
>
map_index_string
;
...
...
@@ -52,11 +52,15 @@ public class OrthoMapsCollection implements Serializable{
public
OrthoMapsCollection
(
String
path
)
{
if
(
path
.
endsWith
(
".list"
))
{
String
[]
paths
=
getPathsFromSorceList
(
path
);
String
[]
scenes0
=
new
String
[
1
];
String
[]
paths
=
getPathsAndScenesFromSorceList
(
path
,
scenes0
);
String
scenes_path
=
scenes0
[
0
];
double
[][]
affine
=
{{
1
,
0
,
0
},{
0
,
1
,
0
}};
// maybe later calculate from mage_enuatr
ortho_maps
=
new
OrthoMap
[
paths
.
length
];
for
(
int
n
=
0
;
n
<
ortho_maps
.
length
;
n
++)
{
ortho_maps
[
n
]
=
new
OrthoMap
(
paths
[
n
]);
String
name
=
OrthoMap
.
getNameFromPath
(
paths
[
n
]);
String
scene_path
=
getSceneDir
(
scenes_path
,
name
);
ortho_maps
[
n
]
=
new
OrthoMap
(
paths
[
n
],
scene_path
);
ortho_maps
[
n
].
setAffine
(
affine
);
}
}
...
...
@@ -64,6 +68,28 @@ public class OrthoMapsCollection implements Serializable{
reindex
();
}
static
String
getSceneDir
(
String
scenes_path
,
String
name
)
{
File
[]
scene_dirs
=
(
new
File
(
scenes_path
)).
listFiles
();
// may contain non-directories, will be filtered by filterScenes
//scene_dirs[3].listFiles()
Arrays
.
sort
(
scene_dirs
);
for
(
int
i
=
scene_dirs
.
length
-
1
;
i
>=
0
;
i
--)
{
if
(
scene_dirs
[
i
].
isDirectory
())
{
String
dirname
=
scene_dirs
[
i
].
getName
();
if
(
name
.
compareTo
(
dirname
)
>=
0
)
{
// verify it has needed scene
File
[]
segment
=
scene_dirs
[
i
].
listFiles
();
for
(
int
j
=
0
;
j
<
segment
.
length
;
j
++)
{
if
(
segment
[
j
].
getName
().
equals
(
name
))
{
return
segment
[
j
].
toString
();
}
}
}
}
}
return
null
;
}
public
int
reindex
()
{
map_index
=
new
HashMap
<
Double
,
Integer
>();
...
...
@@ -87,8 +113,21 @@ public class OrthoMapsCollection implements Serializable{
return
names
;
}
public
void
getAllTemperatures
()
{
for
(
int
n
=
0
;
n
<
ortho_maps
.
length
;
n
++)
{
ortho_maps
[
n
].
getTemperature
();
}
}
public
static
String
[]
getPathsFromSorceList
(
String
files_list
)
{
return
getPathsAndScenesFromSorceList
(
files_list
,
null
);
}
public
static
String
[]
getPathsAndScenesFromSorceList
(
String
files_list
,
String
[]
scenes0
)
{
List
<
String
>
lines
;
List
<
String
>
rel_files
=
new
ArrayList
<
String
>();
Path
seq_path
=
Paths
.
get
(
files_list
);
...
...
@@ -129,11 +168,16 @@ public class OrthoMapsCollection implements Serializable{
sourceDirectory
=(
base_path
.
resolve
(
Paths
.
get
(
dir_map
.
get
(
"sourceDirectory"
)))).
toString
();
}
Path
source_path
=
Paths
.
get
(
sourceDirectory
);
// File source_dir = new File(source_path.toString());
// File source_dir = new File(source_path.toString());
String
[]
paths
=
new
String
[
rel_files
.
size
()];
for
(
int
i
=
0
;
i
<
paths
.
length
;
i
++)
{
paths
[
i
]
=
(
source_path
.
resolve
(
Paths
.
get
(
rel_files
.
get
(
i
)))).
toString
();
}
if
(
dir_map
.
containsKey
(
"scenesDirectory"
))
{
if
(
scenes0
!=
null
)
{
scenes0
[
0
]=(
base_path
.
resolve
(
Paths
.
get
(
dir_map
.
get
(
"scenesDirectory"
)))).
toString
();
}
}
return
paths
;
}
...
...
@@ -213,14 +257,21 @@ public class OrthoMapsCollection implements Serializable{
String
title
,
boolean
use_alt
,
boolean
show_centers
,
// OrthoMap [] maps,
int
zoom_level
,
int
[]
origin
){
return
renderMulti
(
title
,
// String title,
use_alt
,
//boolean use_alt,
null
,
// int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
null
,
// double [][][] affines, // null or [indices.length][2][3]
show_centers
,
// boolean show_centers,
zoom_level
,
// int zoom_level,
origin
);
// int [] origin)
/*
int [] wh = new int[2];
double [][] centers = new double [ortho_maps.length][];
float [][] multi = renderMulti (
use_alt, // boolean use_alt,
// maps, // OrthoMap [] maps,
zoom_level, // int zoom_level,
wh, // int [] wh,
origin, // int [] origin){ // maps[0] as a reference
...
...
@@ -245,10 +296,77 @@ public class OrthoMapsCollection implements Serializable{
roi.setOptions("label");
imp.setRoi(roi);
}
return imp;
*/
}
public
ImagePlus
renderMulti
(
String
title
,
boolean
use_alt
,
int
[]
indices
,
// null or which indices to use (normally just 2 for pairwise comparison)
double
[][][]
affines
,
// null or [indices.length][2][3]
boolean
show_centers
,
int
zoom_level
,
int
[]
origin
){
int
[]
wh
=
new
int
[
2
];
double
[][]
centers
=
new
double
[(
indices
!=
null
)?
indices
.
length
:
ortho_maps
.
length
][];
float
[][]
multi
=
renderMulti
(
use_alt
,
// boolean use_alt,
indices
,
// int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
affines
,
// double [][][] affines, // null or [indices.length][2][3]
zoom_level
,
// int zoom_level,
wh
,
// int [] wh,
origin
,
// int [] origin){ // maps[0] as a reference
centers
);
// double [][] centers)
int
num_images
=
(
indices
!=
null
)?
indices
.
length
:
ortho_maps
.
length
;
// String [] map_names = new String[(indices != null) ? indices.length : ortho_maps.length];
String
[]
map_names
=
new
String
[
num_images
+
((
num_images
==
2
)?
1
:
0
)];
float
[][]
extra_multi
=
new
float
[
map_names
.
length
][];
for
(
int
n
=
0
;
n
<
num_images
;
n
++)
{
int
mapn
=
(
indices
!=
null
)?
indices
[
n
]
:
n
;
map_names
[
n
]
=
ortho_maps
[
mapn
].
getName
()+
"_"
+
ortho_maps
[
mapn
].
getLocalDateTime
().
toString
().
replace
(
"T"
,
"_"
)+
"_UTC"
;
map_names
[
n
]
+=
String
.
format
(
" raw=%7.1f"
,
ortho_maps
[
mapn
].
getTemperature
());
extra_multi
[
n
]
=
multi
[
n
];
}
if
(
map_names
.
length
>
num_images
)
{
// inefficient way, only for display
// correct(offset) pixel values relative to multi[0]
int
map0
=
(
indices
!=
null
)?
indices
[
0
]
:
0
;
if
(!
use_alt
)
{
for
(
int
n
=
1
;
n
<
num_images
;
n
++)
{
int
mapn
=
(
indices
!=
null
)?
indices
[
n
]
:
n
;
double
offs
=
ortho_maps
[
mapn
].
getTemperature
()-
ortho_maps
[
mapn
].
getAveragePixel
()
-(
ortho_maps
[
map0
].
getTemperature
()-
ortho_maps
[
map0
].
getAveragePixel
());
float
foffs
=
(
float
)
offs
;
for
(
int
i
=
0
;
i
<
extra_multi
[
n
].
length
;
i
++)
if
(!
Float
.
isNaN
(
extra_multi
[
n
][
i
]))
{
extra_multi
[
n
][
i
]+=
foffs
;
}
}
}
map_names
[
num_images
]
=
"Diff 0-1"
;
extra_multi
[
num_images
]
=
new
float
[
extra_multi
[
0
].
length
];
for
(
int
i
=
0
;
i
<
extra_multi
[
num_images
].
length
;
i
++)
{
extra_multi
[
num_images
][
i
]
=
extra_multi
[
1
][
i
]-
extra_multi
[
0
][
i
];
}
}
ImageStack
stack
=
ShowDoubleFloatArrays
.
makeStack
(
extra_multi
,
wh
[
0
],
wh
[
1
],
map_names
,
false
);
ImagePlus
imp
=
new
ImagePlus
(
title
,
stack
);
if
(
show_centers
)
{
PointRoi
roi
=
new
PointRoi
();
for
(
int
i
=
0
;
i
<
centers
.
length
;
i
++)
{
roi
.
addPoint
(
centers
[
i
][
0
],
centers
[
i
][
1
],
i
+
1
);
}
roi
.
setOptions
(
"label"
);
imp
.
setRoi
(
roi
);
}
return
imp
;
}
/**
* Rectify and render multiple images (as slices) matching vert_meters to
* their (vert_meters points) provided IMS coordinates
...
...
@@ -267,6 +385,23 @@ public class OrthoMapsCollection implements Serializable{
int
[]
wh
,
int
[]
origin
,
// maps[0] as a reference
double
[][]
centers
){
return
renderMulti
(
use_alt
,
// boolean use_alt,
null
,
// int [] indices,
null
,
// double [][][] affines,
zoom_level
,
// int zoom_level,
wh
,
// int [] wh,
origin
,
// int [] origin, // maps[0] as a reference
centers
);
// double [][] centers)
}
public
float
[][]
renderMulti
(
boolean
use_alt
,
int
[]
indices
,
// null or which indices to use (normally just 2 for pairwise comparison)
double
[][][]
affines
,
// null or [indices.length][2][3]
int
zoom_level
,
int
[]
wh
,
int
[]
origin
,
// maps[0] as a reference
double
[][]
centers
){
int
[][]
bounds
=
getBoundsPixels
(
// should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center
zoom_level
);
int
width
=
bounds
[
0
][
1
]
-
bounds
[
0
][
0
];
// bounds[x][0] - negative
...
...
@@ -279,33 +414,48 @@ public class OrthoMapsCollection implements Serializable{
origin
[
0
]
=
-
bounds
[
0
][
0
];
origin
[
1
]
=
-
bounds
[
1
][
0
];
}
final
float
[][]
fpixels
=
new
float
[
ortho_maps
.
length
][
width
*
height
];
for
(
int
nmap
=
0
;
nmap
<
ortho_maps
.
length
;
nmap
++)
{
final
int
fnmap
=
nmap
;
Arrays
.
fill
(
fpixels
[
nmap
],
Float
.
NaN
);
if
(
indices
==
null
)
{
indices
=
new
int
[
ortho_maps
.
length
];
for
(
int
i
=
0
;
i
<
indices
.
length
;
i
++)
{
indices
[
i
]
=
i
;
}
}
final
float
[][]
fpixels
=
new
float
[
indices
.
length
][
width
*
height
];
// for (int nmap:indices) { // = 0; nmap< ortho_maps.length; nmap++) {
for
(
int
indx
=
0
;
indx
<
indices
.
length
;
indx
++)
{
//:indices) { // = 0; nmap< ortho_maps.length; nmap++) {
final
int
findx
=
indx
;
final
int
nmap
=
indices
[
indx
];
// nmap;
Arrays
.
fill
(
fpixels
[
findx
],
Float
.
NaN
);
final
double
scale
=
1.0
/
OrthoMap
.
getPixelSizeMeters
(
zoom_level
);
final
double
src_scale
=
1.0
/
OrthoMap
.
getPixelSizeMeters
(
ortho_maps
[
nmap
].
orig_zoom_level
);
// pix per meter
// metric bounds of the rectified image relative to its origin
double
[][]
mbounds
=
ortho_maps
[
nmap
].
getBoundsMeters
(
true
);
// double [][] mbounds = (affines !=null) ?
// ortho_maps[nmap].getBoundsMeters(true, affines[indx]): // use provided affine
// ortho_maps[nmap].getBoundsMeters(true);
double
[][]
mbounds
=
ortho_maps
[
nmap
].
getBoundsMeters
(
true
);
// keep original bounds
double
[]
enu_offset
=
ortho_maps
[
0
].
enuOffsetTo
(
ortho_maps
[
nmap
]);
final
double
[]
scaled_out_center
=
{
// xy center to apply affine to
-
bounds
[
0
][
0
]
+
scale
*
enu_offset
[
0
],
-
bounds
[
1
][
0
]
-
scale
*
enu_offset
[
1
]};
if
(
centers
!=
null
)
{
centers
[
nmap
]
=
scaled_out_center
;
centers
[
findx
]
=
scaled_out_center
;
}
final
int
[][]
obounds
=
new
int
[
2
][
2
];
// output (rectified, combined) image bounds, relative to thje top-left
for
(
int
n
=
0
;
n
<
2
;
n
++)
{
obounds
[
n
][
0
]
=
(
int
)
Math
.
floor
(
scaled_out_center
[
n
]
+
scale
*
mbounds
[
n
][
0
]);
obounds
[
n
][
1
]
=
(
int
)
Math
.
ceil
(
scaled_out_center
[
n
]
+
scale
*
mbounds
[
n
][
1
]);
}
// Output window size
// Output window size
(keep original affine - OK if will not exactly fit)
final
int
ownd_width
=
obounds
[
0
][
1
]
-
obounds
[
0
][
0
];
final
int
ownd_height
=
obounds
[
1
][
1
]
-
obounds
[
1
][
0
];
final
int
ownd_len
=
ownd_width
*
ownd_height
;
double
[][]
src_bounds
=
ortho_maps
[
nmap
].
getBoundsMeters
(
true
);
// double [][] src_bounds=(affines !=null) ?
// ortho_maps[nmap].getBoundsMeters (true, affines[indx]): // use provided affine
// ortho_maps[nmap].getBoundsMeters (true);
double
[][]
src_bounds
=
ortho_maps
[
nmap
].
getBoundsMeters
(
true
);
// using original affines
final
double
[]
src_center
=
{-
src_bounds
[
0
][
0
],-
src_bounds
[
1
][
0
]};
// x,y center offset in the source image
final
double
[][]
affine
=
ortho_maps
[
nmap
].
affine
;
final
double
[][]
affine
=
(
affines
!=
null
)
?
affines
[
indx
]:
ortho_maps
[
nmap
].
affine
;
// only here use provided
final
int
src_width
=
use_alt
?
ortho_maps
[
nmap
].
getAltData
().
width
:
ortho_maps
[
nmap
].
getImageData
().
width
;
final
int
src_height
=
use_alt
?
ortho_maps
[
nmap
].
getAltData
().
height
:
ortho_maps
[
nmap
].
getImageData
().
height
;
final
float
[]
src_img
=
use_alt
?
ortho_maps
[
nmap
].
getAltData
().
data
:
ortho_maps
[
nmap
].
getImageData
().
data
;
...
...
@@ -337,7 +487,7 @@ public class OrthoMapsCollection implements Serializable{
d01
*
kxy
[
0
]
*(
1.0
-
kxy
[
1
])+
d10
*(
1.0
-
kxy
[
0
])*
kxy
[
1
]+
d11
*
kxy
[
0
]
*
kxy
[
1
];
fpixels
[
f
nmap
][
opX
+
opY
*
width
]
=
(
float
)
d
;
fpixels
[
f
indx
][
opX
+
opY
*
width
]
=
(
float
)
d
;
}
}
}
...
...
@@ -349,12 +499,17 @@ public class OrthoMapsCollection implements Serializable{
return
fpixels
;
}
public
int
getIndex
(
String
sindx
)
{
return
map_index_string
.
get
(
sindx
);
}
public
float
[][]
getPaddedPairGPU
(
String
[]
spair
,
int
zoom_lev
){
int
[]
pair
=
new
int
[
spair
.
length
];
for
(
int
i
=
0
;
i
<
pair
.
length
;
i
++)
{
pair
[
i
]
=
map_index_string
.
get
(
spair
[
i
]);
pair
[
i
]
=
getIndex
(
spair
[
i
]);
}
return
getPaddedPairGPU
(
pair
,
// int [] pair,
...
...
@@ -421,30 +576,39 @@ public class OrthoMapsCollection implements Serializable{
public
double
[][]
correlateOrthoPair
(
CLTParameters
clt_parameters
,
boolean
batch_mode
,
String
[]
gpu_spair
,
double
[][][]
affines
,
// here in meters, relative to vertical points
int
zoom_lev
,
final
int
debugLevel
){
int
[]
gpu_pair
=
new
int
[
gpu_spair
.
length
];
for
(
int
i
=
0
;
i
<
gpu_pair
.
length
;
i
++)
{
gpu_pair
[
i
]
=
map_index_string
.
get
(
gpu_spair
[
i
]);
gpu_pair
[
i
]
=
getIndex
(
gpu_spair
[
i
]);
}
return
correlateOrthoPair
(
clt_parameters
,
// CLTParameters clt_parameters,
batch_mode
,
// boolean batch_mode,
gpu_pair
,
// int [] gpu_pair,
affines
,
// double [][][] affines, // here in meters, relative to vertical points
zoom_lev
,
// int zoom_lev,
debugLevel
);
// final int debugLevel)
}
private
double
[][]
correlateOrthoPair
(
double
[][]
correlateOrthoPair
(
CLTParameters
clt_parameters
,
boolean
batch_mode
,
int
[]
gpu_pair
,
double
[][][]
affines
,
// here in meters, relative to vertical points
int
zoom_lev
,
final
int
debugLevel
){
int
debugLevel
){
boolean
show_gpu_img
=
true
;
// (debugLevel > 1);
boolean
show_tile_centers
=
true
;
// (debugLevel > 1);
boolean
show_tile_centers
=
false
;
// true; // (debugLevel > 1);
if
(!
batch_mode
)
{
debugLevel
=
3
;
}
else
{
show_gpu_img
=
false
;
// (debugLevel > 1);
show_tile_centers
=
false
;
// true; // (debugLevel > 1);
}
double
[][]
bounds_overlap_meters
=
getOverlapMeters
(
gpu_pair
[
0
],
// int ref_index,
gpu_pair
[
1
],
// int other_index)
...
...
@@ -530,6 +694,10 @@ public class OrthoMapsCollection implements Serializable{
woi
.
height
=
OrthoMap
.
gpu_height
;
}
final
int
gpu_width
=
OrthoMap
.
gpu_width
;
// static
final
int
gpu_height
=
OrthoMap
.
gpu_height
;
// static
int
tilesX
=
gpu_width
/
GPUTileProcessor
.
DTT_SIZE
;
int
tilesY
=
gpu_height
/
GPUTileProcessor
.
DTT_SIZE
;
// uses fixed_size gpu image size
// TDCorrTile [] td_corr_tiles =
TpTask
[][]
tp_tasks
=
new
TpTask
[
2
][];
...
...
@@ -537,6 +705,11 @@ public class OrthoMapsCollection implements Serializable{
double
prev_rms
=
Double
.
NaN
;
double
rel_improve
=
1
E
-
3
;
for
(
int
ntry
=
0
;
ntry
<
num_tries
;
ntry
++)
{
if
(!
batch_mode
)
{
if
(
debugLevel
>-
3
)
{
System
.
out
.
println
(
"correlateOrthoPair(): ntry="
+
ntry
);
}
}
double
[][][]
vector_field
=
ComboMatch
.
rectilinearVectorField
(
//rectilinearCorrelate_TD( // scene0/scene1
clt_parameters
,
// final CLTParameters clt_parameters,
...
...
@@ -545,11 +718,90 @@ public class OrthoMapsCollection implements Serializable{
woi
,
// Rectangle woi, // if null, use full GPU window
affines_gpu
,
// final double [][][] affine, // [2][2][3] affine coefficients to translate common to 2 images
tp_tasks
,
// TpTask [][] tp_tasks_o,
fals
e
,
// final boolean batch_mode,
batch_mod
e
,
// final boolean batch_mode,
debugLevel
);
// final int debugLevel);
boolean
show_vector_field
=
!
batch_mode
&&
(
debugLevel
>
0
);
// true;
Rectangle
tile_woi
=
scaleRectangle
(
woi
,
GPUTileProcessor
.
DTT_SIZE
);
double
max_err
=
5.0
;
int
num_bins
=
1000
;
boolean
ignore_strength
=
false
;
double
frac_remove
=
0.25
;
double
[][]
vf_error2
=
new
double
[
vector_field
.
length
][];
// may be able to skip [0]
double
[][][]
vector_field_bkp
=
show_vector_field
?
new
double
[
vector_field
.
length
][][]:
null
;
if
(
vector_field_bkp
!=
null
)
{
for
(
int
i
=
0
;
i
<
vector_field_bkp
.
length
;
i
++)
{
vector_field_bkp
[
i
]
=
vector_field
[
i
].
clone
();
}
}
for
(
int
nvf_mode
=
0
;
nvf_mode
<
vector_field
.
length
;
nvf_mode
++)
{
vf_error2
[
nvf_mode
]
=
getVectorFieldError2
(
vector_field
[
nvf_mode
],
// double [][] vector_field,
tilesX
,
// int width, // tilesX
tile_woi
);
// Rectangle twoi); // in tiles
double
threshold
=
filterVectorField
(
vector_field
[
nvf_mode
],
// final double [][] vector_field,
vf_error2
[
nvf_mode
],
// final double [] vf_error2,
frac_remove
,
// final double frac_remove,
ignore_strength
,
// final boolean ignore_strength,
num_bins
,
// final int num_bins,
max_err
,
// final double max_err,
tilesX
,
// final int width, // tilesX
tile_woi
);
//final Rectangle twoi); // in tiles
if
(
debugLevel
>-
3
)
{
System
.
out
.
println
(
"vector_field layer= "
+
nvf_mode
+
" error threshold = "
+
threshold
+
" pix."
);
}
}
// TODO: use crop, keep (0,0) (woi.x+woi.width, woi.y+woi.height
if
(
vector_field_bkp
!=
null
)
{
// show_vector_field) {
// double [][] dbg_vf = new double [8 * vector_field.length][tilesX * tilesY];
int
dbg_width
=
tile_woi
.
x
+
tile_woi
.
width
;
int
dbg_height
=
tile_woi
.
y
+
tile_woi
.
height
;
double
[][][][]
vf_all
=
{
vector_field_bkp
,
vector_field
};
double
[][]
dbg_vf
=
new
double
[
8
*
vector_field
.
length
][
dbg_width
*
dbg_height
];
String
[]
dbg_titles
=
new
String
[
dbg_vf
.
length
];
String
[]
prefix
=
{
"single"
,
"single_filtered"
,
"neibs"
,
"neibs_filtered"
};
for
(
int
n
=
0
;
n
<
2
*
vector_field
.
length
;
n
++)
{
dbg_titles
[
4
*
n
+
0
]
=
prefix
[
n
]+
"-vx"
;
dbg_titles
[
4
*
n
+
1
]
=
prefix
[
n
]+
"-vy"
;
dbg_titles
[
4
*
n
+
2
]
=
prefix
[
n
]+
"-str"
;
dbg_titles
[
4
*
n
+
3
]
=
prefix
[
n
]+
"-err"
;
}
for
(
int
i
=
0
;
i
<
dbg_vf
.
length
;
i
++)
{
Arrays
.
fill
(
dbg_vf
[
i
],
Double
.
NaN
);
}
for
(
int
l
=
0
;
l
<
dbg_vf
[
0
].
length
;
l
++)
{
// local tile
int
lx
=
l
%
dbg_width
;
int
ly
=
l
/
dbg_width
;
int
t
=
lx
+
ly
*
tilesX
;
// full width
for
(
int
n
=
0
;
n
<
vector_field
.
length
;
n
++)
{
for
(
int
m
=
0
;
m
<
vf_all
.
length
;
m
++)
{
if
(
vf_all
[
m
][
n
][
t
]
!=
null
)
{
for
(
int
k
=
0
;
k
<
3
;
k
++)
{
dbg_vf
[
m
*
4
+
n
*
8
+
k
][
l
]
=
vf_all
[
m
][
n
][
t
][
k
];
}
// will automatically apply filtered
dbg_vf
[
m
*
4
+
n
*
8
+
3
][
l
]
=
Math
.
sqrt
(
vf_error2
[
n
][
t
]);
}
}
}
}
ShowDoubleFloatArrays
.
showArrays
(
dbg_vf
,
dbg_width
,
dbg_height
,
true
,
"vector_field"
,
dbg_titles
);
}
// may use tl_rect_metric to remap to the original image
double
[][]
tile_centers
=
new
double
[
vector_field
[
0
].
length
][];
int
tilesX
=
gpu_width
/
GPUTileProcessor
.
DTT_SIZE
;
for
(
TpTask
task:
tp_tasks
[
1
])
{
int
ti
=
task
.
getTileY
()
*
tilesX
+
task
.
getTileX
();
tile_centers
[
ti
]
=
task
.
getDoubleCenterXY
();
...
...
@@ -577,6 +829,11 @@ public class OrthoMapsCollection implements Serializable{
"tile_centers"
,
dbg_titles
);
}
if
(!
batch_mode
)
{
if
(
debugLevel
>-
3
)
{
System
.
out
.
println
(
"correlateOrthoPair(): before LMA, ntry="
+
ntry
);
}
}
OrthoPairLMA
orthoPairLMA
=
new
OrthoPairLMA
();
...
...
@@ -605,7 +862,7 @@ public class OrthoMapsCollection implements Serializable{
num_iter
,
// int num_iter, // 20
last_run
,
// boolean last_run,
debugLevel
);
// int debug_level)
if
(
debugLevel
>
-
1
)
{
if
(
debugLevel
>
-
3
)
{
System
.
out
.
println
(
"LMA result = "
+
lma_rslt
);
}
if
(
lma_rslt
<
0
)
{
...
...
@@ -613,10 +870,17 @@ public class OrthoMapsCollection implements Serializable{
return
null
;
}
double
rms
=
orthoPairLMA
.
getRms
();
if
(
debugLevel
>
-
3
)
{
System
.
out
.
println
(
"RMS= "
+
rms
+
" ("
+
orthoPairLMA
.
getInitialRms
()+
")"
);
}
if
(
rms
>
prev_rms
)
{
if
(
debugLevel
>
-
3
)
{
if
((
rms
-
prev_rms
)/
prev_rms
<
rel_improve
)
{
System
.
out
.
println
(
"LMA RMSE worsened, but less than improvement threshold: new"
+
rms
+
" ("
+
orthoPairLMA
.
getInitialRms
()+
"), prev="
+
prev_rms
);
}
else
{
System
.
out
.
println
(
"LMA RMSE worsened: new"
+
rms
+
" ("
+
orthoPairLMA
.
getInitialRms
()+
"), prev="
+
prev_rms
);
}
}
break
;
}
affines_gpu
[
1
]=
OrthoMap
.
combineAffine
(
affines_gpu
[
1
],
orthoPairLMA
.
getAffine
());
...
...
@@ -629,6 +893,25 @@ public class OrthoMapsCollection implements Serializable{
}
prev_rms
=
rms
;
}
// for (int ntry = 0; ntry < num_tries; ntry++) {
// unrapping backwards, for "other" map only, reference is not modified.
double
[]
tlo_src_metric_other
=
new
double
[
2
];
// check affines[][][] here -
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
// tlo_source_pixel[n][i] = (tlo_src_metric[n][i] + ortho_maps[gpu_pair[n]].vert_meters[i])/pix_size;
tlo_src_metric_other
[
i
]
=
affines_gpu
[
1
][
i
][
2
]
*
pix_size
-
ortho_maps
[
gpu_pair
[
1
]].
vert_meters
[
i
];
for
(
int
j
=
0
;
j
<
2
;
j
++)
{
affines
[
1
][
i
][
j
]
=
affines_gpu
[
1
][
i
][
j
];
}
}
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
affines
[
1
][
i
][
2
]
=
tlo_src_metric_other
[
i
]
-
tlo_rect_metric
[
1
][
0
]
*
affines
[
1
][
i
][
0
]
-
tlo_rect_metric
[
1
][
1
]
*
affines
[
1
][
i
][
1
];
}
if
(
debugLevel
>-
3
)
{
System
.
out
.
println
(
"correlateOrthoPair(): adjusted affines[1]"
);
System
.
out
.
println
(
"[["
+
affines
[
1
][
0
][
0
]+
","
+
affines
[
1
][
0
][
1
]+
","
+
affines
[
1
][
0
][
2
]+
"],"
);
System
.
out
.
println
(
" ["
+
affines
[
1
][
1
][
0
]+
","
+
affines
[
1
][
1
][
1
]+
","
+
affines
[
1
][
1
][
2
]+
"]]"
);
}
// analyze result, re-run correlation
...
...
@@ -666,6 +949,8 @@ public class OrthoMapsCollection implements Serializable{
}
*/
// modify affines[1]
if
(
debugLevel
>
1
)
{
// show result here
String
[]
map_names
=
{
ortho_maps
[
gpu_pair
[
0
]].
getName
(),
ortho_maps
[
gpu_pair
[
1
]].
getName
()};
ShowDoubleFloatArrays
.
showArrays
(
...
...
@@ -679,8 +964,135 @@ public class OrthoMapsCollection implements Serializable{
return
null
;
}
public
static
Rectangle
scaleRectangle
(
Rectangle
woi
,
int
tile_size
){
int
min_tx
=
woi
.
x
/
tile_size
;
int
min_ty
=
woi
.
y
/
tile_size
;
int
max_tx1
=
(
woi
.
x
+
woi
.
width
+
(
tile_size
-
1
))
/
tile_size
;
int
max_ty1
=
(
woi
.
y
+
woi
.
height
+
(
tile_size
-
1
))
/
tile_size
;
return
new
Rectangle
(
min_tx
,
min_ty
,
max_tx1
-
min_tx
,
max_ty1
-
min_ty
);
}
public
static
double
[]
getVectorFieldError2
(
double
[][]
vector_field
,
int
width
,
// tilesX
Rectangle
twoi
)
{
// in tiles
final
Rectangle
woi
=
(
twoi
!=
null
)?
twoi:
(
new
Rectangle
(
0
,
0
,
width
,
vector_field
.
length
/
width
));
final
int
num_tiles
=
woi
.
width
*
woi
.
height
;
final
int
tlTile
=
width
*
woi
.
y
+
woi
.
x
;
final
double
[]
vf_error2
=
new
double
[
vector_field
.
length
];
// Arrays.fill(vf_error2, Double.NaN);
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
num_tiles
;
nTile
=
ai
.
getAndIncrement
())
{
int
itileX
=
nTile
%
woi
.
width
;
int
itileY
=
nTile
/
woi
.
width
;
int
tile
=
tlTile
+
itileY
*
width
+
itileX
;
if
(
vector_field
[
tile
]
!=
null
)
{
double
[]
xys
=
vector_field
[
tile
];
vf_error2
[
tile
]
+=
xys
[
0
]*
xys
[
0
]+
xys
[
1
]*
xys
[
1
];
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
vf_error2
;
}
public
static
double
filterVectorField
(
final
double
[][]
vector_field
,
final
double
[]
vf_error2
,
final
double
frac_remove
,
final
boolean
ignore_strength
,
final
int
num_bins
,
final
double
max_err
,
final
int
width
,
// tilesX
final
Rectangle
twoi
)
{
// in tiles
final
Rectangle
woi
=
(
twoi
!=
null
)?
twoi:
(
new
Rectangle
(
0
,
0
,
width
,
vector_field
.
length
/
width
));
final
int
STRENGTH_INDEX
=
2
;
final
double
max_err2
=
max_err
*
max_err
;
final
double
scale
=
num_bins
/
max_err2
;
final
int
num_tiles
=
woi
.
width
*
woi
.
height
;
final
int
tlTile
=
width
*
woi
.
y
+
woi
.
x
;
final
Thread
[]
threads
=
ImageDtt
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
final
AtomicInteger
ati
=
new
AtomicInteger
(
0
);
final
double
[][]
hist2
=
new
double
[
threads
.
length
][
num_bins
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
int
thread_num
=
ati
.
getAndIncrement
();
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
num_tiles
;
nTile
=
ai
.
getAndIncrement
())
{
int
itileX
=
nTile
%
woi
.
width
;
int
itileY
=
nTile
/
woi
.
width
;
int
tile
=
tlTile
+
itileY
*
width
+
itileX
;
if
(!
Double
.
isNaN
(
vf_error2
[
tile
])
&&
(
vector_field
[
tile
]
!=
null
)){
// one test is enough
int
bin
=
(
int
)
Math
.
round
(
vf_error2
[
tile
]*
scale
);
if
(
bin
>=
num_bins
)
{
bin
=
num_bins
-
1
;
}
hist2
[
thread_num
][
bin
]
+=
ignore_strength
?
1.0
:
vector_field
[
tile
][
STRENGTH_INDEX
];
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
final
double
[]
hist
=
new
double
[
num_bins
];
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
bin
=
ai
.
getAndIncrement
();
bin
<
num_bins
;
bin
=
ai
.
getAndIncrement
())
{
for
(
int
i
=
0
;
i
<
hist2
.
length
;
i
++)
{
hist
[
bin
]+=
hist2
[
i
][
bin
];
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
double
sw
=
0
;
for
(
int
bin
=
0
;
bin
<
num_bins
;
bin
++)
{
sw
+=
hist
[
bin
];
}
double
aremove
=
sw
*
frac_remove
;
double
sh
=
0
,
shp
=
0
;
double
t2
=
max_err2
;
for
(
int
bin
=
num_bins
-
1
;
bin
>=
0
;
bin
--)
{
shp
=
sh
;
sh
+=
hist
[
bin
];
if
(
sh
>
aremove
)
{
double
r
=
(
sh
-
aremove
)/(
sh
-
shp
);
t2
=
(
bin
+
r
)/
scale
;
break
;
}
}
final
double
threshold2
=
t2
;
// remove bad tiles
ai
.
set
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
for
(
int
nTile
=
ai
.
getAndIncrement
();
nTile
<
num_tiles
;
nTile
=
ai
.
getAndIncrement
())
{
int
itileX
=
nTile
%
woi
.
width
;
int
itileY
=
nTile
/
woi
.
width
;
int
tile
=
tlTile
+
itileY
*
width
+
itileX
;
if
((
vector_field
[
tile
]
!=
null
)
&&
!(
vf_error2
[
tile
]
<=
threshold2
)){
vector_field
[
tile
]=
null
;
}
}
}
};
}
ImageDtt
.
startAndJoin
(
threads
);
return
Math
.
sqrt
(
threshold2
);
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java
View file @
24a92f5c
...
...
@@ -1101,6 +1101,7 @@ public class ImageDtt extends ImageDttCPU {
public
void
interRectilinearCorrTD
(
final
ImageDttParameters
imgdtt_params
,
// Now just extra correlation parameters, later will include, most others
final
boolean
batch_mode
,
final
int
erase_clt
,
final
float
[]
fpixels
,
final
int
[]
wh
,
// null (use sensor dimensions) or pair {width, height} in pixels
...
...
@@ -1136,27 +1137,27 @@ public class ImageDtt extends ImageDttCPU {
};
gpuQuad
.
setLpfRbg
(
// constants memory - same for all cameras
lpf_rgb
,
globalDebugLevel
>
2
);
!
batch_mode
&&
(
globalDebugLevel
>
2
)
);
final
float
[]
lpf_flat
=
floatGetCltLpfFd
(
gpu_sigma_corr
);
gpuQuad
.
setLpfCorr
(
// constants memory - same for all cameras
"lpf_corr"
,
// String const_name, // "lpf_corr"
lpf_flat
,
globalDebugLevel
>
2
);
!
batch_mode
&&
(
globalDebugLevel
>
2
)
);
final
float
[]
lpf_rb_flat
=
floatGetCltLpfFd
(
gpu_sigma_rb_corr
);
gpuQuad
.
setLpfCorr
(
// constants memory - same for all cameras
"lpf_rb_corr"
,
// String const_name, // "lpf_corr"
lpf_rb_flat
,
globalDebugLevel
>
2
);
!
batch_mode
&&
(
globalDebugLevel
>
2
)
);
final
float
[]
log_flat
=
floatGetCltHpfFd
(
gpu_sigma_log_corr
);
gpuQuad
.
setLpfCorr
(
// constants memory - same for all cameras
"LoG_corr"
,
// String const_name, // "lpf_corr"
log_flat
,
globalDebugLevel
>
2
);
if
(
globalDebugLevel
>
2
)
{
!
batch_mode
&&
(
globalDebugLevel
>
2
)
);
if
(
!
batch_mode
&&
(
globalDebugLevel
>
2
)
)
{
gpuQuad
.
printConstMem
(
"lpf_data"
,
true
);
gpuQuad
.
printConstMem
(
"lpf_corr"
,
true
);
gpuQuad
.
printConstMem
(
"lpf_rb_corr"
,
true
);
...
...
@@ -1176,7 +1177,7 @@ public class ImageDtt extends ImageDttCPU {
use_reference_buffer
,
wh
,
erase_clt
);
// put results into a "reference" buffer
if
(
globalDebugLevel
>
2
)
{
if
(
!
batch_mode
&&
(
globalDebugLevel
>
2
)
)
{
ComboMatch
.
renderFromTD
(
false
,
// boolean use_reference,
"img"
);
//String suffix
...
...
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