Commit b70fdc39 authored by Andrey Filippov's avatar Andrey Filippov

Implementing scene high frequency decay calculation/reporting

parent 12d3c947
......@@ -2424,7 +2424,27 @@ public class DoubleFHT {
return amp;
}
public double[] calculateAmplitudeNoSwap(double[] fht) {
public double [] getFreqAmplitude(
double [] data) {
updateMaxN(data);
swapQuadrants(data);
if (!transform(data, false))
return null; // direct FHT
double [] amp = calculateAmplitude(data);
return amp;
}
public double [] getFreqAmplitude2(
double [] data) {
updateMaxN(data);
swapQuadrants(data);
if (!transform(data, false))
return null; // direct FHT
double [] amp = calculateAmplitude2(data);
return amp;
}
public static double[] calculateAmplitudeNoSwap(double[] fht) {
int size = (int) Math.sqrt(fht.length);
double[] amp = new double[size * size];
for (int row = 0; row < size; row++) {
......@@ -2473,7 +2493,7 @@ public class DoubleFHT {
}
/* Amplitude of one row from 2D Hartley Transform. */
void amplitude(int row, int size, double[] fht, double[] amplitude) {
static void amplitude(int row, int size, double[] fht, double[] amplitude) {
int base = row * size;
int l;
for (int c = 0; c < size; c++) {
......@@ -2495,7 +2515,7 @@ public class DoubleFHT {
}
/* Squared amplitude of one row from 2D Hartley Transform. */
void amplitude2(int row, int size, double[] fht, double[] amplitude) {
static void amplitude2(int row, int size, double[] fht, double[] amplitude) {
int base = row * size;
int l;
for (int c = 0; c < size; c++) {
......
......@@ -3531,6 +3531,347 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return null;
}
/**
* Trying to estimate image OTF to modify correlation results. Some images are better, some - worse
* (blurred because of elevation errors)? For all image or parts of it? So on some images all
* real objects (and false ones) get higher correlation, on some - all get lower. So some compensation
* on image quality may help to discriminate
* @param data image to process (may have NaNs)
* @param width image width
* @param size FFT size (now 128)
* @param center_period period (in pixels) corresponding to the frequency to measure OTF derivative
* @param range_period relative frequency range to average: low band from center/range_period to center,
* high band - from center to center*range_period
* @param wh if not null, should be int[2] - will return {tilesX,tilesY} for the result
* @param debugLevel
* @return per tile: null or a pair of high_frequency_response/low_frequency_response (around center)
* for horizontal and vertical directions
*/
public static double [][] getHiFreq(
final double [] data,
final int width,
final int size, // power of 2, such as 64
final double center_period,// center frequency is size/center_period
final double range_period, // ~1.5 - from center/range to center*range
final int [] wh, // result size
final int debugLevel){
final int dbg_x = -2668;
final int dbg_y = 256;
final int height = data.length/width;
final int tilesX = (int) Math.ceil(width/(size/2)) + 1;
final int tilesY = (int) Math.ceil(height/(size/2)) + 1;
if (wh != null) {
wh[0] = tilesX;
wh[1] = tilesY;
}
final double [][] hi_feq = new double [tilesX*tilesY][];
int center_freq = (int) Math.round(size/center_period);
int low_freq = (int) Math.round(size/center_period/range_period);
int high_freq = (int) Math.round(size/center_period*range_period);
final int [][][] ranges = { // {first, second},{low freq, high freq}, {start, end}
{ {size/2 - center_freq + 1, size/2 - low_freq},
{size/2 - high_freq, size/2 - center_freq - 1}
},
{{size/2 + low_freq, size/2 + center_freq - 1},
{size/2 + center_freq + 1, size/2 + high_freq}}};
final double [] range_npix = {
size*(center_freq-low_freq),
size*(high_freq-center_freq)};
final double [] window = new double [size*size];
final double [] wnd1d = new double[size/2];
for (int i = 0; i < size/2; i++) {
wnd1d[i] = Math.sin((i+0.5)*Math.PI/size);
}
for (int i = 0; i < size/2; i++) {
for (int j = 0; j < size/2; j++) {
double w = wnd1d[i]*wnd1d[j];
int k = i*size + j;
window[k] = w;
window[window.length-1-k] = w;
k = (i+ 1)*size - 1 -j;
window[k] = w;
window[window.length-1-k] = w;
}
}
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() {
double [] dtile = new double [size*size];
TileNeibs tn = new TileNeibs(size,size);
DoubleFHT doubleFHT = new DoubleFHT();
for (int nTile = ai.getAndIncrement(); nTile <hi_feq.length; nTile = ai.getAndIncrement()){
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
int px0 = (size/2) * tileX; // absolute in the original/result image
int py0 = (size/2) * tileY;
int x0 = Math.max(0, -px0);
int y0 = Math.max(0, -py0);
int x1 = Math.min(size, width- px0);
int y1 = Math.min(size, height-py0);
boolean dbg_tile = (Math.abs((px0 + size/2) - dbg_x) < size/4) && (Math.abs((py0 + size/2) - dbg_y) < size/4);
if (dbg_tile) {
System.out.println("getHiFreq(): tileX="+tileX+", tileY="+tileY);
System.out.println("getHiFreq(): px0="+px0+", py0="+py0);
}
int lwidth=x1-x0;
boolean has_NaN = false;
if ((x0>0) || (y0>0) || (x1 < size) || (y1 < size)) {
Arrays.fill(dtile,Double.NaN);
}
for (int y = y0; y < y1; y++) {
System.arraycopy(
data,
(py0 + y)*width+(px0+x0),
dtile,
y*size+x0,
lwidth);
}
for (int i = 0; i < dtile.length; i++) {
if (Double.isNaN(dtile[i])) {
has_NaN = true;
break;
}
}
if (has_NaN) {
fillNaNs(dtile, tn, 3);
}
for (int i = 0; i < dtile.length; i++) {
dtile[i] *= window[i];
}
if (dbg_tile) {
String [] rslt_titles= {"windowed"};
ShowDoubleFloatArrays.showArrays(
new double[][] {dtile},
size,
size,
true,
"windowed_data_tx"+tileX+"_ty"+tileY,
rslt_titles);
}
double [] amp = doubleFHT.getFreqAmplitude(dtile);
if (dbg_tile) {
String [] rslt_titles= {"amplitude"};
ShowDoubleFloatArrays.showArrays(
new double[][] {amp},
size,
size,
true,
"amplitude_tx"+tileX+"_ty"+tileY,
rslt_titles);
}
double [][] lo_hi_avg = new double[2][2]; // {x,y}{low,high}
for (int hl = 0; hl < 2; hl++) { // 0 - low, 1 - high
for (int sf = 0; sf < 2; sf++) { // 0 - fist, 1 second range
for (int i = ranges[sf][hl][0]; i <=ranges[sf][hl][1]; i++) {
for (int j = 0; j < size; j++) {
lo_hi_avg[0][hl] += amp[j*size + i];
lo_hi_avg[1][hl] += amp[i*size + j];
}
}
}
}
hi_feq[nTile] = new double[2];
for (int yx = 0; yx < 2; yx++) { // 0 - y, 1 - x
for (int hl = 0; hl < 2; hl++) { // 0 - low, 1 - high
lo_hi_avg[yx][hl] /= range_npix[hl];
}
hi_feq[nTile][yx] = lo_hi_avg[yx][1]/lo_hi_avg[yx][0];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return hi_feq;
}
/**
* Similar to above, but calculates for 2 rings
* @param data
* @param width
* @param size
* @param center_period
* @param range_period
* @param blank_xy discard data long x and y axes (probably remaining row/column noise?)
* @param wh
* @param debugLevel
* @return
*/
public static double [][] getHiFreqCirc(
final double [] data,
final int width,
final int size, // power of 2, such as 64
final double center_period,// center frequency is size/center_period
final double range_period, // ~1.5 - from center/range to center*range
final int blank_xy, //
final int [] wh, // result size
final int debugLevel){
final int dbg_x = 1144; // -2668;
final int dbg_y = 199; // 256;
final int height = data.length/width;
final int tilesX = (int) Math.ceil(width/(size/2)) + 1;
final int tilesY = (int) Math.ceil(height/(size/2)) + 1;
if (wh != null) {
wh[0] = tilesX;
wh[1] = tilesY;
}
final double [][] hi_feq = new double [tilesX*tilesY][];
int center_freq = (int) Math.round(size/center_period);
int low_freq = (int) Math.round(size/center_period/range_period);
int high_freq = (int) Math.round(size/center_period*range_period);
final double blank2 = (blank_xy-1) * (blank_xy-1) + 0.5;
final double [][] masks= new double [2][size*size];
for (int y = 0; y<size; y++) {
double y2 = (y-size/2);
y2*=y2;
if ((blank_xy == 0) || (y2 > blank2)) {
for (int x = 0; x < size; x++) {
double x2 = (x-size/2);
x2*=x2;
if ((blank_xy == 0) || (x2 > blank2)) {
double r = Math.sqrt(x2+y2);
if ((r >= low_freq) && (r <= high_freq)) {
int indx = y*size + x;
if (r < center_freq) {
masks[0][indx] = Math.sin(Math.PI *(center_freq - r)/(center_freq-low_freq));
} else {
masks[1][indx] = Math.sin(Math.PI *(r - center_freq)/(high_freq -center_freq));
}
}
}
}
}
}
if ((dbg_x >=0) && (dbg_y >=0)) {
String [] rslt_titles= {"low_mask","high_mask"};
ShowDoubleFloatArrays.showArrays(
masks,
size,
size,
true,
"masks",
rslt_titles);
}
for (int n = 0; n < 2; n++) {
double s=0.0;
for (int i = 0; i < masks[n].length; i++) {
s+=masks[n][i];
}
s = 1/s;
for (int i = 0; i < masks[n].length; i++) {
masks[n][i]*=s;
}
}
final double [] window = new double [size*size];
final double [] wnd1d = new double[size/2];
for (int i = 0; i < size/2; i++) {
wnd1d[i] = Math.sin((i+0.5)*Math.PI/size);
}
for (int i = 0; i < size/2; i++) {
for (int j = 0; j < size/2; j++) {
double w = wnd1d[i]*wnd1d[j];
int k = i*size + j;
window[k] = w;
window[window.length-1-k] = w;
k = (i+ 1)*size - 1 -j;
window[k] = w;
window[window.length-1-k] = w;
}
}
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() {
double [] dtile = new double [size*size];
TileNeibs tn = new TileNeibs(size,size);
DoubleFHT doubleFHT = new DoubleFHT();
for (int nTile = ai.getAndIncrement(); nTile <hi_feq.length; nTile = ai.getAndIncrement()){
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
int px0 = (size/2) * tileX; // absolute in the original/result image
int py0 = (size/2) * tileY;
int x0 = Math.max(0, -px0);
int y0 = Math.max(0, -py0);
int x1 = Math.min(size, width- px0);
int y1 = Math.min(size, height-py0);
boolean dbg_tile = (Math.abs((px0 + size/2) - dbg_x) < size/4) && (Math.abs((py0 + size/2) - dbg_y) < size/4);
if (dbg_tile) {
System.out.println("getHiFreq(): tileX="+tileX+", tileY="+tileY);
System.out.println("getHiFreq(): px0="+px0+", py0="+py0);
}
int lwidth=x1-x0;
boolean has_NaN = false;
if ((x0>0) || (y0>0) || (x1 < size) || (y1 < size)) {
Arrays.fill(dtile,Double.NaN);
}
for (int y = y0; y < y1; y++) {
System.arraycopy(
data,
(py0 + y)*width+(px0+x0),
dtile,
y*size+x0,
lwidth);
}
for (int i = 0; i < dtile.length; i++) {
if (Double.isNaN(dtile[i])) {
has_NaN = true;
break;
}
}
if (has_NaN) {
continue;
// fillNaNs(dtile, tn, 3);
}
for (int i = 0; i < dtile.length; i++) {
dtile[i] *= window[i];
}
if (dbg_tile) {
String [] rslt_titles= {"windowed"};
ShowDoubleFloatArrays.showArrays(
new double[][] {dtile},
size,
size,
true,
"windowed_data_tx"+tileX+"_ty"+tileY,
rslt_titles);
}
double [] amp2 = doubleFHT.getFreqAmplitude2(dtile);
if (dbg_tile) {
String [] rslt_titles= {"amplitude2","low_mask","high_mask"};
ShowDoubleFloatArrays.showArrays(
new double[][] {amp2,masks[0],masks[1]},
size,
size,
true,
"amplitude2_tx"+tileX+"_ty"+tileY,
rslt_titles);
}
hi_feq[nTile] = new double[masks.length];
for (int n = 0; n < masks.length; n++) {
for (int i = 0; i < masks[n].length; i++) {
hi_feq[nTile][n] += masks[n][i] * amp2[i];
}
hi_feq[nTile][n] = Math.sqrt(hi_feq[nTile][n]);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return hi_feq;
}
public static double [] correlateWithPattern(
final double [] data,
final int width,
......
......@@ -1994,7 +1994,7 @@ public class OrthoMapsCollection implements Serializable{
int debugLevel = 1;
String save_top_dir = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/pattern_match/";
String sub_dir = "dbg_recenter_06";
String sub_dir = "dbg_recenter_07";
boolean show_images = true;
boolean save_images = true;
String alt_mode="??m";
......@@ -2323,7 +2323,7 @@ public class OrthoMapsCollection implements Serializable{
// from (128/spectrum_sample[0])/spectrum_sample[1]
// to (128/spectrum_sample[0])*spectrum_sample[1].
// Calculate average of FFT power spectrum on both sides, in both directions and get ratio
double [] spectrum_sample = {14, 1.5};
double [] spectrum_sample = {14, 1.5, 1.0};
double search_radius_recenter = 3; // how far to look for updated correlation peak after recenter
if (warp != null) {
......@@ -2383,7 +2383,7 @@ public class OrthoMapsCollection implements Serializable{
zoom_level, // int zoom_level,
wh, // int [] wh,
origin, // int [] origin){ // maps[0] as a reference
centers); // double [][] centers)
null); // centers); // double [][] centers) // already set with dmulti
}
......@@ -2579,7 +2579,80 @@ public class OrthoMapsCollection implements Serializable{
}
// Splitting - above done for both scenes, below - just for the main one
int scene_num = 0;
int scene_num = 0;
double hi_lo_freq = 0.0;
double [][] hi_freq_arr = null;
int [] hi_freq_wh = new int[2];
{
// Just testing for now
int shrink_sel = 4;
double spectrum_sigma = 2.0;
int blank_xy = (int) Math.round(spectrum_sample[1]);
double [][] hi_freq = OrthoMap.getHiFreqCirc(
dmulti[scene_num], // final double [] data,
width, // final int width,
corr_size, // final int size, // power of 2, such as 64
spectrum_sample[0], // final double center_period,// center frequency is size/center_period
spectrum_sample[1], // final double range_period, // ~1.5 - from center/range to center*range
blank_xy, // final int blank_xy, //
hi_freq_wh, // final int [] wh, // result size
debugLevel); // final int debugLevel);
hi_freq_arr = new double [4][hi_freq.length];
for (int i = 0; i < hi_freq_arr.length; i++) {
Arrays.fill(hi_freq_arr[i], Double.NaN);
}
for (int i = 0; i < hi_freq.length;i++) if (hi_freq[i] != null) {
hi_freq_arr[2][i] = hi_freq[i][0];
hi_freq_arr[3][i] = hi_freq[i][1];
hi_freq_arr[1][i] = hi_freq[i][1]/hi_freq[i][0];
}
hi_freq_arr[0] = hi_freq_arr[1].clone();
TileNeibs tn = new TileNeibs(hi_freq_wh[0],hi_freq_wh[1]);
OrthoMap.fillNaNs(
hi_freq_arr[0], // double [] data,
tn, // TileNeibs tn,
3); // int min_neibs)
(new DoubleGaussianBlur()).blurDouble(
hi_freq_arr[0], // double[] pixels,
hi_freq_wh[0], // int width,
hi_freq_wh[1], // int height,
spectrum_sigma, // double sigmaX,
spectrum_sigma, // double sigmaY,
0.01); // double accuracy);
boolean [] mask = new boolean[hi_freq.length];
for (int i = 0; i < mask.length;i++) {
mask[i] = hi_freq[i] != null;
}
tn.shrinkSelection(
shrink_sel, // final int shrink, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
mask, // final boolean [] tiles,
null); // final boolean [] prohibit)
double swd = 0.0, sw = 0.0;
for (int i = 0; i < mask.length;i++) if (mask[i]){
swd += hi_freq[i][1]/hi_freq[i][0];
sw+= 1.0;
}
hi_lo_freq = swd/sw;
String [] hi_freq_titles = {"blur","ratio","low","high"};
ImagePlus img_hi_freq = ShowDoubleFloatArrays.makeArrays(
hi_freq_arr,
hi_freq_wh[0],
hi_freq_wh[1],
indices[scene_num]+"-"+ortho_maps[indices[scene_num]].getName()+"-HIGH_FREQ",
hi_freq_titles);
showSaveImagePlus(
img_hi_freq, // ImagePlus imp,
show_images, // boolean show,
save_images, // boolean save,
save_dir, // String save_dir,
debugLevel); // int debugLevel)
System.out.println("Average hi_lo_freq="+hi_lo_freq);
System.out.println();
}
corrs_out[scene_num] = correlateAllPatterns(
dmulti[scene_num], // double [] data,
width, // int width,
......@@ -2703,7 +2776,8 @@ public class OrthoMapsCollection implements Serializable{
if (num_non_overlap > 0) {
System.out.println("Removed "+num_non_overlap+" objects outside of the scenes overlap, "+match_sort.size()+" remain");
}
System.out.print(String.format("%4s: %9s %8s %8s %6s %3s"," # ", " x/y ", "sel-corr"," best ","round", "sub"));
System.out.print(String.format("%4s: %9s %8s %8s %8s %6s %3s %6s %6s",
" # ", " x/y ", " hfreq ", "sel-corr"," best ","round", "sub"," dist "," az "));
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));
}
......@@ -2713,13 +2787,27 @@ public class OrthoMapsCollection implements Serializable{
ItemMatch match = matches_list.get(indx);
double [] match_values = match.getMatchValues(gops[scene_num]);
int [] icenter_xy = match.getIntXY();
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %6.3f %3d",
double hfr = Double.NaN;
if (hi_freq_arr != null) {
int hfr_x = icenter_xy[0]/(corr_size/2);
int hfr_y = icenter_xy[1]/(corr_size/2);
hfr = hi_freq_arr[0][hfr_x + hfr_y * hi_freq_wh[0]];
}
double [] vert_offs = new double[2];
for (int j = 0; j < vert_offs.length; j++) {
vert_offs[j] = icenter_xy[j] - origin[j];
}
double vert_dist = Math.sqrt(vert_offs[0]*vert_offs[0]+vert_offs[1]*vert_offs[1]);
double vert_az= Math.atan2(vert_offs[1],vert_offs[0])*180.0/Math.PI;
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.5f %6.3f %3d %6.1f %6.1f",
i,
icenter_xy[0],icenter_xy[1],
hfr,
match.getMatchValue(gops[scene_num]),
match.getMatchBestValue(gops[scene_num]),
match.getRoundness (gops[scene_num]),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
match.getPatternMatch(gops[scene_num]).getBestSub(), // 1-based
vert_dist, vert_az)); // horizontal distance and azimuth from the camera ground projection
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8.5f",match_values[j]));
if (j == (match_values.length-1)) {
......@@ -2883,7 +2971,8 @@ public class OrthoMapsCollection implements Serializable{
System.out.println("Centered match candidates ("+match_sort.size()+
")"); // +min_corrs[scene_num]);
// print updated list
System.out.print(String.format("%4s: %9s %8s %8s %6s %3s"," # ", " x/y ", "sel-corr"," best ","round", "sub"));
System.out.print(String.format("%4s: %9s %8s %8s %8s %6s %3s %6s %6s",
" # ", " x/y ", " hfreq ", "sel-corr"," best ","round", "sub"," dist "," az "));
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));
}
......@@ -2893,13 +2982,27 @@ public class OrthoMapsCollection implements Serializable{
ItemMatch match = matches_list.get(indx);
double [] match_values = match.getMatchValues(gops[scene_num]);
int [] icenter_xy = match.getIntXY();
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %6.3f %3d",
double hfr = Double.NaN;
if (hi_freq_arr != null) {
int hfr_x = icenter_xy[0]/(corr_size/2);
int hfr_y = icenter_xy[1]/(corr_size/2);
hfr = hi_freq_arr[0][hfr_x + hfr_y * hi_freq_wh[0]];
}
double [] vert_offs = new double[2];
for (int j = 0; j < vert_offs.length; j++) {
vert_offs[j] = icenter_xy[j] - origin[j];
}
double vert_dist = Math.sqrt(vert_offs[0]*vert_offs[0]+vert_offs[1]*vert_offs[1]);
double vert_az= Math.atan2(vert_offs[1],vert_offs[0])*180.0/Math.PI;
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.5f %6.3f %3d %6.1f %6.1f",
i,
icenter_xy[0],icenter_xy[1],
hfr,
match.getMatchValue(gops[scene_num]),
match.getMatchBestValue(gops[scene_num]),
match.getRoundness (gops[scene_num]),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
match.getPatternMatch(gops[scene_num]).getBestSub(), // 1-based
vert_dist, vert_az)); // horizontal distance and azimuth from the camera ground projection
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8.5f",match_values[j]));
if (j == (match_values.length-1)) {
......@@ -3068,7 +3171,8 @@ public class OrthoMapsCollection implements Serializable{
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 %8s %6s %3s"," # ", " x/y ", "sel-corr"," best ","contrast","round", "sub"));
System.out.print(String.format("%4s: %9s %8s %8s %8s %8s %6s %3s %6s %6s",
" # ", " x/y ", " hfreq ", "sel-corr"," best ","contrast","round", "sub"," dist "," az "));
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));
}
......@@ -3080,19 +3184,34 @@ public class OrthoMapsCollection implements Serializable{
ItemMatch match = matches_list.get(indx);
double [] match_values = match.getMatchValues(gops[scene_num]);
int [] icenter_xy = match.getIntXY();
double hfr = Double.NaN;
if (hi_freq_arr != null) {
int hfr_x = icenter_xy[0]/(corr_size/2);
int hfr_y = icenter_xy[1]/(corr_size/2);
hfr = hi_freq_arr[0][hfr_x + hfr_y * hi_freq_wh[0]];
}
double [] vert_offs = new double[2];
for (int j = 0; j < vert_offs.length; j++) {
vert_offs[j] = icenter_xy[j] - origin[j];
}
double vert_dist = Math.sqrt(vert_offs[0]*vert_offs[0]+vert_offs[1]*vert_offs[1]);
double vert_az= Math.atan2(vert_offs[1],vert_offs[0])*180.0/Math.PI;
boolean removed = match.isRemoved();
String sremoved = removed?" removed":"";
// double best_val = match.getMatchValue(gops[scene_num],sort_pattern_index);
// so it is updated after best subpattern could be changed in setAbsoluteContrasts()
//match_values[match.getPatternMatch(gops[scene_num]).getBestSub() -1];
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.3f %6.3f %3d",
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.5f %8.3f %6.3f %3d %6.1f %6.1f",
i,
icenter_xy[0],icenter_xy[1],
hfr,
match.getMatchValue(gops[scene_num]),
match.getMatchBestValue(gops[scene_num]),
match.getAbsoluteContrast(),
match.getRoundness(gops[scene_num]),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
match.getPatternMatch(gops[scene_num]).getBestSub(), // 1-based
vert_dist, vert_az)); // horizontal distance and azimuth from the camera ground projection
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8.5f",match_values[j]));
if (j == (match_values.length-1)) {
......@@ -3271,14 +3390,14 @@ public class OrthoMapsCollection implements Serializable{
System.out.println("abs_edge_frac="+abs_edge_frac+", abs_oversize="+abs_oversize+
", abs_force_round="+abs_force_round+", abs_mode="+abs_mode+", abs_invert="+abs_invert);
System.out.println("abs_outliers_frac="+abs_outliers_frac+", abs_obscure_warm="+abs_obscure_warm+
", abs_obscure_frac="+abs_obscure_frac);
", abs_obscure_frac="+abs_obscure_frac + ", Average hi_lo_freq="+hi_lo_freq);
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.print(String.format("%4s: %9s %8s %8s %8s %6s %3s"," # ", " x/y ", "sel-corr", " best ","contrast","round","sub"));
System.out.print(String.format("%4s: %9s %8s %8s %8s %8s %6s %3s %6s %6s",
" # ", " x/y ", " hfreq ","sel-corr", " best ","contrast","round","sub"," dist "," az "));
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));
}
......@@ -3288,6 +3407,7 @@ public class OrthoMapsCollection implements Serializable{
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"));
System.out.print(String.format("| %6s %6s"," dist2"," az2 "));
}
System.out.println(String.format(" %7s",
"removed"));
......@@ -3298,14 +3418,28 @@ public class OrthoMapsCollection implements Serializable{
double [] match_values = match.getMatchValues(gops[scene_num]);
CorrelationPeakStats [][] filter_data = match.filter_data;
int [] icenter_xy = match.getIntXY();
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.3f %6.3f %3d",
double hfr = Double.NaN;
if (hi_freq_arr != null) {
int hfr_x = icenter_xy[0]/(corr_size/2);
int hfr_y = icenter_xy[1]/(corr_size/2);
hfr = hi_freq_arr[0][hfr_x + hfr_y * hi_freq_wh[0]];
}
double [] vert_offs = new double[2];
for (int j = 0; j < vert_offs.length; j++) {
vert_offs[j] = icenter_xy[j] - origin[j];
}
double vert_dist = Math.sqrt(vert_offs[0]*vert_offs[0]+vert_offs[1]*vert_offs[1]);
double vert_az= Math.atan2(vert_offs[1],vert_offs[0])*180.0/Math.PI;
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.5f %8.5f %8.3f %6.3f %3d %6.1f %6.1f",
i,
icenter_xy[0],icenter_xy[1],
hfr,
match.getMatchValue(gops[scene_num]), // ,sort_pattern_index),
match.getMatchBestValue(gops[scene_num]),
match.getAbsoluteContrast(),
match.getRoundness(gops[scene_num]),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
match.getPatternMatch(gops[scene_num]).getBestSub(), // 1-based
vert_dist, vert_az)); // horizontal distance and azimuth from the camera ground projection
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8.5f",match_values[j]));
if (j != (match_values.length-1)) {
......@@ -3317,6 +3451,7 @@ public class OrthoMapsCollection implements Serializable{
double m_fhr = filter_data[0][0].best_d/filter_data[0][1].best_d;
boolean removed = match.isRemoved();
String sremoved = removed?" 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
......@@ -3326,6 +3461,13 @@ public class OrthoMapsCollection implements Serializable{
m_fhr));
if (indices.length > 1) {
double [] vert_offs2 = new double[2];
for (int j = 0; j < vert_offs.length; j++) {
vert_offs2[j] = icenter_xy[j] - centers[1][j];
}
double vert_dist2 = Math.sqrt(vert_offs2[0]*vert_offs2[0]+vert_offs2[1]*vert_offs2[1]);
double vert_az2= Math.atan2(vert_offs2[1],vert_offs2[0])*180.0/Math.PI;
double [] second_xy_offsets = filter_data[1][0].cent_offs;
// try elevation for second scene and full pattern only
double [] scnd_xy_proj = projectOffsetOnVector(
......@@ -3349,6 +3491,8 @@ public class OrthoMapsCollection implements Serializable{
filter_data[1][1].max_other, ///
o_fhr,
filter_data[1][1].dist, filter_data[1][1].cent_offs[0], filter_data[1][1].cent_offs[1])); // half: dist, dx, dy
System.out.print(String.format(
"| %6.1f %6.1f", vert_dist2, vert_az2));
}
System.out.println(String.format(" %7s",
sremoved));
......
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