Commit dc9a97a8 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Added "roundness" and dual-scene for 100m

parent 33f052a0
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -916,6 +916,10 @@ public class ComboMatch {
        						zoom_lev,       // int              zoom_lev,
        						zoom_lev,       // int              zoom_lev,


        						debugLevel);    // final int        debugLevel)
        						debugLevel);    // final int        debugLevel)
        				if (warp == null) {
        					System.out.println("Failed correlateOrthoPair()");
        					return false;
        				}
        				//maps_collection.ortho_maps[gpu_pair[1]]
        				//maps_collection.ortho_maps[gpu_pair[1]]
        				if (process_correlation) {
        				if (process_correlation) {
        					if (update_match) {
        					if (update_match) {
+31 −0
Original line number Original line Diff line number Diff line
@@ -57,10 +57,41 @@ public class ItemMatch {
		}
		}
		return match.getMatches();
		return match.getMatches();
	}
	}
	
	public double [] getMatchValues(GroundObjectPattern groundObjectPattern) {
	public double [] getMatchValues(GroundObjectPattern groundObjectPattern) {
		return getMatchValues(groundObjectPattern.getPatternPath());
		return getMatchValues(groundObjectPattern.getPatternPath());
	}
	}
	
	
	/**
	 * Get ratio of the worst and best partial pattern correlation values
	 * @param groundObjectPattern
	 * @return
	 */
	public double getRoundness (GroundObjectPattern groundObjectPattern) {
		return getRoundness(groundObjectPattern.getPatternPath());
	}	
	
	public double getRoundness (String pattern_path) {
		ItemPatternMatch match = pattern_matches.get(pattern_path);
		if (match == null) {
			System.out.println("No matches found for pattern "+pattern_path);
			return Double.NaN;
		}
		double [] matches = match.getMatches();
		double best =  matches[1]; 
		double worst = matches[1];
		for (int i = 1; i < matches.length; i++) {
			if (matches[i] < worst) {
				worst = matches[i];
			}
			if (matches[i] > best) {
				best = matches[i];
			}
		}
		return worst/best;
	}
	
	
	public double getMatchValue(String pattern_path, int indx) {
	public double getMatchValue(String pattern_path, int indx) {
		ItemPatternMatch match = pattern_matches.get(pattern_path);
		ItemPatternMatch match = pattern_matches.get(pattern_path);
		if (match == null) {
		if (match == null) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -2193,6 +2193,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
					switch (ipatterns[n][i]) {
					switch (ipatterns[n][i]) {
					case 1: dbg_img[n][i] = 1.0; break;
					case 1: dbg_img[n][i] = 1.0; break;
					case 2: 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;
					}
					}
				}
				}
			}
			}
+77 −59
Original line number Original line Diff line number Diff line
@@ -1185,6 +1185,7 @@ public class OrthoMapsCollection implements Serializable{
				if (num_left < tp_tasks[0].length/4) {
				if (num_left < tp_tasks[0].length/4) {
					num_elevations--;
					num_elevations--;
					System.out.println("too few tiles remain, try again. metric_error="+metric_error);
					System.out.println("too few tiles remain, try again. metric_error="+metric_error);
					return null;
				}
				}
			}
			}


@@ -1726,7 +1727,7 @@ public class OrthoMapsCollection implements Serializable{
    				ImageDtt.THREADS_MAX, // int       threadsMax,
    				ImageDtt.THREADS_MAX, // int       threadsMax,
    				debugLevel-1);        // int       debug_level)
    				debugLevel-1);        // int       debug_level)
    	}		
    	}		
		if (debugLevel > 1) {
		if (debugLevel > 0) {
			String [] dbg_titles = {"x-raw","x_filled","y-raw","y_filled"};
			String [] dbg_titles = {"x-raw","x_filled","y-raw","y_filled"};
			double [][] dbg_img = {vf[0], vf_filled[0],vf[1], vf_filled[1]};
			double [][] dbg_img = {vf[0], vf_filled[0],vf[1], vf_filled[1]};
    		ShowDoubleFloatArrays.showArrays(
    		ShowDoubleFloatArrays.showArrays(
@@ -1781,7 +1782,7 @@ public class OrthoMapsCollection implements Serializable{
		int           abs_mode =          1; // 0 - keep, 1 keep type and if half +/-1, 2 - keep type, 3 - any, 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
		boolean       abs_invert =        true; // center has lower value than around
		double        abs_outliers_frac = 0.3;
		double        abs_outliers_frac = 0.3;
		boolean       abs_obscure_warm =  true; // obscured can only be by warmer objects 
		boolean       abs_obscure_warm =  false; // true; // obscured can only be by warmer objects 
		double        abs_obscure_frac =  0.25; // obscured threshold between center and outer 
		double        abs_obscure_frac =  0.25; // obscured threshold between center and outer 
		
		
		// filters
		// filters
@@ -1800,6 +1801,7 @@ 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_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.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_full_half_frac = {0.675, 0.5}; // second probably not needed, it is for main
		double []     filt_roundness =      {0.6,   0.0}; // second currently is not calculated/ used
		double        filt_abs_contrast = 80.0; // 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)
		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)
		boolean       convolve_after =    false; // true for old kernel tuning (kernel decimation before convolution)
@@ -1816,7 +1818,7 @@ public class OrthoMapsCollection implements Serializable{
				phaseCoeff[0] =     0.9;
				phaseCoeff[0] =     0.9;
//				adv_radius =       20; // pix?
//				adv_radius =       20; // pix?
			} else { // 100m defaults
			} else { // 100m defaults
				min_corrs[0] =      0.0119;
				min_corrs[0] =      0.009; // 119;
				abs_edge_frac =     0.35;
				abs_edge_frac =     0.35;
				abs_oversize =      2.2;		
				abs_oversize =      2.2;		
				filt_abs_contrast = 60;
				filt_abs_contrast = 60;
@@ -1882,6 +1884,8 @@ public class OrthoMapsCollection implements Serializable{
		gd.addNumericField("Maximal object height",             filt_height,      5,7,"m",  "Maximal object height to allow extra offset.");
		gd.addNumericField("Maximal object height",             filt_height,      5,7,"m",  "Maximal object height to allow extra offset.");
		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, 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("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 roundness of round, main",  filt_roundness[0],  5,7,"","Minimal ratio of worst half-pattern correlation to the full-pattern ones. Only for full patterns.");
		
		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("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("Ease absolute contrast for halves", filt_abs_easepart, 5,7,"","Ease absolute contast requirements for high AGL (low resolution).");
		//
		//
@@ -1937,6 +1941,7 @@ public class OrthoMapsCollection implements Serializable{
		filt_height =          gd.getNextNumber();
		filt_height =          gd.getNextNumber();
		filt_full_half_frac[0]=gd.getNextNumber();
		filt_full_half_frac[0]=gd.getNextNumber();
		filt_full_half_frac[1]=gd.getNextNumber();
		filt_full_half_frac[1]=gd.getNextNumber();
		filt_roundness[0]=gd.getNextNumber();
		filt_abs_contrast=     gd.getNextNumber();
		filt_abs_contrast=     gd.getNextNumber();
		filt_abs_easepart=     gd.getNextNumber();
		filt_abs_easepart=     gd.getNextNumber();
		debugLevel=      (int) gd.getNextNumber();
		debugLevel=      (int) gd.getNextNumber();
@@ -1976,6 +1981,7 @@ public class OrthoMapsCollection implements Serializable{
				filt_dist,           // double []     filt_dist,
				filt_dist,           // double []     filt_dist,
				filt_height,         // double        filt_height,
				filt_height,         // double        filt_height,
				filt_full_half_frac, // double []     filt_full_half_frac,
				filt_full_half_frac, // double []     filt_full_half_frac,
				filt_roundness, // double []     filt_half_full_frac,
				filt_abs_contrast,   // double        filt_abs_contrast, //  = 50.0;
				filt_abs_contrast,   // double        filt_abs_contrast, //  = 50.0;
				filt_abs_easepart,   // double filt_abs_easepart,
				filt_abs_easepart,   // double filt_abs_easepart,
				convolve_after,      // boolean       convolve_after,
				convolve_after,      // boolean       convolve_after,
@@ -2017,6 +2023,7 @@ public class OrthoMapsCollection implements Serializable{
			double []     filt_dist,
			double []     filt_dist,
			double        filt_height,
			double        filt_height,
			double []     filt_full_half_frac,
			double []     filt_full_half_frac,
			double []     filt_roundness,
			double        filt_abs_contrast, //  = 50.0;
			double        filt_abs_contrast, //  = 50.0;
			double        filt_abs_easepart,
			double        filt_abs_easepart,
			boolean       convolve_after, // mitigating kernels tuned for decimate before convolve
			boolean       convolve_after, // mitigating kernels tuned for decimate before convolve
@@ -2347,7 +2354,7 @@ public class OrthoMapsCollection implements Serializable{
			if (num_non_overlap > 0) {
			if (num_non_overlap > 0) {
				System.out.println("Removed "+num_non_overlap+" objects outside of the scenes overlap, "+match_sort.size()+" remain");
				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 %3s"," # ", "  x/y  ", " best ","sub"));
			System.out.print(String.format("%4s: %9s %8s %6s %3s"," # ", "  x/y  ", " best ","round", "sub"));
			for (int j = 0; j < (corrs_out[scene_num].length + 1); j++) if (j != sort_pattern_index) {
			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(" %8s ","match_"+j));
			}
			}
@@ -2357,10 +2364,11 @@ public class OrthoMapsCollection implements Serializable{
				ItemMatch match = matches_list.get(indx);
				ItemMatch match = matches_list.get(indx);
				double [] match_values = match.getMatchValues(gops[scene_num]);
				double [] match_values = match.getMatchValues(gops[scene_num]);
				int [] icenter_xy = match.getIntXY();
				int [] icenter_xy = match.getIntXY();
				System.out.print(String.format("%4d: %4d/%4d %8.5f %3d",
				System.out.print(String.format("%4d: %4d/%4d %8.5f %6.3f %3d",
						i,
						i,
						icenter_xy[0],icenter_xy[1],
						icenter_xy[0],icenter_xy[1],
						match.getMatchValue(gops[scene_num]), // ,sort_pattern_index),
						match.getMatchValue(gops[scene_num]),
						match.getRoundness (gops[scene_num]),
						match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
						match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
				for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
				for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
					System.out.print(String.format(" %8.5f",match_values[j]));
					System.out.print(String.format(" %8.5f",match_values[j]));
@@ -2564,6 +2572,7 @@ public class OrthoMapsCollection implements Serializable{
							filt_dist,          // double []             filt_dist,
							filt_dist,          // double []             filt_dist,
							filt_height,        // double                filt_height,
							filt_height,        // double                filt_height,
							filt_full_half_frac,// double []             filt_full_half_frac,
							filt_full_half_frac,// double []             filt_full_half_frac,
							filt_roundness,     // double []             filt_roundness,
							filt_abs_contrast,  // double                filt_abs_contrast,
							filt_abs_contrast,  // double                filt_abs_contrast,
							filt_abs_easepart,  // double                filt_abs_easepart,
							filt_abs_easepart,  // double                filt_abs_easepart,
							gops[scene_num],    // GroundObjectPattern   gop,
							gops[scene_num],    // GroundObjectPattern   gop,
@@ -2640,7 +2649,7 @@ public class OrthoMapsCollection implements Serializable{
				if (indices.length > 1) {
				if (indices.length > 1) {
					// print updated table after some scenes may be removed by the filter
					// print updated table after some scenes may be removed by the filter
					System.out.println("\nAfter first scene filtering:");
					System.out.println("\nAfter first scene filtering:");
					System.out.print(String.format("%4s: %9s %8s %8s %3s"," # ", "  x/y  ", " best ","contrast","sub"));
					System.out.print(String.format("%4s: %9s %8s %8s %6s %3s"," # ", "  x/y  ", " best ","contrast","round", "sub"));
					for (int j = 0; j < (corrs_out[scene_num].length + 1); j++) if (j != sort_pattern_index) {
					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(" %8s ","match_"+j));
					}
					}
@@ -2653,13 +2662,13 @@ public class OrthoMapsCollection implements Serializable{
						int [] icenter_xy = match.getIntXY();
						int [] icenter_xy = match.getIntXY();
//						double best_val = match.getMatchValue(gops[scene_num],sort_pattern_index);
//						double best_val = match.getMatchValue(gops[scene_num],sort_pattern_index);
						// so it is updated after best subpattern could be changed in setAbsoluteContrasts()
						// 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];
						//match_values[match.getPatternMatch(gops[scene_num]).getBestSub() -1];
						System.out.print(String.format("%4d: %4d/%4d %8.5f %8.3f %3d",
						System.out.print(String.format("%4d: %4d/%4d %8.5f %8.3f %6.3f %3d",
								i,
								i,
								icenter_xy[0],icenter_xy[1],
								icenter_xy[0],icenter_xy[1],
								best_val,
								match.getMatchValue(gops[scene_num]),
								match.getAbsoluteContrast(),
								match.getAbsoluteContrast(),
								match.getRoundness(gops[scene_num]),
								match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
								match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
						for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
						for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
							System.out.print(String.format(" %8.5f",match_values[j]));
							System.out.print(String.format(" %8.5f",match_values[j]));
@@ -2761,6 +2770,7 @@ public class OrthoMapsCollection implements Serializable{
						filt_dist,          // double []             filt_dist,
						filt_dist,          // double []             filt_dist,
						filt_height,        // double                filt_height,
						filt_height,        // double                filt_height,
						filt_full_half_frac,// double []             filt_other_frac, // null - disable, for all full (round) patterns.
						filt_full_half_frac,// double []             filt_other_frac, // null - disable, for all full (round) patterns.
						filt_roundness,     // double []             filt_roundness,
						filt_abs_contrast,  // double                filt_abs_contrast,
						filt_abs_contrast,  // double                filt_abs_contrast,
						filt_abs_easepart,  // double                filt_abs_easepart,
						filt_abs_easepart,  // double                filt_abs_easepart,
						gops[scene_num],    // GroundObjectPattern   gop,
						gops[scene_num],    // GroundObjectPattern   gop,
@@ -2858,7 +2868,7 @@ public class OrthoMapsCollection implements Serializable{
							Math.sqrt(scene_xy_offset[0]*scene_xy_offset[0]+scene_xy_offset[1]*scene_xy_offset[1])+" pix");
							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"));
				System.out.print(String.format("%4s: %9s %8s %8s %6s %3s"," # ", "  x/y  ", " best ","contrast","round","sub"));
				for (int j = 0; j < (corrs_out[scene_num].length + 1); j++) if (j != sort_pattern_index) {
				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(" %8s ","match_"+j));
				}
				}
@@ -2877,11 +2887,12 @@ public class OrthoMapsCollection implements Serializable{
					ItemMatch match = matches_list.get(indx);
					ItemMatch match = matches_list.get(indx);
					double [] match_values = match.getMatchValues(gops[scene_num]);
					double [] match_values = match.getMatchValues(gops[scene_num]);
					int [] icenter_xy = match.getIntXY();
					int [] icenter_xy = match.getIntXY();
					System.out.print(String.format("%4d: %4d/%4d %8.5f %8.3f %3d",
					System.out.print(String.format("%4d: %4d/%4d %8.5f %8.3f %6.3f %3d",
							i,
							i,
							icenter_xy[0],icenter_xy[1],
							icenter_xy[0],icenter_xy[1],
							match.getMatchValue(gops[scene_num],sort_pattern_index),
							match.getMatchValue(gops[scene_num]), // ,sort_pattern_index),
							match.getAbsoluteContrast(),
							match.getAbsoluteContrast(),
							match.getRoundness(gops[scene_num]),
							match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
							match.getPatternMatch(gops[scene_num]).getBestSub())); // 1-based
					for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
					for (int j = 0; j < match_values.length; j++) if (j != sort_pattern_index) {
						System.out.print(String.format(" %8.5f",match_values[j]));
						System.out.print(String.format(" %8.5f",match_values[j]));
@@ -2915,7 +2926,7 @@ public class OrthoMapsCollection implements Serializable{
						//			System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f",
						//			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];
						double o_fhr = filter_data[1][i][0][0]/filter_data[1][i][1][0];
						System.out.print(String.format(
						System.out.print(String.format(
								" %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",
								" %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",
								// for second full - everything and parallel/perpendicular+elevation
								// 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][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
								filter_data[1][i][0][3], filter_data[1][i][0][4], filter_data[1][i][0][5], // full: dist, dx, dy
@@ -3151,6 +3162,7 @@ public class OrthoMapsCollection implements Serializable{
			double []             filt_dist,
			double []             filt_dist,
			double                filt_height,
			double                filt_height,
			double []             filt_full_half_frac,
			double []             filt_full_half_frac,
			double []             filt_roundness,
			double                filt_abs_contrast,
			double                filt_abs_contrast,
			double                filt_abs_easepart,
			double                filt_abs_easepart,
			GroundObjectPattern   gop,
			GroundObjectPattern   gop,
@@ -3181,8 +3193,8 @@ public class OrthoMapsCollection implements Serializable{
			int [] ixy = match.getIntXY();
			int [] ixy = match.getIntXY();
			String name = ixy[0]+"/"+ixy[1];
			String name = ixy[0]+"/"+ixy[1];
			double abs_contrast = match.getAbsoluteContrast();
			double abs_contrast = match.getAbsoluteContrast();
			double roundness = match.getRoundness(gop);
			int best_patt= match.getPatternMatch(gop).getBestSub(); // 1-based	 		
			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
			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[num_scenes];
			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){
			for (int scene_num = 0; scene_num < num_scenes; scene_num++) if (filter_data[scene_num] != null){
@@ -3199,7 +3211,12 @@ public class OrthoMapsCollection implements Serializable{
				if (!remove[mn]) num_removed++;
				if (!remove[mn]) num_removed++;
				remove[mn] = true;
				remove[mn] = true;
			}
			}
			
			if (!is_partial && (roundness < filt_roundness[0])) {
				System.out.println(name+": filtered out by "+NAME_MO[0]+" scene because it is full/round, and its roundness = "+
						roundness+ " < "+filt_roundness[0]);
				if (!remove[mn]) num_removed++;
				remove[mn] = true;
			}			
			for (int hf = 0; hf < 2; hf++) {
			for (int hf = 0; hf < 2; hf++) {
				for (int scene_num = 0; scene_num < num_scenes; 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])) {
					if (Double.isNaN(filter_data[scene_num][mn][hf][0])) {
@@ -3224,7 +3241,7 @@ public class OrthoMapsCollection implements Serializable{
								NAME_FH[hf]+ " = "+corr_val+" < "+ min_corrs_other[scene_num][hf]);
								NAME_FH[hf]+ " = "+corr_val+" < "+ min_corrs_other[scene_num][hf]);
						if (scene_num == 0) {
						if (scene_num == 0) {
							System.out.println(
							System.out.println(
									"For the main scene it could happen if the sub_pattern index changed after\n"+
									"For the main scene it could happen if the sub_pattern index changed after"+
							" the absolute contrast evaluation.");
							" the absolute contrast evaluation.");
						}
						}
						if (!remove[mn]) num_removed++;
						if (!remove[mn]) num_removed++;
@@ -3408,7 +3425,7 @@ public class OrthoMapsCollection implements Serializable{
			}
			}
			double [][] dir_contrasts = new double [try_sub.length][];
			double [][] dir_contrasts = new double [try_sub.length][];
			int best_index = -1;
			int best_index = -1;
			for (int i = 0; i < try_sub.length; i++) if (try_sub[i]) {
			for (int i = 0; i < try_sub.length; i++) if ((i==0) || try_sub[i]) {
				dir_contrasts[i]= OrthoMap.getAbsoluteContrast(
				dir_contrasts[i]= OrthoMap.getAbsoluteContrast(
						extracted_objects[mn], // double [] data,
						extracted_objects[mn], // double [] data,
						ipatterns[i],          // int    [] ipattern,
						ipatterns[i],          // int    [] ipattern,
@@ -3420,7 +3437,7 @@ public class OrthoMapsCollection implements Serializable{
					dir_contrasts[i][0] *= -1;
					dir_contrasts[i][0] *= -1;
				}
				}
				boolean bad_obscurant = obscure_warm && (dir_contrasts[i][1] < 0);
				boolean bad_obscurant = obscure_warm && (dir_contrasts[i][1] < 0);
				if (!bad_obscurant && (dir_contrasts[i][0] > 0)) {
				if (try_sub[i] && !bad_obscurant && (dir_contrasts[i][0] > 0)) {
					if ((best_index < 0) || (dir_contrasts[i][0] > dir_contrasts[best_index][0])) {
					if ((best_index < 0) || (dir_contrasts[i][0] > dir_contrasts[best_index][0])) {
						best_index = i;
						best_index = i;
					}
					}
@@ -3428,6 +3445,7 @@ public class OrthoMapsCollection implements Serializable{
			}
			}
			if (best_index < 0) {
			if (best_index < 0) {
				best_index = 0;
				best_index = 0;
				
				if (debugLevel > -3) {
				if (debugLevel > -3) {
					System.out.println("setAbsoluteContrasts(): no candidates found (probably after removing bad obscurants) #"
					System.out.println("setAbsoluteContrasts(): no candidates found (probably after removing bad obscurants) #"
							+mn+", giving a chance as full pattern. Was (1 for full):"+
							+mn+", giving a chance as full pattern. Was (1 for full):"+