Commit 33f052a0 authored by Andrey Filippov's avatar Andrey Filippov

Working on 100m AGL

parent 758adc65
......@@ -70,6 +70,24 @@ public class ItemMatch {
return match.getMatch(indx);
}
/**
* Return correlation value as the one of the pattern correlations pointed
* by the best subpattern index.
* @param groundObjectPattern
* @return selected correlation value
*/
public double getMatchValue(GroundObjectPattern groundObjectPattern) {
return getMatchValue(groundObjectPattern.getPatternPath());
}
public double getMatchValue(String pattern_path) {
int indx = getPatternMatch(pattern_path).getBestSub(); // -1;
return getMatchValue(pattern_path,indx);
}
public double getMatchValue(GroundObjectPattern groundObjectPattern, int indx) {
return getMatchValue(groundObjectPattern.getPatternPath(), indx);
}
......
......@@ -2073,18 +2073,28 @@ 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 obscure_frac fraction between center average and peripheral ring to compare when obscure_warm
* is set.
* @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
* @return a pair of : difference between average in-pattern (1) and outside (2) average
* values, and difference between third zone and a threshold between averages of zone1
* and zone2. For full patterns (no zone3) this value is NaN. Positive values are good,
* regardless the cold or warm center. For cold patterns (morning) positive means
* that zone 3 minimum is warmer than fraction point between zone1 and zone2 (cold
* object obscured by something warmer, for hot - that obscurant is colder.
*
*/
public static double getAbsoluteContrast(
public static double [] getAbsoluteContrast(
double [] data,
int [] ipattern,
double outliers_frac,
// boolean obscure_warm, // = true; // obscured can only be by warmer objects
double obscure_frac, // 0.25; // obscured threshold between center and outer
double [] masked_data, // null or double [data.length] to return masked data
boolean debug) {
int num_segments = 3;
if (debug) {
int size = (int) Math.sqrt(data.length);
ShowDoubleFloatArrays.showArrays(
......@@ -2095,11 +2105,14 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
}
ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 2; i++) {
for (int i = 0; i < num_segments; i++) {
lists.add(new ArrayList<Integer>());
}
double [] swd = new double [2],sw = new double [2], avg= new double[2], fracw=new double[2];
for (int n = 0; n < swd.length; n++) {
double [] swd = new double [num_segments],
sw = new double [num_segments],
avg= new double[num_segments],
fracw=new double[num_segments];
for (int n = 0; n < num_segments; n++) { // swd.length; n++) {
ArrayList<Integer> list = lists.get(n);
int n1 = n+1;
for (int i = 0; i < ipattern.length; i++) if (ipattern[i] == n1){
......@@ -2110,9 +2123,23 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
avg[n] = swd[n]/sw[n];
fracw[n] = (1.0-outliers_frac) * sw[n];
}
double [] zone3_min_max = {Double.NaN, Double.NaN};
int zone3=3;
for (int i:lists.get(zone3-1)) {
if (Double.isNaN(zone3_min_max[0]) || (data[i] < zone3_min_max[0])) {
zone3_min_max[0] = data[i];
}
if (Double.isNaN(zone3_min_max[1]) || (data[i] > zone3_min_max[1])) {
zone3_min_max[1] = data[i];
}
}
if (debug) {
System.out.println("getAbsoluteContrast() before outliers: avg[0] ="+avg[0]+", avg[1]="+avg[1]+", avg[0]-avg[1]="+(avg[0]-avg[1]));
}
if (outliers_frac > 0) {
for (int n = 0; n < swd.length; n++) {
ArrayList<Integer> list = lists.get(n);
......@@ -2124,7 +2151,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return (rhsd > lhsd) ? -1 : (rhsd < lhsd) ? 1 : 0;
}
});
while (sw[n] >= fracw[n]) {
while (!list.isEmpty() && (sw[n] >= fracw[n])) {
int indx_first = list.get(0);
int indx_last = list.get(list.size()-1);
boolean remove_first = Math.abs(data[indx_first] - avg[n]) > Math.abs(data[indx_last] - avg[n]);
......@@ -2137,6 +2164,11 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
}
}
}
double threshold = obscure_frac * avg[0] + (1.0 - obscure_frac) * avg[1];
double over_thresh = (avg[0] < avg[1]) ? (zone3_min_max[0] - threshold) : (threshold - zone3_min_max[1]);
if (masked_data != null) {
Arrays.fill(masked_data, Double.NaN);
for (int n = 0; n < lists.size(); n++) {
......@@ -2175,14 +2207,15 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
if (debug) {
System.out.println("getAbsoluteContrast() after outliers: avg[0] ="+avg[0]+", avg[1]="+avg[1]+", avg[0]-avg[1]="+(avg[0]-avg[1]));
}
return avg[0]-avg[1];
return new double [] {avg[0]-avg[1], over_thresh};
}
/**
* From existing pattern (only for simple dark main scene)
* create two zones to calculate average (w/o outliers) inside
* the pattern and around it. Mark inner with 1, outer - 2, keep
* other 0. Then later find 2 averages (removing outliers) and their
* the pattern and around it. Mark inner with 1, outer - 2,
* 3 - potential obscurant for partial patterns
* keep other 0. Then later find 2 averages (removing outliers) and their
* difference - absolute contrast.
* @param patterns set of square patterns, first [0] for full pattern,
* others - for half-patterns cut in different directions.
......@@ -2287,6 +2320,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
( fys)*( fxs)*npatterns[n][sindx+size+1];
if (sdn/sd0 > 0.5) {
ipatterns[n][indx] = ipatterns[0][indx]; // =2
} else {
ipatterns[n][indx] = 3; // =2
}
}
}
......@@ -2305,6 +2340,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
switch (ipatterns[n][i]) {
case 1: dbg_img[n][i] = 1.0; break;
case 2: dbg_img[n][i] = -1.0; break;
case 3: dbg_img[n][i] = -2.0; break;
}
}
}
......@@ -4297,7 +4333,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
final int dbg_pix3 = 1439211; // 2827822;
final int dbg_x = 1445;
final int dbg_y = 2338;
final int dbg_tolerance = 10;
final int dbg_tolerance = -10;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......
......@@ -1816,12 +1816,13 @@ public class OrthoMapsCollection implements Serializable{
phaseCoeff[0] = 0.9;
// adv_radius = 20; // pix?
} else { // 100m defaults
min_corrs[0] = 0.009;
min_corrs[0] = 0.0119;
abs_edge_frac = 0.35;
abs_oversize = 2.2;
filt_abs_contrast = 60;
filt_abs_easepart = 0.85;
phaseCoeff[0] = 0.9;
abs_force_round = true;
// adv_radius = 20; // pix?
}
}
......@@ -2359,7 +2360,7 @@ public class OrthoMapsCollection implements Serializable{
System.out.print(String.format("%4d: %4d/%4d %8.5f %3d",
i,
icenter_xy[0],icenter_xy[1],
match.getMatchValue(gops[scene_num],sort_pattern_index),
match.getMatchValue(gops[scene_num]), // ,sort_pattern_index),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
System.out.print(String.format(" %8.5f",match_values[j]));
......@@ -2384,12 +2385,47 @@ public class OrthoMapsCollection implements Serializable{
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()];
// Extract main scene areas around candidates
// extract main scene data, needed for the absolute contrast calculations, no display
showExtractedImages( // scene_num == 0 here
null, // ortho_maps[indices[scene_num]].getName()+"-prefilter", // String prefix
scene_num, //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
null, // extract_display, // double[][][] extract_display, // may be null - will not be displayed
dmulti, // double[][] dmulti,
width, // int width,
remove_dc, // boolean remove_dc,
null, // imps_extracted, //ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
// calculate absolute contrasts for all patterns, update best_sub modes: 0 - keep, 1 - keep type, 2 keep type and if half +/-1,
// 3 - free, 4 - force round objects. This may change best subpattern and should be reflected by filters. Maybe even reorder candidates?
setAbsoluteContrasts(
abs_force_round, // boolean abs_force_round,
abs_mode, // int mode, // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
abs_invert, // boolean neg_better, // more negative is difference - stronger result
abs_outliers_frac, // double 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
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
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
for (int mn=0; mn < match_sort.size(); mn++) {
int indx =match_sort.get(mn);
ItemMatch match = matches_list.get(indx);
// should be already updated by setAbsoluteContrasts();
int best_patt = match.getPatternMatch(gops[scene_num]).getBestSub() - 1;
/// best_patt_indx[mn] = best_patt;
double [] center_xy = match.getXY();
extr_corr[scene_num][mn] = ObjectLocation.extractObjectImage(
center_xy, // double [] center_xy,
......@@ -2426,11 +2462,12 @@ public class OrthoMapsCollection implements Serializable{
frac_max, // double frac_max)
filt_other_rad, // double other_radius,
debugLevel); // final int debugLevel) {
/*
// extract main scene data, needed for the absolute contrast calculations, no display
showExtractedImages( // scene_num == 0 here
null, // ortho_maps[indices[scene_num]].getName()+"-prefilter", // String prefix
scene_num, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
//sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
......@@ -2442,12 +2479,17 @@ public class OrthoMapsCollection implements Serializable{
remove_dc, // boolean remove_dc,
null, // imps_extracted, //ImagePlus[] imps_extracted, // may be null - will not be displayed
debugLevel); // int debugLevel
*/
}
/*
// calculate absolute contrasts for all patterns, update best_sub modes: 0 - keep, 1 - keep type, 2 keep type and if half +/-1
setAbsoluteContrasts(
abs_force_round, // boolean abs_force_round,
abs_mode, // int mode, // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
abs_invert, // boolean neg_better, // more negative is difference - stronger result
abs_outliers_frac, // double 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
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
match_sort, // ArrayList<Integer> match_sort,
......@@ -2455,7 +2497,7 @@ public class OrthoMapsCollection implements Serializable{
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[last_scene][0]-centers[0][0],centers[last_scene][1]-centers[0][1]};
boolean [] removed = null;
double scene_agl = gops[last_scene].getAGL(); // second scene agl
......@@ -2464,7 +2506,7 @@ public class OrthoMapsCollection implements Serializable{
showExtractedImages(
ortho_maps[indices[scene_num]].getName()+"-prefilter1", // String prefix
sn, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
//sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
......@@ -2553,7 +2595,7 @@ public class OrthoMapsCollection implements Serializable{
showExtractedImages(
ortho_maps[indices[scene_num]].getName()+"-postfilter1", // String prefix
sn, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
//sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
......@@ -2609,10 +2651,14 @@ 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 best_val = match.getMatchValue(gops[scene_num],sort_pattern_index);
// so it is updated after best subpattern could be changed in setAbsoluteContrasts()
double best_val = match.getMatchValue(gops[scene_num]);
//match_values[match.getPatternMatch(gops[scene_num]).getBestSub() -1];
System.out.print(String.format("%4d: %4d/%4d %8.5f %8.3f %3d",
i,
icenter_xy[0],icenter_xy[1],
match.getMatchValue(gops[scene_num],sort_pattern_index),
best_val,
match.getAbsoluteContrast(),
match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
......@@ -2748,7 +2794,7 @@ public class OrthoMapsCollection implements Serializable{
showExtractedImages(
ortho_maps[indices[scene_num]].getName()+"-final", // String prefix
sn, //int scene_num,
sort_pattern_index, // int sort_pattern_index,
//sort_pattern_index, // int sort_pattern_index,
extr_size, // int extr_size,
gops[scene_num], // GroundObjectPattern gop,
matches_list, // ArrayList <ItemMatch> matches_list,
......@@ -3121,7 +3167,9 @@ public class OrthoMapsCollection implements Serializable{
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]};
double [][] min_corrs_other = {
{min_corrs[0]*min_corr_full_rel, min_corrs[0]},
{min_corrs[1]*min_corr_full_rel, min_corrs[1]}};
double offset_from_height = elevationToParallelOffset( // will be negative
filt_height, // double height,
scene_xy_offset, // double [] scene_offset,
......@@ -3171,14 +3219,19 @@ public class OrthoMapsCollection implements Serializable{
double [] scnd_xy_proj = projectOffsetOnVector(
second_xy_offsets, // double [] object_offset,
scene_xy_offset); // double [] scene_offset)
if (scene_num > 0) { // other scene
// {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1]} ;
if (corr_val < min_corrs_other[hf]) {
if (corr_val < min_corrs_other[scene_num][hf]) {
System.out.println(name+": filtered out by "+NAME_MO[scene_num]+" correlation maximum value for "+
NAME_FH[hf]+ " = "+corr_val+" < "+ min_corrs_other[hf]);
NAME_FH[hf]+ " = "+corr_val+" < "+ min_corrs_other[scene_num][hf]);
if (scene_num == 0) {
System.out.println(
"For the main scene it could happen if the sub_pattern index changed after\n"+
"the absolute contrast evaluation.");
}
if (!remove[mn]) num_removed++;
remove[mn] = true;
}
if (scene_num > 0) { // other scene
// {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1]} ;
if (dist > filt_dist[0]) {
System.out.println(name+": filtered out by "+NAME_MO[scene_num]+" distance from the main scene peak "+
NAME_FH[hf]+ " = "+dist+" > "+filt_dist[0]);
......@@ -3266,13 +3319,20 @@ public class OrthoMapsCollection implements Serializable{
* the ring around it (zone2).
* On return the matches_list data is modified - absolute contrasts are set, and best_pattern may be
* updated.
* @param force_round overwrite mode with 4 - force pattern index to full (round) one
* @param mode Update of the best sub-pattern index:
* 0 - keep current
* 1 - keep type (full/half) and allow half direction to change by -1,0, or +1
* 2 - keep type (full/half)
* 3 - no restrictions - find the best sub-pattern index from scratch.
* 3 - no restrictions - find the best sub-pattern index from scratch,
* 4 - force round (full pattern)
* @param neg_better center lower (colder) than around
* @param outliers_frac fraction of outliers to remove while calculating averages
* @param obscure_warm allow obscurant (that makes half-pattern from a full one only to be warmer
* than the object (defined below fraction between the object center region and peripheral
* ring. For hot objects obscurant should be colder than such fraction.
* @param obscure_frac fraction between center average and peripheral ring to compare when obscure_warm
* is set.
* @param gop GroundObjectPattern instance used
* @param matches_list list of pattern matches
* @param match_sort sorted list of indices in pattern matches list, so the first is the best match.
......@@ -3286,9 +3346,12 @@ public class OrthoMapsCollection implements Serializable{
* @return true
*/
public static boolean setAbsoluteContrasts(
boolean force_round,
int mode, // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any
boolean neg_better, // more negative is difference - stronger result
double outliers_frac,
boolean obscure_warm, // = true; // obscured can only be by warmer objects
double obscure_frac, // 0.25; // obscured threshold between center and outer
GroundObjectPattern gop,
ArrayList <ItemMatch> matches_list,
ArrayList<Integer> match_sort,
......@@ -3307,6 +3370,9 @@ public class OrthoMapsCollection implements Serializable{
boolean [] try_sub = new boolean [ipatterns.length];
int best_patt= match.getPatternMatch(gop).getBestSub() - 1; // 0-based
int num_halves = ipatterns.length - 1; // == 8
if (force_round) {
mode = 4;
}
switch (mode) {
case 0: try_sub[best_patt] = true; break; // only one
case 1: // keep type and +-1 for direction
......@@ -3338,27 +3404,35 @@ public class OrthoMapsCollection implements Serializable{
try_sub[i] = true;
}
break;
case 4: try_sub[0] = true; break; // only full pattern
}
double [] dir_contrasts = new double [try_sub.length];
double [][] dir_contrasts = new double [try_sub.length][];
int best_index = -1;
for (int i = 0; i < try_sub.length; i++) if (try_sub[i]) {
dir_contrasts[i]= OrthoMap.getAbsoluteContrast(
extracted_objects[mn], // double [] data,
ipatterns[i], // int [] ipattern,
outliers_frac, // double outliers_frac,
obscure_frac, // double obscure_frac, // 0.25; // obscured threshold between center and outer
null,
debug); // boolean debug)
if (neg_better) {
dir_contrasts[i] *= -1;
dir_contrasts[i][0] *= -1;
}
if (dir_contrasts[i] > 0) {
if ((best_index < 0) || (dir_contrasts[i] > dir_contrasts[best_index])) {
boolean bad_obscurant = obscure_warm && (dir_contrasts[i][1] < 0);
if (!bad_obscurant && (dir_contrasts[i][0] > 0)) {
if ((best_index < 0) || (dir_contrasts[i][0] > dir_contrasts[best_index][0])) {
best_index = i;
}
}
}
if (best_index < 0) {
best_index = best_patt;
best_index = 0;
if (debugLevel > -3) {
System.out.println("setAbsoluteContrasts(): no candidates found (probably after removing bad obscurants) #"
+mn+", giving a chance as full pattern. Was (1 for full):"+
(best_patt+1)+", new is "+(best_index + 1));
}
}
if (best_index != best_patt) {
if (debugLevel > -3) {
......@@ -3367,9 +3441,11 @@ public class OrthoMapsCollection implements Serializable{
}
match.getPatternMatch(gop).setBestSub(best_index + 1);
}
match.setAbsoluteContrast(dir_contrasts[best_index]); // the higher the better
match.setAbsoluteContrast(dir_contrasts[best_index][0]); // the higher the better
if (debugLevel > -3) {
System.out.println("setAbsoluteContrasts(): Set absolute contrast for match #"+mn+" = "+dir_contrasts[best_index]);
System.out.println("setAbsoluteContrasts(): Set absolute contrast for match #"+mn+" = "+
dir_contrasts[best_index][0]+
", over threshold="+dir_contrasts[best_index][1]+".");
}
if (masked_src != null) {
masked_src[mn] = new double [extracted_objects[mn].length];
......@@ -3377,6 +3453,7 @@ public class OrthoMapsCollection implements Serializable{
extracted_objects[mn], // double [] data,
ipatterns[best_index], // int [] ipattern,
outliers_frac, // double outliers_frac,
obscure_frac, // double obscure_frac, // 0.25; // obscured threshold between center and outer
masked_src[mn],
debug); // boolean debug)
}
......@@ -3390,7 +3467,7 @@ public class OrthoMapsCollection implements Serializable{
public static void showExtractedImages(
String prefix,
int scene_num,
int sort_pattern_index,
// int sort_pattern_index,
int extr_size,
GroundObjectPattern gop,
ArrayList <ItemMatch> matches_list,
......@@ -3452,7 +3529,7 @@ public class OrthoMapsCollection implements Serializable{
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));
match.getMatchValue(gop)); // ,sort_pattern_index));
}
imps_extracted[scene_num] = ShowDoubleFloatArrays.makeArrays(
extract_display[scene_num],
......
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