Commit 758adc65 authored by Andrey Filippov's avatar Andrey Filippov

Working with single-image higher AGL (75 and 100)

parent 5e4e5577
......@@ -216,6 +216,31 @@ public class GenericJTabbedDialog implements ActionListener {
inp_units.putClientProperty("type", "combo");
// combo.setPreferredSize(new Dimension(200));
// combo.setSize(200, combo.getPreferredSize().height);
// combo.setMaximumSize(20); // combo.getPreferredSize() );
inp_units.setLayout(new FlowLayout(FlowLayout.LEFT));
addLine(label, inp_units, tooltip);
}
public void addChoice(String label, String[] items, String defaultItem, String tooltip, int count) {
int index = 0;
if (defaultItem != null) {
for (int i = 0; i < items.length; i++) if (items[i].equals(defaultItem)) {
index = i;
break;
}
}
JComboBox<String> combo = new JComboBox<String>(items);
combo.setSelectedIndex(index);
JPanel inp_units = new JPanel(false);
inp_units.add(combo);
inp_units.putClientProperty("type", "combo");
if (count > 0) {
combo.setMaximumRowCount(count);
}
// combo.setPreferredSize(new Dimension(200));
// combo.setSize(200, combo.getPreferredSize().height);
// combo.setMaximumSize(20); // combo.getPreferredSize() );
inp_units.setLayout(new FlowLayout(FlowLayout.LEFT));
......
......@@ -48,6 +48,11 @@ public class ComboMatch {
GPUTileProcessor gpu_tile_processor, // initialized by the caller
boolean extract_objects,
int debugLevel) {
boolean create_kernels = debugLevel>1000;
if (create_kernels) {
OrthoMap.combineKernels();
return true;
}
GPU_TILE_PROCESSOR = gpu_tile_processor;
PairwiseOrthoMatch pairwiseOrthoMatch = null;
String [] pair_names = new String[2];
......@@ -797,29 +802,46 @@ public class ComboMatch {
String [] choices = getPairChoices(
available_pairs, // int [][] pairs,
names); // String [] names)
String [] choices_all = new String[choices.length+1];
System.arraycopy(choices, 0, choices_all, 0, choices.length);
choices_all[choices_all.length-1] = "--- select a single image ---";
GenericJTabbedDialog gdc = new GenericJTabbedDialog("Select image pair",1200,400);
gdc.addChoice("Operation:", choices, choices[choices.length-1]);
int num_choice_lines = 50;
gdc.addChoice("Image pair:",
choices_all,
choices_all[choices.length], // -1],
"Select processed image pair or request a single image selection", num_choice_lines);
gdc.showDialog();
if (gdc.wasCanceled()) return false;
int pair= gdc.getNextChoiceIndex();
if (pair >= choices.length) {
int default_choice = 0;
int num_scene_lines = 50;
String scene_name = maps_collection.selectOneScene(
default_choice, // int default_choice,
num_scene_lines); // int num_choice_lines)
if (scene_name == null) {
return false;
}
gpu_spair = new String[] {scene_name};
} else {
gpu_spair = new String[] {
maps_collection.ortho_maps[available_pairs[pair][0]].getName(),
maps_collection.ortho_maps[available_pairs[pair][1]].getName()};
}
}
int [] gpu_pair = new int[gpu_spair.length];
int min_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
int max_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
for (int i = 0; i < gpu_pair.length; i++) {
gpu_pair[i] = maps_collection.getIndex(gpu_spair[i]);
min_zoom_lev = Math.min(min_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
max_zoom_lev = Math.max(max_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
}
int min_zoom_lev = Math.min(
maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel(),
maps_collection.ortho_maps[gpu_pair[1]].getOriginalZoomLevel());
int max_zoom_lev = Math.max(
maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel(),
maps_collection.ortho_maps[gpu_pair[1]].getOriginalZoomLevel());
int initial_zoom = max_zoom_lev - 4; // another algorithm?
System.out.println("Setting up GPU");
if (GPU_QUAD_AFFINE == null) {
try {
......@@ -836,13 +858,23 @@ public class ComboMatch {
return false;
} // final int debugLevel);
}
double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same
double [][] affine1 = null;
if (gpu_spair.length < 2) {
System.out.println("Selected a single image");
double [][][] affines = {affine0}; // or use affine1 = null as second?
if (pattern_match) {
ImagePlus imp_pat_match = maps_collection.patternMatchDualWrap (
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]
null); // warp); // FineXYCorr warp)
// imp_pat_match.show();
}
double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same
} else {
pairwiseOrthoMatch = maps_collection.ortho_maps[gpu_pair[0]].getMatch(
maps_collection.ortho_maps[gpu_pair[1]].getName());
double [][] affine1 = null;
if (pairwiseOrthoMatch == null) {
System.out.println("No correlation data is available for pairs "+gpu_spair[0]+
" - "+gpu_spair[1]+" need to implement/search reverse, a spiral search or restart command");
......@@ -853,7 +885,7 @@ public class ComboMatch {
double [][][] affines = {affine0,affine1};
int [] zooms = {initial_zoom, min_zoom_lev, 1000,1000}; // make automatic
double scale = 2.0; // scale vectors when warping;
// int num_tries = 5; // make configurable
// int num_tries = 5; // make configurable
if (!process_correlation) {
zooms = new int[] {min_zoom_lev, 1000};
num_tries_fit = 0;
......@@ -908,18 +940,21 @@ public class ComboMatch {
System.out.println();
}
}
if (pattern_match) {
ImagePlus imp_pat_match = maps_collection.patternMatchDualWrap (
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]
warp); // FineXYCorr warp)
// imp_pat_match.show();
// imp_pat_match.show();
}
if (render_match) {
ImagePlus imp_img_pair = maps_collection.renderMulti (
//_zoom<integer> is needed for opening with "Extract Objects" command
"multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"_zoom"+min_zoom_lev+"_"+zoom_lev, // String title,
// false, // boolean use_alt,
// false, // boolean use_alt,
OrthoMapsCollection.MODE_IMAGE, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask // boolean use_alt,
gpu_pair, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
bounds_to_indices, // boolean bounds_to_indices,
......@@ -934,6 +969,7 @@ public class ComboMatch {
}
}
}
}
if (save_collection) {
try {
maps_collection.writeOrthoMapsCollection(orthoMapsCollection_path);
......@@ -1132,8 +1168,8 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
pairs, // int [][] pairs,
scene_names); // String [] names)
GenericJTabbedDialog gds = new GenericJTabbedDialog("Select image pair",1200,400);
gds.addChoice("Operation:", choices, choices[choices.length-1]);
GenericJTabbedDialog gds = new GenericJTabbedDialog("Select image pair from the image",1200,400);
gds.addChoice("Image pair in the marked image:", choices, choices[choices.length-1]);
gds.showDialog();
if (gds.wasCanceled()) return null;
pair= gds.getNextChoiceIndex();
......
......@@ -46,6 +46,7 @@ import ij.ImageStack;
import ij.Prefs;
import ij.gui.PointRoi;
import ij.gui.Roi;
import ij.io.FileSaver;
import ij.plugin.filter.AVI_Writer;
import ij.plugin.filter.GaussianBlur;
import ij.process.ColorProcessor;
......@@ -1808,7 +1809,215 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
}
return point_arr;
}
///media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/kernels/
/*
/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/kernels/kernel_25_50.tiff
/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/kernels/kernel_50_100.tiff
/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/kernels/kernel_50_75.tiff
*/
public static void combineKernels() { // specific hard-wired kernels
String kernels_dir = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/kernels/";
String kernel_25_50_after = "kernel_25_50_after.tiff";
/*
String kernel_25_50 = "kernel_25_50.tiff";
String kernel_50_75 = "kernel_50_75.tiff";
String kernel_50_100 = "kernel_50_100.tiff";
String kernel_25_75 = "kernel_25_75.tiff";
String kernel_25_100 = "kernel_25_100.tiff";
*/
String [] kernels_paths = {
kernels_dir+kernel_25_50_after}; //
// kernels_dir+kernel_25_50,
// kernels_dir+kernel_50_75,
// kernels_dir+kernel_50_100};
double [][] kernels_data = new double [kernels_paths.length][];
for (int n = 0; n < kernels_data.length; n++) {
ImagePlus imp = new ImagePlus(kernels_paths[n]);
float [] pixels = (float []) imp.getProcessor().getPixels();
kernels_data[n] = new double [pixels.length];
for (int i = 0; i < pixels.length; i++) {
kernels_data[n][i] = pixels[i];
}
}
ArrayList<Double> scale_list = new ArrayList<Double>();
for (double scale = 1.5; scale < 3.0; scale += 0.05) {
scale_list.add(scale);
}
for (double scale = 3.0; scale <= 4.5; scale += 0.1) {
scale_list.add(scale);
}
for (double scale:scale_list) {
double [] dkernel_scaled = scaleKernel(scale, kernels_data[0]);
int size = (int) Math.sqrt(dkernel_scaled.length);
String title = String.format("kernel_25x%4.2f.tiff",scale);
ImagePlus imp_kernel = ShowDoubleFloatArrays.makeArrays(
dkernel_scaled,
size,
size,
title);
// imp_kernel.show();
String kpath = kernels_dir+title;
FileSaver imp_kernel_fs = new FileSaver(imp_kernel);
imp_kernel_fs.saveAsTiff(kpath);
// imp_kernel//
}
/*
double [] dkernel_25_75 = combineKernels(
kernels_data[0],
scaleKernel(2, kernels_data[1]));
double [] dkernel_25_100 = combineKernels(
kernels_data[0],
scaleKernel(2, kernels_data[2]));
double [] dkernel_25_50_2x = scaleKernel(2, kernels_data[0]);
double [] dkernel_25_50_3x = scaleKernel(3, kernels_data[0]);
double [] dkernel_25_50_4x = scaleKernel(4, kernels_data[0]);
int size_25_75 = (int) Math.sqrt(dkernel_25_75.length);
int size_25_100 = (int) Math.sqrt(dkernel_25_100.length);
ImagePlus [] imp_kernel = new ImagePlus[5];
imp_kernel[0] = ShowDoubleFloatArrays.makeArrays(
dkernel_25_75,
size_25_75,
size_25_75,
kernel_25_75);
imp_kernel[1] = ShowDoubleFloatArrays.makeArrays(
dkernel_25_100,
size_25_100,
size_25_100,
kernel_25_100);
imp_kernel[2] = ShowDoubleFloatArrays.makeArrays(
dkernel_25_50_2x,
(int) Math.sqrt(dkernel_25_50_2x.length),
(int) Math.sqrt(dkernel_25_50_2x.length),
"kernel_25_50_2x");
imp_kernel[3] = ShowDoubleFloatArrays.makeArrays(
dkernel_25_50_3x,
(int) Math.sqrt(dkernel_25_50_3x.length),
(int) Math.sqrt(dkernel_25_50_3x.length),
"kernel_25_50_3x");
imp_kernel[4] = ShowDoubleFloatArrays.makeArrays(
dkernel_25_50_4x,
(int) Math.sqrt(dkernel_25_50_4x.length),
(int) Math.sqrt(dkernel_25_50_4x.length),
"kernel_25_50_4x");
imp_kernel[0].show();
imp_kernel[1].show();
imp_kernel[2].show();
imp_kernel[3].show();
imp_kernel[4].show();
*/
System.out.println("combineKernels(): Created kernels");
}
/*
public static double [] scaleKernel(
int scale, // normally is exactly twice
double [] kernel1) {
int kernel_size1 = (int) Math.sqrt(kernel1.length);
int radius1 = (kernel_size1 - 1)/2;
int radius = scale * radius1;
int kernel_size = 2 * radius + 1;
double [] kernel = new double [kernel_size*kernel_size];
double rscale = 1.0/scale;
for (int dy = -radius; dy <= radius; dy++) {
int y = radius + dy;
double y_in = radius1 + dy*rscale;
int iy0 = (int) Math.floor(y_in);
double fy = y_in-iy0;
int iy1 = Math.min(iy0+1, kernel_size1-1);
for (int dx = -radius; dx <= radius; dx++) {
int x = radius + dx;
double x_in = radius1 + dx*rscale;
int ix0 = (int) Math.floor(x_in);
double fx = x_in-ix0;
int ix1 = Math.min(ix0+1, kernel_size1-1);
kernel[y*kernel_size + x] =
(1-fy)*(1-fx)*kernel1[iy0*kernel_size1+ix0]+
(1-fy)*( fx)*kernel1[iy0*kernel_size1+ix1]+
( fy)*(1-fx)*kernel1[iy1*kernel_size1+ix0]+
( fy)*( fx)*kernel1[iy1*kernel_size1+ix1];
}
}
return kernel;
}
*/
public static double [] scaleKernel(
double scale, // normally is exactly twice
double [] kernel1) {
int kernel_size1 = (int) Math.sqrt(kernel1.length);
int radius1 = (kernel_size1 - 1)/2;
int radius = (int) Math.floor(scale * radius1);
int kernel_size = 2 * radius + 1;
double [] kernel = new double [kernel_size*kernel_size];
double rscale = 1.0/scale;
for (int dy = -radius; dy <= radius; dy++) {
int y = radius + dy;
double y_in = radius1 + dy*rscale;
int iy0 = (int) Math.floor(y_in);
double fy = y_in-iy0;
int iy1 = Math.min(iy0+1, kernel_size1-1);
for (int dx = -radius; dx <= radius; dx++) {
int x = radius + dx;
double x_in = radius1 + dx*rscale;
int ix0 = (int) Math.floor(x_in);
double fx = x_in-ix0;
int ix1 = Math.min(ix0+1, kernel_size1-1);
kernel[y*kernel_size + x] =
(1-fy)*(1-fx)*kernel1[iy0*kernel_size1+ix0]+
(1-fy)*( fx)*kernel1[iy0*kernel_size1+ix1]+
( fy)*(1-fx)*kernel1[iy1*kernel_size1+ix0]+
( fy)*( fx)*kernel1[iy1*kernel_size1+ix1];
}
}
// normalize result
double s = 0;
for (int i = 0; i < kernel.length; i++) s+= kernel[i];
System.out.println("scaleKernel(): s="+s);
double k = 1/s;
for (int i = 0; i < kernel.length; i++) kernel[i] *= k;
return kernel;
}
public static double [] combineKernels(
double [] kernel1,
double [] kernel2) {
int kernel_size1 = (int) Math.sqrt(kernel1.length);
int kernel_size2 = (int) Math.sqrt(kernel2.length);
int kernel_radius1 = (kernel_size1 - 1)/2;
int kernel_radius2 = (kernel_size2 - 1)/2;
int kernel_radius = kernel_radius1 + kernel_radius2;
int kernel_size = 2*kernel_radius + 1;
double [] kernel = new double [kernel_size * kernel_size];
int indx_tl = kernel_radius2 * (kernel_size + 1);
for (int y = 0; y < kernel_size1; y++) {
System.arraycopy(
kernel1,
y* kernel_size1,
kernel,
indx_tl + y * kernel_size,
kernel_size1);
}
kernel = convolveWithKernel(
kernel, // final double [] data,
kernel2, // final double [] kernel,
kernel_size); // final int width);
// normalize result
double s = 0;
for (int i = 0; i < kernel.length; i++) s+= kernel[i];
System.out.println("combineKernels(): s="+s);
double k = 1/s;
for (int i = 0; i < kernel.length; i++) kernel[i] *= k;
return kernel;
}
public static double [] convolveWithKernel(
......@@ -1864,6 +2073,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
* @param ipattern square pattern array corresponding to data. 1 means
* average (w/o outliers) and add, 2 - average and subtract
* @param outliers_frac - fraction of outliers to remove while averaging
* @param masked_data null or double[data.length] - will return a copy of data
* with NaN for all unused for averaging
* @param debug show debug images
* @return difference between average in-pattern (1) and outside (2) average
* values
......@@ -1872,6 +2083,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
double [] data,
int [] ipattern,
double outliers_frac,
double [] masked_data, // null or double [data.length] to return masked data
boolean debug) {
if (debug) {
int size = (int) Math.sqrt(data.length);
......@@ -1925,6 +2137,15 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
}
}
}
if (masked_data != null) {
Arrays.fill(masked_data, Double.NaN);
for (int n = 0; n < lists.size(); n++) {
ArrayList<Integer> list = lists.get(n);
for (Integer i: list) {
masked_data[i] = data[i];
}
}
}
if (debug) {
int [] ipattern1 = new int [ipattern.length];
for (int n = 0; n < lists.size(); n++) {
......@@ -4074,7 +4295,9 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
final int dbg_pix0= 1439210; // -2827822; // 3649679;// #3
final int dbg_pix2 = 1442449; // -2831060;
final int dbg_pix3 = 1439211; // 2827822;
final int dbg_x = 1445;
final int dbg_y = 2338;
final int dbg_tolerance = 10;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -4097,6 +4320,15 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
break is_max;
}
}
if (dbg_tolerance >= 0) {
int dbg_px = ipix % width;
int dbg_py = ipix / width;
if ((Math.abs(dbg_px-dbg_x) <= dbg_tolerance) || (Math.abs(dbg_py-dbg_y) <= dbg_tolerance)) {
System.out.println("combineDirCorrs(): ipix="+ipix+
", dbg_px="+dbg_px+", dbg_py="+dbg_py);
System.out.println();
}
}
// compare with others in adversarial radius, if equal - use higher index ipix
for (int dy = -iradius; dy <= iradius; dy++) {
for (int dx = -iradius; dx <= iradius; dx++) {
......
......@@ -762,7 +762,7 @@ public class OrthoMapsCollection implements Serializable{
}
public double [][] renderMultiDouble (
public double [][] renderMultiDouble ( // should work with just a single image (indice.length ==1)?
boolean use_alt,
int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
boolean bounds_to_indices,
......@@ -1463,11 +1463,14 @@ public class OrthoMapsCollection implements Serializable{
double [] object_offset,
double [] scene_offset) {
double l1 = Math.sqrt(scene_offset[0]*scene_offset[0] + scene_offset[1]*scene_offset[1]);
if (!(l1 > 0.00001)) {
double [] offs_rot = new double [2];
offs_rot[0] = ( object_offset[0]*scene_offset[0] + object_offset[1]*scene_offset[1]) / l1;
offs_rot[1] = (-object_offset[0]*scene_offset[1] + object_offset[1]*scene_offset[0]) / l1;
return offs_rot;
}
return object_offset;
}
/**
* Estimate object height if its offset between image is caused by its elevation
......@@ -1755,18 +1758,17 @@ public class OrthoMapsCollection implements Serializable{
int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
double [][][] affines, // null or [indices.length][2][3]
FineXYCorr warp) { // use for a single pair only
// double [] min_corrs = {0.008, 0.0035}; // morning/evening
// double [] min_corrs = {0.0095, 0.0035}; // morning/evening
double [] min_corrs = {0.0085, 0.0036}; // 0.0035}; // morning/evening
//indices //getAGL()
double scene0_agl = ortho_maps[indices[0]].getAGL();
//int min_zoom_lev = ortho_maps[indices[0]].getOriginalZoomLevel();
double [] min_corrs = {0.009, 0.0036}; // 0.0035}; // morning/evening
double [] phaseCoeff = {0.98,0.5};
// double min_corr_full_rel = 0.75; // try 0.85
double min_corr_full_rel = 0.85; // try 0.85
double full_preference = 1.4;
double max_min_ratio = 3.0;
boolean[] combine_full = {true, true}; // try for other olso?
int corr_size = 128; // pix
double adv_radius = 30.0; // cm
double adv_radius = 30.0; // cm ?
double search_radius = 15; // look for other scene max within this distance from main
String object_type = "TM62";
double scale_warp = 1.0; // use 4?
......@@ -1775,9 +1777,12 @@ public class OrthoMapsCollection implements Serializable{
// creating filters for absolute contrast calculation (main scene only)
double abs_edge_frac = 0.25;
double abs_oversize = 1.8;
int abs_mode = 1; // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
boolean abs_force_round = false; // after selection best pattern, force full pattern
int abs_mode = 1; // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any, force full pattern
boolean abs_invert = true; // center has lower value than around
double abs_outliers_frac = 0.3;
boolean abs_obscure_warm = true; // obscured can only be by warmer objects
double abs_obscure_frac = 0.25; // obscured threshold between center and outer
// filters
boolean filt_keep = false; // list filtered out, but actually keep them
......@@ -1795,11 +1800,34 @@ public class OrthoMapsCollection implements Serializable{
double filt_height = 0.2; // allow extra negative offset parallel to image offset, corresponding to object above ground
// double [] filt_full_half_frac = {0.7, 0.5}; // second probably not needed, it is for main
double [] filt_full_half_frac = {0.675, 0.5}; // second probably not needed, it is for main
double filt_abs_contrast = 50.0;
double filt_abs_contrast = 80.0; // 50.0;
double filt_abs_easepart = 1.0; // 1.0-no ease for low AGL. Allow lower absolute contrast for partial patterns (high AGL)
boolean convolve_after = false; // true for old kernel tuning (kernel decimation before convolution)
int debugLevel = 1;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Correlate two images with patterns",1200,1100);
// Overwrite some defaults based on AGL
if (scene0_agl > ((50+75)/2)) {
if (scene0_agl < ((75+100)/2)) { // 75m defaults
min_corrs[0] = 0.0119;
abs_edge_frac = 0.35;
abs_oversize = 2.2;
filt_abs_contrast = 75;
filt_abs_easepart = 0.85;
phaseCoeff[0] = 0.9;
// adv_radius = 20; // pix?
} else { // 100m defaults
min_corrs[0] = 0.009;
abs_edge_frac = 0.35;
abs_oversize = 2.2;
filt_abs_contrast = 60;
filt_abs_easepart = 0.85;
phaseCoeff[0] = 0.9;
// adv_radius = 20; // pix?
}
}
GenericJTabbedDialog gd = new GenericJTabbedDialog("Correlate "+((indices.length==1)? "one image":"two images")+" with patterns",1200,1100);
gd.addTab("General","General parameters");
gd.addStringField ("Object type", object_type, 20,"Object type/name.");
gd.addNumericField("Minimal correlation, first", min_corrs[0], 5,7,"","Minimal correlation value to keep, first scene.");
......@@ -1817,13 +1845,19 @@ public class OrthoMapsCollection implements Serializable{
gd.addNumericField("Scale warp", scale_warp, 1,6,"x", "Scale second image warping.");
gd.addNumericField("Extract object size", extr_size, 0,4,"", "Size of square object image to extract.");
gd.addCheckbox ("Remove DC", remove_dc, "Remove DC in extracted object images.");
gd.addMessage("Mitigating what seems to be a bug - kernels tuned to be convolved after decimation. Should be opposite?");
gd.addCheckbox ("Convolve after zoom out", convolve_after, "Zoom patterns before convolving with resolution-matching kernels.");
gd.addTab("Absolute Contrast","Preparing absolute contrast measurements for the main scene");
gd.addNumericField("Edge cutt-off fraction (<0.5)", abs_edge_frac, 5,7,"","Used for extracting inner and outer zones from tha existing patterns.");
gd.addNumericField("Radius of outer ring to pattern radius",abs_oversize, 5,7,"","Outer ring external radius as a mupltile of the pattern radius.");
gd.addCheckbox ("Force round", abs_force_round, "Force round pattern and recheck \"best\" correlation value.");
gd.addNumericField("Update subpattern mode", abs_mode, 0,4,"", "0 - keep, 1 keep type and if half, only change by +/-1, 2 - keep type, 3 - any.");
gd.addCheckbox ("Cold center", abs_invert, "Center pattern values are lower than around.");
gd.addNumericField("Outlier fraction when averaging", abs_outliers_frac, 5,7,"","Discard this fraction of pixels in inner and outer zones when averaging.");
gd.addCheckbox ("May be obscured only by warmer", abs_obscure_warm, "Half-pattern objects may be obscured by warmer (for cold objects).");
gd.addNumericField("\"warmer\" threshold", abs_obscure_frac, 5,7,"","Threshold fraction between average center and average around ring.");
gd.addTab("Filters","Filtering results to reduce false positives");
gd.addCheckbox ("Keep filtered out", filt_keep, "List filtered out, but actaually keep them.");
......@@ -1848,6 +1882,7 @@ public class OrthoMapsCollection implements Serializable{
gd.addNumericField("Full/half corr minimal ratio, main",filt_full_half_frac[0], 5,7,"","Minimal correlation with full pattern strength ratio to correlation with a half-pattern.");
gd.addNumericField("Full/half corr minimal ratio, other",filt_full_half_frac[1], 5,7,"","Minimal correlation with full pattern strength ratio to correlation with a half-pattern.");
gd.addNumericField("Minimal absolute contrast", filt_abs_contrast, 5,7,"","Minimal absolute difference between center and peripheral areas of the main scene objects.");
gd.addNumericField("Ease absolute contrast for halves", filt_abs_easepart, 5,7,"","Ease absolute contast requirements for high AGL (low resolution).");
//
gd.addNumericField("Debug level", debugLevel, 0,4,"", "Debug level.");
gd.showDialog();
......@@ -1869,11 +1904,16 @@ public class OrthoMapsCollection implements Serializable{
extr_size= (int) gd.getNextNumber();
remove_dc= gd.getNextBoolean();
convolve_after= gd.getNextBoolean();
abs_edge_frac = gd.getNextNumber();
abs_oversize = gd.getNextNumber();
abs_force_round= gd.getNextBoolean();
abs_mode = (int) gd.getNextNumber();
abs_invert = gd.getNextBoolean();
abs_outliers_frac = gd.getNextNumber();
abs_obscure_warm= gd.getNextBoolean();
abs_obscure_frac = gd.getNextNumber();
filt_keep= gd.getNextBoolean();
filt_atonce= gd.getNextBoolean();
......@@ -1897,7 +1937,7 @@ public class OrthoMapsCollection implements Serializable{
filt_full_half_frac[0]=gd.getNextNumber();
filt_full_half_frac[1]=gd.getNextNumber();
filt_abs_contrast= gd.getNextNumber();
filt_abs_easepart= gd.getNextNumber();
debugLevel= (int) gd.getNextNumber();
return patternMatchDual (
......@@ -1919,9 +1959,12 @@ public class OrthoMapsCollection implements Serializable{
remove_dc, // boolean remove_dc,
abs_edge_frac, // double abs_edge_frac, // = 0.25;
abs_oversize, // double abs_oversize, // = 1.8;
abs_force_round, // boolean abs_force_round,
abs_mode, // int abs_mode, // = 1; // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
abs_invert, // boolean abs_invert, // = true; // center has lower value than around
abs_outliers_frac, // double abs_outliers_frac,
abs_obscure_warm, // boolean abs_obscure_warm, // = true; // obscured can only be by warmer objects
abs_obscure_frac, // double abs_obscure_frac, // 0.25; // obscured threshold between center and outer
filt_keep, // boolean filt_keep,
filt_atonce, // boolean filt_atonce,
filt_frac_max, // double frac_max, // measure are at fraction of max
......@@ -1933,6 +1976,8 @@ public class OrthoMapsCollection implements Serializable{
filt_height, // double filt_height,
filt_full_half_frac, // double [] filt_full_half_frac,
filt_abs_contrast, // double filt_abs_contrast, // = 50.0;
filt_abs_easepart, // double filt_abs_easepart,
convolve_after, // boolean convolve_after,
debugLevel); // int debugLevel)
}
......@@ -1955,9 +2000,12 @@ public class OrthoMapsCollection implements Serializable{
boolean remove_dc,
double abs_edge_frac, // = 0.25;
double abs_oversize, // = 1.8;
boolean abs_force_round,
int abs_mode, // = 1; // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
boolean abs_invert, // = true; // center has lower value than around
double abs_outliers_frac,
boolean abs_obscure_warm, // = true; // obscured can only be by warmer objects
double abs_obscure_frac, // 0.25; // obscured threshold between center and outer
boolean filt_keep,
boolean filt_atonce,
double frac_max, // measure are at fraction of max
......@@ -1969,16 +2017,22 @@ public class OrthoMapsCollection implements Serializable{
double filt_height,
double [] filt_full_half_frac,
double filt_abs_contrast, // = 50.0;
double filt_abs_easepart,
boolean convolve_after, // mitigating kernels tuned for decimate before convolve
int debugLevel) {
if (warp != null) {
warp.scale_warp = scale_warp;
int corr_radius = (int) (Math.sqrt(0.5)* adv_radius) -1 ;
}
int last_scene = indices.length-1;
// int corr_radius = (int) (Math.sqrt(0.5)* adv_radius) -1 ;
// String title_match = OrthoMap.removeKnownExtension(imp_src.getTitle())+"-PATTERN_CORRS"
int min_zoom_lev = Math.min(
ortho_maps[indices[0]].getOriginalZoomLevel(),
ortho_maps[indices[1]].getOriginalZoomLevel());
int max_zoom_lev = Math.max(
ortho_maps[indices[0]].getOriginalZoomLevel(),
ortho_maps[indices[1]].getOriginalZoomLevel());
int min_zoom_lev = ortho_maps[indices[0]].getOriginalZoomLevel();
int max_zoom_lev = ortho_maps[indices[0]].getOriginalZoomLevel();
for (int i = 0; i < indices.length; i++) {
min_zoom_lev = Math.min(min_zoom_lev, ortho_maps[indices[i]].getOriginalZoomLevel());
max_zoom_lev = Math.max(max_zoom_lev, ortho_maps[indices[i]].getOriginalZoomLevel());
}
int zoom_level = min_zoom_lev;
int [] wh = new int[2];
int [] origin = new int[2];
......@@ -1993,8 +2047,24 @@ public class OrthoMapsCollection implements Serializable{
wh, // int [] wh,
origin, // int [] origin){ // maps[0] as a reference
centers); // double [][] centers)
int width = wh[0];
int height = wh[1];
String [] dbg_titles = new String[dmulti.length];
for (int i = 0; i < dbg_titles.length; i++) {
dbg_titles[i] = ""+i;
}
ImagePlus img_first = ShowDoubleFloatArrays.makeArrays(
dmulti,
width,
height,
ortho_maps[indices[0]].getName(),
dbg_titles);
img_first.show();
//makeArrays(double[][] pixels, int width, int height, String title)
double [][] src_marks = null;
double [][][] patterns_all = new double [indices.length][][];
......@@ -2023,15 +2093,19 @@ public class OrthoMapsCollection implements Serializable{
ImagePlus [] imps_patt_corrs = new ImagePlus[indices.length];
ImagePlus [] imps_patt_conv = new ImagePlus[indices.length];
ImagePlus [] imps_extracted = new ImagePlus[indices.length];
ImagePlus [] imps_masked = new ImagePlus[indices.length];
ImagePlus [] imps_extracted_corr = new ImagePlus[indices.length];
ImagePlus [] imps_extracted_corr_half = new ImagePlus[indices.length];
ArrayList <ItemMatch> matches_list = new ArrayList <ItemMatch>();
double [][][] extracted_objects = new double [indices.length][][];
double [][][] extracted_masked = new double [indices.length][][];
double [][][] extr_corr = new double [indices.length][][];
// double [][][] extr_corr_best = new double [indices.length][][]; // only for main - already combined
double [][][] extr_corr_half = new double [indices.length][][];
double [][][][] filter_data = new double [indices.length][][][]; // [scene][max][0-full, 1 - half][0- max, 1 - area, 2 - distance]
double [] adv_radii = new double[indices.length];
int [] corr_radius = new int [indices.length];
// int [] best_patt_indx;
for (int scene_num = 0; scene_num < indices.length; scene_num++) { // will probably just use first one, second - derivative
gops[scene_num] = GroundObjectPattern.getPattern(
......@@ -2042,6 +2116,14 @@ public class OrthoMapsCollection implements Serializable{
System.out.println("Failed to find a pattern for object \""+object_type+"\", aborting operation.");
return null;
}
zoomout[scene_num] = 1;
for (int i = zoom_level; i < gops[scene_num].getZoomLevel();i++) {
zoomout[scene_num] *= 2;
}
adv_radii[scene_num] = adv_radius/zoomout[scene_num];
corr_radius[scene_num] = (int) (Math.sqrt(0.5)* adv_radii[scene_num]) -1 ;
ImagePlus imp_pattern = new ImagePlus(gops[scene_num].getPatternPath());
pattern_sizes[scene_num] = imp_pattern.getWidth();
if (pattern_sizes[scene_num] == 0) {
......@@ -2080,12 +2162,8 @@ public class OrthoMapsCollection implements Serializable{
convolve_out[scene_num] = new double[patterns_all[scene_num].length][];
corr_patterns[scene_num] = new double[patterns_all[scene_num].length][];
zoomout[scene_num] = 1;
for (int i = zoom_level; i < gops[scene_num].getZoomLevel();i++) {
zoomout[scene_num] *= 2;
}
for (int n = 0; n < patterns_all[scene_num].length; n++) {
if (convolve_after) {
corr_patterns[scene_num][n] = OrthoMap.patternZoomCropPad(
patterns_all[scene_num][n], // double [] pattern,
pattern_sizes[scene_num], // int pattern_size,
......@@ -2098,9 +2176,34 @@ public class OrthoMapsCollection implements Serializable{
kernels_all[scene_num], // final double [] kernel,
corr_size); // final int width)
}
} else {
double [] pattern = patterns_all[scene_num][n].clone();
if (kernels_all[scene_num] != null) {
pattern = OrthoMap.convolveWithKernel(
pattern, // final double [] data,
kernels_all[scene_num], // final double [] kernel,
pattern_sizes[scene_num]); // final int width)
}
corr_patterns[scene_num][n] = OrthoMap.patternZoomCropPad(
pattern, // double [] pattern,
pattern_sizes[scene_num], // int pattern_size,
corr_size, // int size,
zoomout[scene_num], // int zoomout,
false); // out_normalize); // boolean normalize)
}
}
if (debugLevel > 0) {
ShowDoubleFloatArrays.showArrays(
corr_patterns[scene_num],
corr_size,
corr_size,
true,
"pattern-"+scene_num+"_"+corr_size+"x"+corr_size+(convolve_after?"_convolved_after":"_convolved_before"));
}
if (scene_num == 0) {
boolean debug = debugLevel > 1;
boolean debug = debugLevel > 0; // 1;
icorr_patterns[scene_num] = OrthoMap.getIntPatterns(
corr_patterns[scene_num], // double [][] patterns,
abs_edge_frac, // double edge_frac, // 0.15
......@@ -2128,7 +2231,7 @@ public class OrthoMapsCollection implements Serializable{
corrs_out[scene_num],
width,
height,
ortho_maps[indices[scene_num]].getName()+"-PATTERN_CORRS",
ortho_maps[indices[scene_num]].getName()+"-PATTERN_CORRS_PC"+phaseCoeff[scene_num],
patt_titles); // test_titles,
if (src_marks != null) {
PointRoi roi = new PointRoi();
......@@ -2156,8 +2259,8 @@ public class OrthoMapsCollection implements Serializable{
full_preference, // final double full_preference,
max_min_ratio, // final double max_min_ratio,
combine_full[0], // final boolean combine_full, // multiply by normalized full pattern correlation maximum
adv_radius, // final double adv_radius,
corr_radius); // final int corr_radius)
adv_radii[scene_num], // final double adv_radius,
corr_radius[scene_num]); // final int corr_radius)
// GroundObjectPattern gop = gops[scene_num];
for (Point p : plist) {
double [] matches = new double [corrs_out[scene_num].length + 1];
......@@ -2279,6 +2382,7 @@ public class OrthoMapsCollection implements Serializable{
// extract already calculated correlations for scene 0
filter_data[scene_num] = new double[match_sort.size()][2][]; // [scene][max][0-full, 1 - half][0- max, 1 - area, 2 - distance]
extr_corr[scene_num] = new double [match_sort.size()][]; // extracted_objects[scene_num].length][];
extracted_masked[scene_num]= new double [match_sort.size()][]; //
extr_corr_half[scene_num] = new double [match_sort.size()][]; // extracted_objects[scene_num].length][];
/// best_patt_indx = new int [match_sort.size()];
for (int mn=0; mn < match_sort.size(); mn++) {
......@@ -2349,14 +2453,65 @@ public class OrthoMapsCollection implements Serializable{
match_sort, // ArrayList<Integer> match_sort,
extracted_objects[scene_num], //double[][] extracted_objects, // for this scene
icorr_patterns[scene_num], // int [][] ipatterns,
extracted_masked[scene_num], // double [][] masked_src, // if not null, will return masked extracted objects
debugLevel); // int debugLevel
double [] scene_xy_offset = {centers[1][0]-centers[0][0],centers[1][1]-centers[0][1]};
double [] scene_xy_offset = {centers[last_scene][0]-centers[0][0],centers[last_scene][1]-centers[0][1]};
boolean [] removed = null;
double scene_agl = gops[1].getAGL(); // second scene agl
double scene_agl = gops[last_scene].getAGL(); // second scene agl
if (indices.length == 1) { // for a single-scene show before filtering by the first(only) scene
for (int sn = 0; sn < indices.length; sn++) {
showExtractedImages(
ortho_maps[indices[scene_num]].getName()+"-prefilter1", // String prefix
sn, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
extracted_objects, // double[][][] extracted_objects, // may be null - will not be generated
extract_display, // double[][][] extract_display, // may be null - will not be displayed
dmulti, // double[][] dmulti,
width, // int width,
remove_dc, // boolean remove_dc,
imps_extracted, //ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
if (sn==0) {
showExtracts(
ortho_maps[indices[scene_num]].getName()+"-prefilter1_contrast-masks", // String prefix
sn, // int scene_num,
sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
extracted_masked, // double[][][] extracts,
imps_masked, // ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
if (debugLevel > 0) {
showExtractedCorrelations(
ortho_maps[indices[scene_num]].getName()+"-prefilter1", // String prefix
scene_num, // int scene_num,
phaseCoeff, // double [] phaseCoeff,
extr_corr, // double [][][] extr_corr,
extr_corr_half, // double [][][] extr_corr_half,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
imps_extracted_corr, // ImagePlus[] imps_extracted_corr, // may be null - will not be displayed
imps_extracted_corr_half); // ImagePlus[] imps_extracted_corr_half
}
}
}
}
if (!filt_atonce) {
boolean[] filt_main_other = {true,false};
boolean[] filt_main_other = new boolean [indices.length]; //{true,false};
filt_main_other[0] = true;
//int num_removed =
// filt_abs_contrast
// filt_abs_easepart
removed = filterCandidates(
filt_keep, // boolean filt_keep,
filt_main_other, // new boolean [] filt_main_other,
......@@ -2368,6 +2523,7 @@ public class OrthoMapsCollection implements Serializable{
filt_height, // double filt_height,
filt_full_half_frac,// double [] filt_full_half_frac,
filt_abs_contrast, // double filt_abs_contrast,
filt_abs_easepart, // double filt_abs_easepart,
gops[scene_num], // GroundObjectPattern gop,
filt_other_frac, // double [] filt_other_frac, // null - disable, for all full (round) patterns.
filter_data, // double [][][][] filter_data,
......@@ -2381,6 +2537,7 @@ public class OrthoMapsCollection implements Serializable{
for (int sn = 0; sn < filter_data.length; sn++) {
filter_data[sn] = removeFilteredOut (filter_data[sn], removed);
extracted_objects[sn] = removeFilteredOut (extracted_objects[sn], removed);
extracted_masked[sn] = removeFilteredOut (extracted_masked[sn], removed);
extr_corr[sn] = removeFilteredOut (extr_corr[sn], removed);
extr_corr_half[sn] = removeFilteredOut (extr_corr_half[sn], removed);
}
......@@ -2390,10 +2547,11 @@ public class OrthoMapsCollection implements Serializable{
// System.out.println(num_removed+ "scenes filtered out, "+match_sort.size()+" candidates remain");
}
if (indices.length > 1) { // for a multi-scene show after filtering by the first scene
// show extracted scenes after some were optionally removed by the main scene filters
for (int sn = 0; sn < indices.length; sn++) {
showExtractedImages(
ortho_maps[indices[scene_num]].getName()+"-prefilter", // String prefix
ortho_maps[indices[scene_num]].getName()+"-postfilter1", // String prefix
sn, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
......@@ -2407,11 +2565,21 @@ public class OrthoMapsCollection implements Serializable{
remove_dc, // boolean remove_dc,
imps_extracted, //ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
}
// display extracted correlations for the main scene:
if (sn==0) {
showExtracts(
ortho_maps[indices[scene_num]].getName()+"-postfilter1_contrast-masks", // String prefix
sn, // int scene_num,
sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
extracted_masked, // double[][][] extracts,
imps_masked, // ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
if (debugLevel > 0) {
showExtractedCorrelations(
ortho_maps[indices[scene_num]].getName()+"-prefilter", // String prefix
ortho_maps[indices[scene_num]].getName()+"-postfilter1", // String prefix
scene_num, // int scene_num,
phaseCoeff, // double [] phaseCoeff,
extr_corr, // double [][][] extr_corr,
......@@ -2423,6 +2591,11 @@ public class OrthoMapsCollection implements Serializable{
imps_extracted_corr, // ImagePlus[] imps_extracted_corr, // may be null - will not be displayed
imps_extracted_corr_half); // ImagePlus[] imps_extracted_corr_half
}
}
}
}
// display extracted correlations for the main scene:
if (indices.length > 1) {
// print updated table after some scenes may be removed by the filter
System.out.println("\nAfter first scene filtering:");
System.out.print(String.format("%4s: %9s %8s %8s %3s"," # ", " x/y ", " best ","contrast","sub"));
......@@ -2451,7 +2624,7 @@ public class OrthoMapsCollection implements Serializable{
}
}
}
}
// Correlate second scene only for selected fragments
for (int scene_other = 1; scene_other < indices.length; scene_other++) { // normally just 1
......@@ -2530,9 +2703,11 @@ public class OrthoMapsCollection implements Serializable{
}
}
// final filter
boolean[] filt_main_other = new boolean [indices.length]; //{true,false};
Arrays.fill(filt_main_other, true);
removed = filterCandidates( // will filter again if already
filt_keep, // boolean filt_keep,
new boolean[] {true,true}, // new boolean [] filt_main_other,
filt_main_other, // new boolean [] filt_main_other,
min_corrs, //double [] min_corrs, // one per
min_corr_full_rel, // double min_corr_full_rel,
filt_max_radius, // double [][] filt_max_radius,
......@@ -2541,6 +2716,7 @@ public class OrthoMapsCollection implements Serializable{
filt_height, // double filt_height,
filt_full_half_frac,// double [] filt_other_frac, // null - disable, for all full (round) patterns.
filt_abs_contrast, // double filt_abs_contrast,
filt_abs_easepart, // double filt_abs_easepart,
gops[scene_num], // GroundObjectPattern gop,
filt_other_frac, // double [] filt_other_frac, // null - disable, for all full (round) patterns.
filter_data, // double [][][][] filter_data,
......@@ -2555,6 +2731,7 @@ public class OrthoMapsCollection implements Serializable{
for (int sn = 0; sn < filter_data.length; sn++) {
filter_data[sn] = removeFilteredOut (filter_data[sn], removed);
extracted_objects[sn] = removeFilteredOut (extracted_objects[sn], removed);
extracted_masked[sn] = removeFilteredOut (extracted_masked[sn], removed);
extr_corr[sn] = removeFilteredOut (extr_corr[sn], removed);
extr_corr_half[sn] = removeFilteredOut (extr_corr_half[sn], removed);
}
......@@ -2595,12 +2772,29 @@ public class OrthoMapsCollection implements Serializable{
match_sort, // ArrayList<Integer> match_sort,
imps_extracted_corr_final, // ImagePlus[] imps_extracted_corr, // may be null - will not be displayed
imps_extracted_corr_half_final); // ImagePlus[] imps_extracted_corr_half
if (sn==0) {
showExtracts(
ortho_maps[indices[scene_num]].getName()+"-final_contrast-masks", // String prefix
sn, // int scene_num,
sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
extracted_masked, // double[][][] extracts,
imps_masked, // ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
}
}
}
// double scene_agl = gops[1].getAGL(); // second scene agl
if (indices.length > 1) {
System.out.println(String.format("Main scene: (%03d) %17s",indices[0],ortho_maps[indices[0]].getName()));
System.out.println(String.format("Other scene: (%03d) %17s",indices[1],ortho_maps[indices[1]].getName()));
} else {
System.out.println(String.format("Scene: (%03d) %17s",indices[0],ortho_maps[indices[0]].getName()));
}
System.out.println("Searching for object type="+object_type+", found "+match_sort.size()+" of them."+
" PhaseCoeff=["+phaseCoeff[0]+","+phaseCoeff[1]+"], min_corrs=["+min_corrs[0]+","+min_corrs[1]+
"], min_corr_full_rel="+min_corr_full_rel+", frac_max="+frac_max);
......@@ -2613,19 +2807,24 @@ public class OrthoMapsCollection implements Serializable{
" filt_height="+filt_height+ " meters.");
System.out.println("filt_other_rad="+filt_other_rad+"pix, filt_other_frac=["+filt_other_frac[0]+", "+filt_other_frac[1]+"],"+
" filt_full_half_frac=["+filt_full_half_frac[0]+", "+filt_full_half_frac[1]+"].");
if (indices.length > 1) {
System.out.println("Second image is offset by dx="+scene_xy_offset[0]+", dy="+scene_xy_offset[1]+", dist="+
Math.sqrt(scene_xy_offset[0]*scene_xy_offset[0]+scene_xy_offset[1]*scene_xy_offset[1])+" pix");
System.out.println("Updated object list with main scene peak areas and secondary scene maximums, areas and maximum distances from the main");
}
// System.out.println("Updated object list with main scene peak areas and secondary scene maximums, areas and maximum distances from the main");
System.out.print(String.format("%4s: %9s %8s %8s %3s"," # ", " x/y ", " best ","contrast","sub"));
for (int j = 0; j < (corrs_out[scene_num].length + 1); j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8s ","match_"+j));
}
System.out.print(String.format("%6s %6s %6s %6s %6s %6s | %8s %6s %6s %6s %7s %7s %7s %7s %7s | %8s %6s %6s %6s %6s %6s %7s %7s %7s",
"mf-rad", "mf-eln","mh-rad", "mh-eln", "mh-ofr", "m_fhr", // main: full radius, full elongation, half radius, half elongation
System.out.print(String.format("%6s %6s %6s %6s %6s %6s |",
"mf-rad", "mf-eln","mh-rad", "mh-eln", "mh-ofr", "m_fhr"));
if (indices.length > 1) {
System.out.print(String.format(" %8s %6s %6s %6s %7s %7s %7s %7s %7s | %8s %6s %6s %6s %6s %6s %7s %7s",
"of-corr","of-rad","of-eln", "of-dst", "of-dx", "of-dy","of-par","of-prp","elevat",
"oh-corr","oh-rad","oh-eln", "oh-ofr", "o_fhr", "oh-dst", "oh-dx","oh-dy","removed"));
System.out.println();
"oh-corr","oh-rad","oh-eln", "oh-ofr", "o_fhr", "oh-dst", "oh-dx","oh-dy"));
}
System.out.println(String.format(" %7s",
"removed"));
for (int i = 0; i < match_sort.size(); i++) {
int indx =match_sort.get(i);
......@@ -2646,8 +2845,17 @@ public class OrthoMapsCollection implements Serializable{
System.out.print(" ");
}
}
// 0 1 2 3 4 5
// return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1]} ;
double m_fhr = filter_data[0][i][0][0]/filter_data[0][i][1][0];
String sremoved = removed[i]?" removed":"";
System.out.print(String.format(
"%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f |",
// main full and best half areas only, radius and elongation
filter_data[0][i][0][1], filter_data[0][i][0][2], // main full: radius and elongation
filter_data[0][i][1][1], filter_data[0][i][1][2], // main best half: radius and elongation
filter_data[0][i][1][6], // other max fraction of the main one
m_fhr));
if (indices.length > 1) {
double [] second_xy_offsets = {filter_data[1][i][0][4],filter_data[1][i][0][5]};
// try elevation for second scene and full pattern only
double [] scnd_xy_proj = projectOffsetOnVector(
......@@ -2658,17 +2866,10 @@ public class OrthoMapsCollection implements Serializable{
scene_xy_offset, // double [] scene_offset,
zoom_level, // int zoom_level,
scene_agl); // double agl)
// System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f",
String sremoved = removed[i]?" removed":"";
double m_fhr = filter_data[0][i][0][0]/filter_data[0][i][1][0];
// System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f",
double o_fhr = filter_data[1][i][0][0]/filter_data[1][i][1][0];
System.out.print(String.format(
"%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f | %8.5f %6.3f %6.3f %6.3f %7.3f %7.3f %7.3f %7.3f %7.3f | %8.5f %6.3f %6.3f %6.3f %6.3f %6.3f %7.3f %7.3f %7s",
// main full and best half areas only, radius and elongation
filter_data[0][i][0][1], filter_data[0][i][0][2], // main full: radius and elongation
filter_data[0][i][1][1], filter_data[0][i][1][2], // main best half: radius and elongation
filter_data[0][i][1][6], // other max fraction of the main one
m_fhr,
" %8.5f %6.3f %6.3f %6.3f %7.3f %7.3f %7.3f %7.3f %7.3f | %8.5f %6.3f %6.3f %6.3f %6.3f %6.3f %7.3f %7.3f %7s",
// for second full - everything and parallel/perpendicular+elevation
filter_data[1][i][0][0], filter_data[1][i][0][1], filter_data[1][i][0][2], // full: corr, radius, elongation
filter_data[1][i][0][3], filter_data[1][i][0][4], filter_data[1][i][0][5], // full: dist, dx, dy
......@@ -2677,9 +2878,11 @@ public class OrthoMapsCollection implements Serializable{
filter_data[1][i][1][0], filter_data[1][i][1][1], filter_data[1][i][1][2], // half: corr, radius, elongation
filter_data[1][i][1][6], ///
o_fhr,
filter_data[1][i][1][3], filter_data[1][i][1][4], filter_data[1][i][1][5], // half: dist, dx, dy
filter_data[1][i][1][3], filter_data[1][i][1][4], filter_data[1][i][1][5])); // half: dist, dx, dy
}
System.out.println(String.format(" %7s",
sremoved));
System.out.println();
}
System.out.println();
......@@ -2700,7 +2903,6 @@ public class OrthoMapsCollection implements Serializable{
final_map[i] = dmulti[i];
}
String final_title = final_titles[0]+"-"+final_titles[0]+"-MARKED_"+object_type+"_"+match_sort.size()+"_OBJECTS";
ImagePlus img_final = ShowDoubleFloatArrays.makeArrays(
final_map,
width,
......@@ -2895,7 +3097,7 @@ public class OrthoMapsCollection implements Serializable{
*/
public static boolean[] filterCandidates(
boolean filt_keep,
boolean [] filt_main_other,
boolean [] filt_main_other, // length== number of scenes
double [] min_corrs, // one per
double min_corr_full_rel,
double [][] filt_max_radius,
......@@ -2904,6 +3106,7 @@ public class OrthoMapsCollection implements Serializable{
double filt_height,
double [] filt_full_half_frac,
double filt_abs_contrast,
double filt_abs_easepart,
GroundObjectPattern gop,
// int [] best_patt_indx,
double [] filt_other_frac, // null - disable, for all full (round) patterns.
......@@ -2915,6 +3118,7 @@ public class OrthoMapsCollection implements Serializable{
ArrayList<Integer> match_sort,
int debugLevel ) {
int num_scenes = filt_main_other.length;
boolean [] remove = new boolean [match_sort.size()];
int num_removed = 0;
double [] min_corrs_other = {min_corrs[1]*min_corr_full_rel, min_corrs[1]};
......@@ -2932,20 +3136,24 @@ public class OrthoMapsCollection implements Serializable{
int best_patt= match.getPatternMatch(gop).getBestSub(); // 1-based
// boolean is_partial = best_patt_indx[mn] != 0; // only apply to combined full/half correlations, just full may have nearby maximums near the same size
boolean is_partial = best_patt != 1; // only apply to combined full/half correlations, just full may have nearby maximums near the same size
double [] strength_full_half_ratio = new double[2];
for (int scene_num = 0; scene_num < 2; scene_num++) if (filter_data[scene_num] != null){
double [] strength_full_half_ratio = new double[num_scenes];
for (int scene_num = 0; scene_num < num_scenes; scene_num++) if (filter_data[scene_num] != null){
strength_full_half_ratio[scene_num] = filter_data[scene_num][mn][0][0] / filter_data[scene_num][mn][1][0];
}
if (abs_contrast < filt_abs_contrast) {
// filt_abs_easepart
double min_abs_contrast = filt_abs_contrast;
if (is_partial) {
min_abs_contrast *= filt_abs_easepart;
}
if (abs_contrast < min_abs_contrast) {
System.out.println(name+": filtered out by "+NAME_MO[0]+" scene because its absolute contrast = "+
abs_contrast+ " < "+filt_abs_contrast);
abs_contrast+ " < "+min_abs_contrast+(is_partial?(". Eased for partial from "+filt_abs_contrast):""));
if (!remove[mn]) num_removed++;
remove[mn] = true;
}
for (int hf = 0; hf < 2; hf++) {
for (int scene_num = 0; scene_num < 2; scene_num++) if (filt_main_other[scene_num]){
for (int scene_num = 0; scene_num < num_scenes; scene_num++) if (filt_main_other[scene_num]){
if (Double.isNaN(filter_data[scene_num][mn][hf][0])) {
System.out.println(name+": filtered out by "+NAME_MO[scene_num]+"/"+NAME_FH[hf]+
" as correlation maximum is not found");
......@@ -3073,7 +3281,8 @@ public class OrthoMapsCollection implements Serializable{
* @param ipatterns integer square patterns with the same dimensions as the extracted_objects. Value
* 0 - do not use this pixel, 1 - Zone1 (inside the pattern), 2 - Zone2 - reference ring around
* the pattern.
* @param debugLevel debug level. >0 - dispaly images, >-4 - print.
* @param masked_src should be null or double [extracted_objects.length][]
* @param debugLevel debug level. >0 - display images, >-4 - print.
* @return true
*/
public static boolean setAbsoluteContrasts(
......@@ -3085,6 +3294,7 @@ public class OrthoMapsCollection implements Serializable{
ArrayList<Integer> match_sort,
double[][] extracted_objects, // for this scene
int [][] ipatterns,
double [][] masked_src, // if not null, will return masked extracted objects
int debugLevel
) {
boolean debug = debugLevel > 1;
......@@ -3136,6 +3346,7 @@ public class OrthoMapsCollection implements Serializable{
extracted_objects[mn], // double [] data,
ipatterns[i], // int [] ipattern,
outliers_frac, // double outliers_frac,
null,
debug); // boolean debug)
if (neg_better) {
dir_contrasts[i] *= -1;
......@@ -3146,6 +3357,9 @@ public class OrthoMapsCollection implements Serializable{
}
}
}
if (best_index < 0) {
best_index = best_patt;
}
if (best_index != best_patt) {
if (debugLevel > -3) {
System.out.println("setAbsoluteContrasts(): updating best pattern index for match #"
......@@ -3157,7 +3371,15 @@ public class OrthoMapsCollection implements Serializable{
if (debugLevel > -3) {
System.out.println("setAbsoluteContrasts(): Set absolute contrast for match #"+mn+" = "+dir_contrasts[best_index]);
}
if (masked_src != null) {
masked_src[mn] = new double [extracted_objects[mn].length];
OrthoMap.getAbsoluteContrast(
extracted_objects[mn], // double [] data,
ipatterns[best_index], // int [] ipattern,
outliers_frac, // double outliers_frac,
masked_src[mn],
debug); // boolean debug)
}
}
return true;
}
......@@ -3298,6 +3520,81 @@ public class OrthoMapsCollection implements Serializable{
}
}
public static void showExtracts(
String prefix,
int scene_num,
int sort_pattern_index,
int extr_size,
GroundObjectPattern gop,
ArrayList <ItemMatch> matches_list,
ArrayList<Integer> match_sort,
double[][][] extracts,
ImagePlus[] imps_extracted, // may be null - will not be displayed
int debugLevel
) {
if (match_sort.isEmpty()) {
System.out.println("List of detected objects is empty, nothing to display");
return;
}
PointRoi roi = new PointRoi();
roi.setOptions("nolabel"); // label");
for (int mn=0; mn < match_sort.size(); mn++) {
roi.addPoint(extr_size/2,extr_size/2,mn+1); // ,1);
}
for (int mn=0; mn < match_sort.size(); mn++) {
int indx =match_sort.get(mn);
ItemMatch match = matches_list.get(indx);
double [] center_xy = match.getXY();
//some may be missing on a second image
}
if ((debugLevel > 0) && (imps_extracted != null) && (prefix != null)) {
String [] extr_titles = new String [match_sort.size()];
for (int mn=0; mn < match_sort.size(); mn++) {
int indx =match_sort.get(mn);
ItemMatch match = matches_list.get(indx);
int [] ixy = match.getIntXY();
extr_titles[mn] = ixy[0]+"/"+ ixy[1]+":"+String.format("%7.5f",
match.getMatchValue(gop,sort_pattern_index));
}
imps_extracted[scene_num] = ShowDoubleFloatArrays.makeArrays(
extracts[scene_num],
extr_size,
extr_size,
prefix, // +"-objects_"+scene_num,
extr_titles); // test_titles,
imps_extracted[scene_num].setRoi(roi); // null
imps_extracted[scene_num].show();
}
}
public String selectOneScene(int default_choice, int num_choice_lines) {
String [] lines = new String [ortho_maps.length];
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SS zzz");// may be VV instead of zzz
for (int indx = 0; indx < ortho_maps.length; indx++) {
OrthoMap map = ortho_maps[indx];
LocalDateTime ldt = map.getLocalDateTime();
ZonedDateTime zonedUTC = ldt.atZone(ZoneId.of("UTC")); // that time is UTC
ZonedDateTime zonedDateTime = zonedUTC.withZoneSameInstant(ZoneId.of("Europe/Kyiv"));
String sdt = zonedDateTime.format(formatter);
String name = map.getName();
double agl = map.getAGL();
lines[indx]=String.format(
"%3d %17s %26s %6.2f",indx, name, sdt, agl);
}
GenericJTabbedDialog gd = new GenericJTabbedDialog("Select Image from the list ",1200,1000);
gd.addChoice("Image pair:",
lines,
lines[default_choice],
"Select scene", num_choice_lines);
gd.showDialog();
if (gd.wasCanceled()) return null;
int scene_number= gd.getNextChoiceIndex();
return ortho_maps[scene_number].getName();
}
public boolean showScenesStats(boolean select_all) {
String [] lines = new String [ortho_maps.length];
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SS zzz");// may be VV instead of zzz
......
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