Commit 24a92f5c authored by Andrey Filippov's avatar Andrey Filippov

Testing DATI

parent b3e9f364
...@@ -42,12 +42,43 @@ public class ComboMatch { ...@@ -42,12 +42,43 @@ public class ComboMatch {
public static boolean openTestPairGps( public static boolean openTestPairGps(
CLTParameters clt_parameters, CLTParameters clt_parameters,
GPUTileProcessor gpu_tile_processor, // initialized by the caller GPUTileProcessor gpu_tile_processor, // initialized by the caller
final int debugLevel) { int debugLevel) {
GPU_TILE_PROCESSOR = gpu_tile_processor; 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 // 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 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 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}}}; 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; int gpu_width= clt_parameters.imp.rln_gpu_width; // 3008;
...@@ -58,6 +89,7 @@ public class ComboMatch { ...@@ -58,6 +89,7 @@ public class ComboMatch {
boolean use_saved_collection = true; // false; boolean use_saved_collection = true; // false;
boolean save_collection = true; boolean save_collection = true;
boolean process_correlation = true; // use false to save new version of data 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); 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 ("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."); gd.addStringField ("Maps collection save path", orthoMapsCollection_path, 180, "Save path for serialized map collection data.");
...@@ -87,6 +119,8 @@ public class ComboMatch { ...@@ -87,6 +119,8 @@ public class ComboMatch {
"GPU image height"); "GPU image height");
gd.addCheckbox ("Show transformation centers", show_centers, "Mark verticals from the UAS on the ground."); 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.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(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
...@@ -113,6 +147,10 @@ public class ComboMatch { ...@@ -113,6 +147,10 @@ public class ComboMatch {
show_centers = gd.getNextBoolean(); show_centers = gd.getNextBoolean();
use_alt = gd.getNextBoolean(); use_alt = gd.getNextBoolean();
gpu_spair[0] = gd.getNextString();
gpu_spair[1] = gd.getNextString();
OrthoMapsCollection maps_collection=null; OrthoMapsCollection maps_collection=null;
if (use_saved_collection) { if (use_saved_collection) {
try { try {
...@@ -125,9 +163,14 @@ public class ComboMatch { ...@@ -125,9 +163,14 @@ public class ComboMatch {
maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extensiohn maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extensiohn
} }
String [] names = maps_collection.getNames(); String [] names = maps_collection.getNames();
//getTemperature()
// get all temperatures
maps_collection. getAllTemperatures();
// which pair to compare // which pair to compare
int [] gpu_pair = {1,2}; // String [] gpu_spair = {names[gpu_ipair[0]],names[gpu_ipair[1]]};
String [] gpu_spair = {names[gpu_pair[0]],names[gpu_pair[1]]};
int [] origin = new int[2]; int [] origin = new int[2];
ImagePlus imp_img = maps_collection.renderMulti ( ImagePlus imp_img = maps_collection.renderMulti (
"multi_"+zoom_lev, // String title, "multi_"+zoom_lev, // String title,
...@@ -165,14 +208,73 @@ public class ComboMatch { ...@@ -165,14 +208,73 @@ public class ComboMatch {
} }
double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same 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}; 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( double [][] corr_pair_rslt = maps_collection.correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters, 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 affines, // double [][][] affines, // on top of GPS offsets
zoom_lev, // int zoom_lev, zoom_lev, // int zoom_lev,
debugLevel); // final int debugLevel) 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) { if (save_collection) {
try { try {
...@@ -188,6 +290,20 @@ public class ComboMatch { ...@@ -188,6 +290,20 @@ public class ComboMatch {
return true; 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 [] offset_xy_second = {0,0};
double [][] corr_pair_rslt = maps_collection. correlateOrthoPair( double [][] corr_pair_rslt = maps_collection. correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
...@@ -438,10 +554,10 @@ public class ComboMatch { ...@@ -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_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_g, // final double gpu_sigma_g, // 0.6, 0.7
clt_parameters.gpu_sigma_m, // final double gpu_sigma_m, // = 0.4; // 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 tilesX = img_width/GPUTileProcessor.DTT_SIZE;
int tilesY = wh[1]/GPUTileProcessor.DTT_SIZE; int tilesY = wh[1]/GPUTileProcessor.DTT_SIZE;
if (debugLevel > 1) { if (!batch_mode && (debugLevel > 1)) {
renderFromTD ( renderFromTD (
true, // boolean use_reference, true, // boolean use_reference,
"ref"); //String suffix "ref"); //String suffix
...@@ -453,6 +569,7 @@ public class ComboMatch { ...@@ -453,6 +569,7 @@ public class ComboMatch {
final double gpu_sigma_log_corr = clt_parameters.getGpuCorrLoGSigma(image_dtt.isMonochrome()); final double gpu_sigma_log_corr = clt_parameters.getGpuCorrLoGSigma(image_dtt.isMonochrome());
image_dtt.interRectilinearCorrTD( image_dtt.interRectilinearCorrTD(
clt_parameters.img_dtt, //final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others 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, erase_clt, // final int erase_clt,
fpixels[1], // final float [] fpixels, fpixels[1], // final float [] fpixels,
wh, // final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels wh, // final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels
...@@ -518,10 +635,8 @@ public class ComboMatch { ...@@ -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_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) rln_n_recenter); // final int n_recenter); // re-center window around new maximum. 0 -no refines (single-pass)
} }
boolean show_vector_field = (debugLevel>100); // true;
boolean show_vector_field = true; boolean show_2d_correlations = (debugLevel>0); // true;
boolean show_2d_correlations = true;
final int corr_size = 2 * GPUTileProcessor.DTT_SIZE -1; final int corr_size = 2 * GPUTileProcessor.DTT_SIZE -1;
if (show_2d_correlations) { if (show_2d_correlations) {
double [][] dbg_2d_corrs = ImageDtt.corr_partial_dbg( // not used in lwir double [][] dbg_2d_corrs = ImageDtt.corr_partial_dbg( // not used in lwir
......
...@@ -27,6 +27,7 @@ import com.elphel.imagej.common.ShowDoubleFloatArrays; ...@@ -27,6 +27,7 @@ import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.ims.Imx5; import com.elphel.imagej.ims.Imx5;
import com.elphel.imagej.readers.ElphelTiffReader; import com.elphel.imagej.readers.ElphelTiffReader;
import com.elphel.imagej.readers.ImagejJp4Tiff;
import com.elphel.imagej.tileprocessor.ImageDtt; import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters; import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import com.elphel.imagej.tileprocessor.QuadCLT; import com.elphel.imagej.tileprocessor.QuadCLT;
...@@ -41,6 +42,7 @@ import ij.plugin.filter.GaussianBlur; ...@@ -41,6 +42,7 @@ import ij.plugin.filter.GaussianBlur;
import ij.process.FloatProcessor; import ij.process.FloatProcessor;
import ij.process.ImageConverter; import ij.process.ImageConverter;
import ij.process.ImageProcessor; import ij.process.ImageProcessor;
import loci.formats.FormatException;
public class OrthoMap implements Comparable <OrthoMap>, Serializable{ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -55,6 +57,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -55,6 +57,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public transient String name; // timestamp public transient String name; // timestamp
public transient double ts; public transient double ts;
public transient String path; // full path to the model directory (including /vXX?) 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 double [] lla; // lat/long/alt
public LocalDateTime dt; public LocalDateTime dt;
// affine convert (input) rectified coordinates (meters) relative to vert_meters to source image // affine convert (input) rectified coordinates (meters) relative to vert_meters to source image
...@@ -69,6 +72,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -69,6 +72,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public int orig_zoom_level; public int orig_zoom_level;
public boolean orig_zoom_valid; public boolean orig_zoom_valid;
public double need_extra_zoom; 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; transient HashMap <Integer, FloatImageData> images;
HashMap <Double, PairwiseOrthoMatch> pairwise_matches; HashMap <Double, PairwiseOrthoMatch> pairwise_matches;
...@@ -76,6 +81,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -76,6 +81,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
private void writeObject(ObjectOutputStream oos) throws IOException { private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); oos.defaultWriteObject();
oos.writeObject(path); oos.writeObject(path);
oos.writeObject(scenes_path);
// lla is not transient // lla is not transient
// dt is not transient // dt is not transient
// affine is not transient // affine is not transient
...@@ -97,6 +103,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -97,6 +103,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
path = (String) ois.readObject(); path = (String) ois.readObject();
name = getNameFromPath(path); name = getNameFromPath(path);
ts= Double.parseDouble(name.replace("_", ".")); ts= Double.parseDouble(name.replace("_", "."));
scenes_path= (String) ois.readObject();
// lla is not transient // lla is not transient
// dt is not transient // dt is not transient
// affine is not transient // affine is not transient
...@@ -107,6 +114,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -107,6 +114,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
// orig_image was not saved // orig_image was not saved
// alt_image was not saved // alt_image was not saved
images = new HashMap <Integer, FloatImageData>(); // field images 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 is not transient
// pairwise_matches = new HashMap<Double, PairwiseOrthoMatch>(); // pairwise_matches = new HashMap<Double, PairwiseOrthoMatch>();
} }
...@@ -129,11 +138,14 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -129,11 +138,14 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public int getHeight() { public int getHeight() {
return orig_height; return orig_height;
} }
public int getOriginalZoomLevel() {
return orig_zoom_level;
}
// Generate ALT image path from the GEO // Generate ALT image path from the GEO
public static String getAltPath(String path) { public static String getAltPath(String path) {
int p1 = path.lastIndexOf("."); int p1 = path.lastIndexOf(".");
return path.substring(0,p1)+ALT_SUFFIX+".tiff"; return path.substring(0,p1)+ALT_SUFFIX+".tiff";
} }
public static String getNameFromPath(String path) { public static String getNameFromPath(String path) {
int p1 = path.lastIndexOf(Prefs.getFileSeparator()); int p1 = path.lastIndexOf(Prefs.getFileSeparator());
...@@ -143,8 +155,65 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -143,8 +155,65 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return path.substring(p1+1, p2); 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.path = path;
this.scenes_path = scenes_path;
name = getNameFromPath(path); name = getNameFromPath(path);
ts= Double.parseDouble(name.replace("_", ".")); ts= Double.parseDouble(name.replace("_", "."));
Properties imp_prop = null; Properties imp_prop = null;
...@@ -171,6 +240,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -171,6 +240,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
need_extra_zoom = FloatImageData.needZoomIn(orig_pix_meters); need_extra_zoom = FloatImageData.needZoomIn(orig_pix_meters);
images = new HashMap <Integer, FloatImageData>(); images = new HashMap <Integer, FloatImageData>();
pairwise_matches = new HashMap<Double, PairwiseOrthoMatch>(); 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{ ...@@ -221,6 +292,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
if (orig_image == null) { if (orig_image == null) {
readImageData(); readImageData();
} }
getAveragePixel();
return orig_image; return orig_image;
} }
public FloatImageData getAltData() { public FloatImageData getAltData() {
...@@ -246,9 +318,47 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -246,9 +318,47 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
if (orig_zoom_valid) { if (orig_zoom_valid) {
images.put(orig_zoom_level, orig_image); images.put(orig_zoom_level, orig_image);
} }
averageImagePixel = Double.NaN;
return true; 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 private boolean readAltData() { // assuming the same scale as main image
ImagePlus imp = new ImagePlus(getAltPath(path)); ImagePlus imp = new ImagePlus(getAltPath(path));
int width = imp.getWidth(); int width = imp.getWidth();
......
...@@ -33,7 +33,7 @@ import ij.gui.PointRoi; ...@@ -33,7 +33,7 @@ import ij.gui.PointRoi;
public class OrthoMapsCollection implements Serializable{ public class OrthoMapsCollection implements Serializable{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String [] KEY_DIRS= {"rootDirectory", // from EyesisCorrectionParameters public static final String [] KEY_DIRS= {"rootDirectory", // from EyesisCorrectionParameters
"sourceDirectory","linkedModels","videoDirectory","x3dDirectory","resultsDirectory"}; "sourceDirectory","linkedModels","videoDirectory","x3dDirectory","resultsDirectory","scenesDirectory"};
OrthoMap [] ortho_maps; OrthoMap [] ortho_maps;
transient HashMap<Double,Integer> map_index; transient HashMap<Double,Integer> map_index;
transient HashMap<String,Integer> map_index_string; transient HashMap<String,Integer> map_index_string;
...@@ -52,11 +52,15 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -52,11 +52,15 @@ public class OrthoMapsCollection implements Serializable{
public OrthoMapsCollection( public OrthoMapsCollection(
String path) { String path) {
if (path.endsWith(".list")) { 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 double [][] affine = {{1,0,0},{0,1,0}}; // maybe later calculate from mage_enuatr
ortho_maps = new OrthoMap[paths.length]; ortho_maps = new OrthoMap[paths.length];
for (int n = 0; n < ortho_maps.length; n++) { 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); ortho_maps[n].setAffine(affine);
} }
} }
...@@ -64,6 +68,28 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -64,6 +68,28 @@ public class OrthoMapsCollection implements Serializable{
reindex(); 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() { public int reindex() {
map_index = new HashMap<Double,Integer>(); map_index = new HashMap<Double,Integer>();
...@@ -87,8 +113,21 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -87,8 +113,21 @@ public class OrthoMapsCollection implements Serializable{
return names; return names;
} }
public void getAllTemperatures() {
for (int n = 0; n < ortho_maps.length; n++) {
ortho_maps[n].getTemperature();
}
}
public static String[] getPathsFromSorceList( public static String[] getPathsFromSorceList(
String files_list) { String files_list) {
return getPathsAndScenesFromSorceList(files_list, null);
}
public static String[] getPathsAndScenesFromSorceList(
String files_list,
String[] scenes0) {
List<String> lines; List<String> lines;
List<String> rel_files = new ArrayList<String>(); List<String> rel_files = new ArrayList<String>();
Path seq_path = Paths.get(files_list); Path seq_path = Paths.get(files_list);
...@@ -129,11 +168,16 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -129,11 +168,16 @@ public class OrthoMapsCollection implements Serializable{
sourceDirectory=(base_path.resolve(Paths.get(dir_map.get("sourceDirectory")))).toString(); sourceDirectory=(base_path.resolve(Paths.get(dir_map.get("sourceDirectory")))).toString();
} }
Path source_path = Paths.get(sourceDirectory); 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()]; String [] paths = new String[rel_files.size()];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
paths[i] = (source_path.resolve(Paths.get(rel_files.get(i)))).toString(); 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; return paths;
} }
...@@ -213,14 +257,21 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -213,14 +257,21 @@ public class OrthoMapsCollection implements Serializable{
String title, String title,
boolean use_alt, boolean use_alt,
boolean show_centers, boolean show_centers,
// OrthoMap [] maps,
int zoom_level, int zoom_level,
int [] origin){ 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]; int [] wh = new int[2];
double [][] centers = new double [ortho_maps.length][]; double [][] centers = new double [ortho_maps.length][];
float [][] multi = renderMulti ( float [][] multi = renderMulti (
use_alt, // boolean use_alt, use_alt, // boolean use_alt,
// maps, // OrthoMap [] maps,
zoom_level, // int zoom_level, zoom_level, // int zoom_level,
wh, // int [] wh, wh, // int [] wh,
origin, // int [] origin){ // maps[0] as a reference origin, // int [] origin){ // maps[0] as a reference
...@@ -245,10 +296,77 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -245,10 +296,77 @@ public class OrthoMapsCollection implements Serializable{
roi.setOptions("label"); roi.setOptions("label");
imp.setRoi(roi); 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; return imp;
} }
/** /**
* Rectify and render multiple images (as slices) matching vert_meters to * Rectify and render multiple images (as slices) matching vert_meters to
* their (vert_meters points) provided IMS coordinates * their (vert_meters points) provided IMS coordinates
...@@ -267,6 +385,23 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -267,6 +385,23 @@ public class OrthoMapsCollection implements Serializable{
int [] wh, int [] wh,
int [] origin, // maps[0] as a reference int [] origin, // maps[0] as a reference
double [][] centers){ 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 int [][] bounds = getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center
zoom_level); zoom_level);
int width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative int width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative
...@@ -279,33 +414,48 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -279,33 +414,48 @@ public class OrthoMapsCollection implements Serializable{
origin[0] = -bounds[0][0]; origin[0] = -bounds[0][0];
origin[1] = -bounds[1][0]; origin[1] = -bounds[1][0];
} }
final float [][] fpixels = new float [ortho_maps.length][width * height]; if (indices == null) {
for (int nmap = 0; nmap< ortho_maps.length; nmap++) { indices = new int [ortho_maps.length];
final int fnmap = nmap; for (int i = 0; i < indices.length; i++) {
Arrays.fill(fpixels[nmap], Float.NaN); 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 scale = 1.0/OrthoMap.getPixelSizeMeters(zoom_level);
final double src_scale = 1.0/OrthoMap.getPixelSizeMeters(ortho_maps[nmap].orig_zoom_level); // pix per meter 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 // 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]); double [] enu_offset = ortho_maps[0].enuOffsetTo(ortho_maps[nmap]);
final double [] scaled_out_center = { // xy center to apply affine to final double [] scaled_out_center = { // xy center to apply affine to
-bounds[0][0] + scale * enu_offset[0], -bounds[0][0] + scale * enu_offset[0],
-bounds[1][0] - scale * enu_offset[1]}; -bounds[1][0] - scale * enu_offset[1]};
if (centers != null) { 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 final int [][] obounds = new int [2][2]; // output (rectified, combined) image bounds, relative to thje top-left
for (int n = 0; n< 2; n++) { for (int n = 0; n< 2; n++) {
obounds[n][0] = (int) Math.floor(scaled_out_center[n] + scale*mbounds[n][0]); 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]); 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_width = obounds[0][1] - obounds[0][0];
final int ownd_height = obounds[1][1] - obounds[1][0]; final int ownd_height = obounds[1][1] - obounds[1][0];
final int ownd_len = ownd_width * ownd_height; 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 [] 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_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 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; 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{ ...@@ -337,7 +487,7 @@ public class OrthoMapsCollection implements Serializable{
d01* kxy[0] *(1.0 - kxy[1])+ d01* kxy[0] *(1.0 - kxy[1])+
d10*(1.0 - kxy[0])* kxy[1]+ d10*(1.0 - kxy[0])* kxy[1]+
d11* kxy[0] * kxy[1]; d11* kxy[0] * kxy[1];
fpixels[fnmap][opX + opY*width] = (float) d; fpixels[findx][opX + opY*width] = (float) d;
} }
} }
} }
...@@ -349,12 +499,17 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -349,12 +499,17 @@ public class OrthoMapsCollection implements Serializable{
return fpixels; return fpixels;
} }
public int getIndex(String sindx) {
return map_index_string.get(sindx);
}
public float [][] getPaddedPairGPU( public float [][] getPaddedPairGPU(
String [] spair, String [] spair,
int zoom_lev){ int zoom_lev){
int [] pair = new int [spair.length]; int [] pair = new int [spair.length];
for (int i = 0; i < pair.length; i++) { for (int i = 0; i < pair.length; i++) {
pair[i] = map_index_string.get(spair[i]); pair[i] = getIndex(spair[i]);
} }
return getPaddedPairGPU( return getPaddedPairGPU(
pair, // int [] pair, pair, // int [] pair,
...@@ -421,30 +576,39 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -421,30 +576,39 @@ public class OrthoMapsCollection implements Serializable{
public double [][] correlateOrthoPair( public double [][] correlateOrthoPair(
CLTParameters clt_parameters, CLTParameters clt_parameters,
boolean batch_mode,
String [] gpu_spair, String [] gpu_spair,
double [][][] affines, // here in meters, relative to vertical points double [][][] affines, // here in meters, relative to vertical points
int zoom_lev, int zoom_lev,
final int debugLevel){ final int debugLevel){
int [] gpu_pair = new int[gpu_spair.length]; int [] gpu_pair = new int[gpu_spair.length];
for (int i = 0; i < gpu_pair.length; i++) { 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( return correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
batch_mode, // boolean batch_mode,
gpu_pair, // int [] gpu_pair, gpu_pair, // int [] gpu_pair,
affines, // double [][][] affines, // here in meters, relative to vertical points affines, // double [][][] affines, // here in meters, relative to vertical points
zoom_lev, // int zoom_lev, zoom_lev, // int zoom_lev,
debugLevel); // final int debugLevel) debugLevel); // final int debugLevel)
} }
private double [][] correlateOrthoPair( double [][] correlateOrthoPair(
CLTParameters clt_parameters, CLTParameters clt_parameters,
boolean batch_mode,
int [] gpu_pair, int [] gpu_pair,
double [][][] affines, // here in meters, relative to vertical points double [][][] affines, // here in meters, relative to vertical points
int zoom_lev, int zoom_lev,
final int debugLevel){ int debugLevel){
boolean show_gpu_img = true; // (debugLevel > 1); 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( double [][] bounds_overlap_meters = getOverlapMeters(
gpu_pair[0], // int ref_index, gpu_pair[0], // int ref_index,
gpu_pair[1], // int other_index) gpu_pair[1], // int other_index)
...@@ -530,6 +694,10 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -530,6 +694,10 @@ public class OrthoMapsCollection implements Serializable{
woi.height = OrthoMap.gpu_height; woi.height = OrthoMap.gpu_height;
} }
final int gpu_width = OrthoMap.gpu_width; // static 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 // uses fixed_size gpu image size
// TDCorrTile [] td_corr_tiles = // TDCorrTile [] td_corr_tiles =
TpTask [][] tp_tasks = new TpTask [2][]; TpTask [][] tp_tasks = new TpTask [2][];
...@@ -537,6 +705,11 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -537,6 +705,11 @@ public class OrthoMapsCollection implements Serializable{
double prev_rms = Double.NaN; double prev_rms = Double.NaN;
double rel_improve = 1E-3; double rel_improve = 1E-3;
for (int ntry = 0; ntry < num_tries; ntry++) { for (int ntry = 0; ntry < num_tries; ntry++) {
if (!batch_mode) {
if (debugLevel>-3) {
System.out.println("correlateOrthoPair(): ntry="+ntry);
}
}
double [][][] vector_field = double [][][] vector_field =
ComboMatch.rectilinearVectorField(//rectilinearCorrelate_TD( // scene0/scene1 ComboMatch.rectilinearVectorField(//rectilinearCorrelate_TD( // scene0/scene1
clt_parameters, // final CLTParameters clt_parameters, clt_parameters, // final CLTParameters clt_parameters,
...@@ -545,11 +718,90 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -545,11 +718,90 @@ public class OrthoMapsCollection implements Serializable{
woi, // Rectangle woi, // if null, use full GPU window 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 affines_gpu, // final double [][][] affine, // [2][2][3] affine coefficients to translate common to 2 images
tp_tasks, // TpTask [][] tp_tasks_o, tp_tasks, // TpTask [][] tp_tasks_o,
false, // final boolean batch_mode, batch_mode, // final boolean batch_mode,
debugLevel); // final int debugLevel); 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 // may use tl_rect_metric to remap to the original image
double [][] tile_centers = new double [vector_field[0].length][]; double [][] tile_centers = new double [vector_field[0].length][];
int tilesX = gpu_width/GPUTileProcessor.DTT_SIZE;
for (TpTask task: tp_tasks[1]) { for (TpTask task: tp_tasks[1]) {
int ti = task.getTileY() * tilesX + task.getTileX(); int ti = task.getTileY() * tilesX + task.getTileX();
tile_centers[ti] = task.getDoubleCenterXY(); tile_centers[ti] = task.getDoubleCenterXY();
...@@ -577,6 +829,11 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -577,6 +829,11 @@ public class OrthoMapsCollection implements Serializable{
"tile_centers", "tile_centers",
dbg_titles); dbg_titles);
} }
if (!batch_mode) {
if (debugLevel>-3) {
System.out.println("correlateOrthoPair(): before LMA, ntry="+ntry);
}
}
OrthoPairLMA orthoPairLMA = new OrthoPairLMA(); OrthoPairLMA orthoPairLMA = new OrthoPairLMA();
...@@ -605,7 +862,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -605,7 +862,7 @@ public class OrthoMapsCollection implements Serializable{
num_iter, // int num_iter, // 20 num_iter, // int num_iter, // 20
last_run, // boolean last_run, last_run, // boolean last_run,
debugLevel); // int debug_level) debugLevel); // int debug_level)
if (debugLevel > -1) { if (debugLevel > -3) {
System.out.println("LMA result = "+lma_rslt); System.out.println("LMA result = "+lma_rslt);
} }
if (lma_rslt < 0) { if (lma_rslt < 0) {
...@@ -613,10 +870,17 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -613,10 +870,17 @@ public class OrthoMapsCollection implements Serializable{
return null; return null;
} }
double rms = orthoPairLMA.getRms(); double rms = orthoPairLMA.getRms();
if (debugLevel > -3) {
System.out.println("RMS= "+rms+" ("+orthoPairLMA.getInitialRms()+")");
}
if (rms > prev_rms) { if (rms > prev_rms) {
if (debugLevel > -3) { 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); System.out.println("LMA RMSE worsened: new"+rms+" ("+ orthoPairLMA.getInitialRms()+"), prev="+prev_rms);
} }
}
break; break;
} }
affines_gpu[1]=OrthoMap.combineAffine(affines_gpu[1], orthoPairLMA.getAffine()); affines_gpu[1]=OrthoMap.combineAffine(affines_gpu[1], orthoPairLMA.getAffine());
...@@ -629,6 +893,25 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -629,6 +893,25 @@ public class OrthoMapsCollection implements Serializable{
} }
prev_rms=rms; prev_rms=rms;
} // for (int ntry = 0; ntry < num_tries; ntry++) { } // 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 // analyze result, re-run correlation
...@@ -666,6 +949,8 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -666,6 +949,8 @@ public class OrthoMapsCollection implements Serializable{
} }
*/ */
// modify affines[1]
if (debugLevel > 1) {// show result here if (debugLevel > 1) {// show result here
String [] map_names = {ortho_maps[gpu_pair[0]].getName(),ortho_maps[gpu_pair[1]].getName()}; String [] map_names = {ortho_maps[gpu_pair[0]].getName(),ortho_maps[gpu_pair[1]].getName()};
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
...@@ -679,8 +964,135 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -679,8 +964,135 @@ public class OrthoMapsCollection implements Serializable{
return null; 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);
}
......
...@@ -1101,6 +1101,7 @@ public class ImageDtt extends ImageDttCPU { ...@@ -1101,6 +1101,7 @@ public class ImageDtt extends ImageDttCPU {
public void interRectilinearCorrTD( public void interRectilinearCorrTD(
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
final boolean batch_mode,
final int erase_clt, final int erase_clt,
final float [] fpixels, final float [] fpixels,
final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels final int [] wh, // null (use sensor dimensions) or pair {width, height} in pixels
...@@ -1136,27 +1137,27 @@ public class ImageDtt extends ImageDttCPU { ...@@ -1136,27 +1137,27 @@ public class ImageDtt extends ImageDttCPU {
}; };
gpuQuad.setLpfRbg( // constants memory - same for all cameras gpuQuad.setLpfRbg( // constants memory - same for all cameras
lpf_rgb, lpf_rgb,
globalDebugLevel > 2); !batch_mode && (globalDebugLevel > 2));
final float [] lpf_flat = floatGetCltLpfFd(gpu_sigma_corr); final float [] lpf_flat = floatGetCltLpfFd(gpu_sigma_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_corr", // String const_name, // "lpf_corr" "lpf_corr", // String const_name, // "lpf_corr"
lpf_flat, lpf_flat,
globalDebugLevel > 2); !batch_mode && (globalDebugLevel > 2));
final float [] lpf_rb_flat = floatGetCltLpfFd(gpu_sigma_rb_corr); final float [] lpf_rb_flat = floatGetCltLpfFd(gpu_sigma_rb_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_rb_corr", // String const_name, // "lpf_corr" "lpf_rb_corr", // String const_name, // "lpf_corr"
lpf_rb_flat, lpf_rb_flat,
globalDebugLevel > 2); !batch_mode && (globalDebugLevel > 2));
final float [] log_flat = floatGetCltHpfFd(gpu_sigma_log_corr); final float [] log_flat = floatGetCltHpfFd(gpu_sigma_log_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras gpuQuad.setLpfCorr(// constants memory - same for all cameras
"LoG_corr", // String const_name, // "lpf_corr" "LoG_corr", // String const_name, // "lpf_corr"
log_flat, log_flat,
globalDebugLevel > 2); !batch_mode && (globalDebugLevel > 2));
if (globalDebugLevel > 2) { if (!batch_mode && (globalDebugLevel > 2)) {
gpuQuad.printConstMem("lpf_data", true); gpuQuad.printConstMem("lpf_data", true);
gpuQuad.printConstMem("lpf_corr", true); gpuQuad.printConstMem("lpf_corr", true);
gpuQuad.printConstMem("lpf_rb_corr", true); gpuQuad.printConstMem("lpf_rb_corr", true);
...@@ -1176,7 +1177,7 @@ public class ImageDtt extends ImageDttCPU { ...@@ -1176,7 +1177,7 @@ public class ImageDtt extends ImageDttCPU {
use_reference_buffer, use_reference_buffer,
wh, wh,
erase_clt); // put results into a "reference" buffer erase_clt); // put results into a "reference" buffer
if (globalDebugLevel > 2) { if (!batch_mode && (globalDebugLevel > 2)) {
ComboMatch.renderFromTD ( ComboMatch.renderFromTD (
false, // boolean use_reference, false, // boolean use_reference,
"img"); //String suffix "img"); //String suffix
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment