Commit 640b8df3 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Cleaned up pattern matching, implemented re-centering for correlations,

working snapshot
parent c8f99e6d
Loading
Loading
Loading
Loading
+31 −8
Original line number Diff line number Diff line
@@ -293,6 +293,22 @@ public class DoubleFHT {
		return result;
	}

	public double [] getFrequencyFilter (
			double [] data, // just to find out size
			double highPassSigma,
			double lowPassSigma
			) {
		double [] filter= null;
		if ((highPassSigma> 0.0) || (lowPassSigma> 0.0)) {
			updateMaxN(data);
			createFrequencyFilter(highPassSigma, lowPassSigma); // for repetitive calls will reuse mask
			filter =this.freqMask;
		}
		return filter;
	}
	
	
	
	/**
	 * Invert kernel for deconvolutions. Kernel is assumed to fade near edges
	 * @param data     source kernel, square, power of 2 sides. Data is destroyed
@@ -314,7 +330,6 @@ public class DoubleFHT {
			filter =this.freqMask;
		}
		return invert (data, fat_zero, filter);
		
	}
	
	/**
@@ -401,8 +416,6 @@ public class DoubleFHT {
	}

	public double[] phaseCorrelate(double[] first, double phaseCoeff, double high_pass, double low_pass, // high/low
																											// pass
																											// filtering
		double[] fht_save) { // null-OK
		updateMaxN(first);
		double[] filter = null;
@@ -503,7 +516,10 @@ public class DoubleFHT {
	 * @return phase correlation, first still contains original transformed!
	 */
	public double[] phaseCorrelatePattern( // new
			double[] first, double[] secondFD, double phaseCoeff, double[] filter, // high/low pass filtering
			double[] first,
			double[] secondFD,
			double phaseCoeff,
			double[] filter, // high/low pass filtering
			double[] first_save) { // null-OK
		if (first.length != secondFD.length) {
			IJ.showMessage("Error", "Correlation arrays should be the same size");
@@ -537,7 +553,9 @@ public class DoubleFHT {
	 */

	public double[] convolvePattern( // new
			double[] first, double[] secondFD, double[] filter, // high/low pass filtering
			double[] first,
			double[] secondFD,
			double[] filter, // high/low pass filtering
			double[] first_save) { // null-OK
		if (first.length != secondFD.length) {
			IJ.showMessage("Error", "Correlation arrays should be the same size");
@@ -595,11 +613,16 @@ public class DoubleFHT {
		return first;
	}

	public double[] convolve(double[] first, double[] second) {
	public double[] convolve(
			double[] first,
			double[] second) {
		return convolve(first, second, null);
	}

	public double[] convolve(double[] first, double[] second, double[] filter) { // high/low pass filtering
	public double[] convolve(
			double[] first,
			double[] second,
			double[] filter) { // high/low pass filtering
		// System.out.println("correlate");
		if (first.length != second.length) {
			IJ.showMessage("Error", "Correlation arrays should be the same size");
+26 −17
Original line number Diff line number Diff line
@@ -544,13 +544,13 @@ public class ComboMatch {
			}
			imp_obj.setRoi(roi);
			// calculate statistics for cor_ret[i]
			double [][] stats = new double [object_stack.length][];
			CorrelationPeakStats [] stats = new CorrelationPeakStats [object_stack.length];
			double search_rad = 15.0;
			double frac_max =   0.5;
			double other_rad = 25;
			for (int i = 0; i < object_stack.length; i++) {
				double [] a_cent= {corr_size/2+centers[i][0],corr_size/2+centers[i][1]};
				stats[i]=ObjectLocation.getMaxLocArea(
				stats[i]=new CorrelationPeakStats(
						corr_ret[i], // double [] data, // square data
						a_cent, // centers[i],  // double [] cent_xy, // if null, use center of the square
						search_rad,  // double    radius, // search for maximum within this radius
@@ -567,7 +567,8 @@ public class ComboMatch {
				ObjectLocation ol =  object_list.get(i);
				System.out.println(String.format("%2d (%4d/%4d): %7.5f %7.3f %7.3f %7.3f %7.3f %7.3f %17s",
						i, ol.getPixels()[0], ol.getPixels()[1],
						stats[i][0],stats[i][1],stats[i][2],stats[i][3],stats[i][4]+centers[i][0],stats[i][5]+centers[i][1],
						stats[i].best_d,stats[i].eff_rad,stats[i].elong,stats[i].dist,
						stats[i].cent_offs[0]+centers[i][0],stats[i].cent_offs[1]+centers[i][1],
						ol.getName()));
			}
			System.out.println();
@@ -868,7 +869,8 @@ public class ComboMatch {
					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)
							null, // warp);    // FineXYCorr    warp)
							null); // double [][]   ground_planes) TODO: add calculation of the ground plane for single images
					//						imp_pat_match.show();
				}
        		
@@ -895,11 +897,16 @@ public class ComboMatch {
        			boolean  batch_mode = true; // false; //  true;
        			boolean ignore_prev_rms = true;
        			Rectangle woi = new Rectangle(); // used to return actual woi from correlateOrthoPair()
        			double [][] ground_planes = null;
        			for (int zi = 0; zi < zooms.length; zi++) {
        				zoom_lev = zooms[zi];
        				if (zoom_lev >=1000) {
        					break;
        				}
        				boolean show_vf = render_match || pattern_match;
        				if (render_match || pattern_match) {
        					ground_planes = new double [gpu_pair.length][];
        				}
        				// will modify affines[1], later add jtj, weight, smth. else?
        				FineXYCorr warp = maps_collection.correlateOrthoPair(
        						clt_parameters,  // CLTParameters    clt_parameters,
@@ -914,7 +921,8 @@ public class ComboMatch {
        						affines,         // double [][][]    affines, // on top of GPS offsets
        						woi,             // Rectangle        woi,
        						zoom_lev,        // int              zoom_lev,

        						show_vf,         // boolean show_vf,
        						ground_planes,   // double [][]      ground_planes, // null or double[2] - will return ground planes
        						debugLevel);     // final int        debugLevel)
        				if (warp == null) {
        					System.out.println("Failed correlateOrthoPair()");
@@ -951,7 +959,8 @@ public class ComboMatch {
        					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)
        							warp,           // FineXYCorr    warp)
        							ground_planes); // double [][]      ground_planes); // null or
        					//						imp_pat_match.show();
        				}
        				if (render_match) {
+210 −0
Original line number Diff line number Diff line
package com.elphel.imagej.orthomosaic;

import java.util.Arrays;

import com.elphel.imagej.tileprocessor.TileNeibs;

import Jama.EigenvalueDecomposition;
import Jama.Matrix;

public class CorrelationPeakStats {
	public double best_d;
	public double eff_rad;
	public double elong;
	public double dist;
	public double [] cent_offs;
	public double max_other;
	public CorrelationPeakStats(
			double [] data, // square data
			double [] cent_xy, // if null, use center of the square
			double    radius, // search for maximum within this radius
			double    frac_max,
			double    other_radius,
			int       debugLevel) {
		double [] stats = getStatsNaN(
				data,        // square data
				cent_xy,     // if null, use center of the square
				radius,      // search for maximum within this radius
				frac_max,
				other_radius,
				debugLevel);
		best_d =  stats[0];
		eff_rad = stats[1];
		elong =   stats[2];
		dist =    stats[3];
		cent_offs = new double [] {stats[4], stats[5]};
		max_other = stats[6];
	}
	
	int [] getIntOffset() {
		return new int[] {(int) Math.round(cent_offs[0]), (int) Math.round(cent_offs[1])};
	}
	/**
	 * Search for maximum within specified radius from the center or specified offset from the center
	 * @param data square data
	 * @param cent_xy offset from the square center to search
	 * @param radius search for maximum within this radius
	 * @param frac_max fraction of maximum to measure area
	 * @param other_radius measure maximal disconnected pixel fraction of the maximum within this radius
	 * @return {maximum, area, dist, x, y}. No interpolation yet, each returned value is integer. 
	 * Returns null if no local maximum within area. x,y are offsets from the (provided) center 
	 */
	public static double [] getStatsNaN(
			double [] data, // square data
			double [] cent_xy, // if null, use center of the square
			double    radius, // search for maximum within this radius
			double    frac_max,
			double    other_radius,
			int       debugLevel) {
		double [] rslt = getStats(
				data, // square data
				cent_xy, // if null, use center of the square
				radius, // search for maximum within this radius
				frac_max,
				other_radius,
				debugLevel);
		if (rslt != null) {
			return rslt;
		} else {
			return new double[] {Double.NaN,Double.NaN,Double.NaN,Double.NaN,Double.NaN,Double.NaN,Double.NaN};
		}
	}

	public static double [] getStats(
			double [] data, // square data
			double [] cent_xy, // if null, use center of the square
			double    radius, // search for maximum within this radius
			double    frac_max,
			double    other_radius, // may be 0 if not needed
			int       debugLevel) {
		boolean   debug = debugLevel > 1;
		int size = (int) Math.sqrt(data.length);
		if (cent_xy == null) {
			cent_xy = new double [] {size/2, size/2};
		}
		double maxr2 = radius * radius;
		double best_d = 0;
		int best_indx = -1;
		int min_x = Math.max(1, (int) Math.floor(cent_xy[0]-radius));
		int min_y = Math.max(1, (int) Math.floor(cent_xy[1]-radius));
		int max_x = Math.min(size-2, (int) Math.ceil(cent_xy[0]+radius));
		int max_y = Math.min(size-2, (int) Math.ceil(cent_xy[1]+radius));
		for (int y = min_y; y <= max_y; y++) { // do not search on very edges
			double dy = (y-cent_xy[1]);
			double y2 = dy*dy;
			if (y2 < maxr2) {
				for (int x = min_x; x <= max_x; x++) {
					double dx = x - cent_xy[0];
					double r2 = y2 + dx*dx;
					if (r2 < maxr2) {
						int indx = y * size + x;
						double d = data[indx];
						if (d > best_d) {
							best_indx = indx;
							best_d = d;
						}
					}
				}
			}
		}
		if (best_indx < 0) {
			return null;
		}
		// is it local max?
		if     ((data[best_indx - 1] >    best_d) || (data[best_indx + 1] >    best_d) ||
				(data[best_indx - size] > best_d) || (data[best_indx + size] > best_d)) {
			return null; // on the edge, not a local max
		}
		
		boolean [] above_thresh = new boolean [data.length];
		double thresh = best_d * frac_max;
		for (int i = 0; i < data.length; i++) {
			above_thresh[i] = data[i] > thresh;
		}
		
		int [] clusters = (new TileNeibs(size,size)).enumerateClusters(
				above_thresh, // boolean [] tiles,
				null,   // int []     num_clusters,
				false); // boolean ordered)
		int center_cluster = clusters[best_indx];

		int best_x = best_indx % size;
		int best_y = best_indx / size;
		double xc = best_x - cent_xy[0];
		double yc = best_y - cent_xy[1];
		

		double s0=0, sx=0, sy=0, sx2 = 0, sy2=0, sxy = 0;
		for (int i = 0; i < clusters.length; i++) {
			if (clusters[i] == center_cluster) {
				double y = i / size - (yc + cent_xy[1]); //(yc + cent_xy[1]) - absolute, from (0,0)
				double x = i % size - (xc + cent_xy[0]);
				double w = data[i]-thresh;
				s0 += w;
				sx += w * x;
				sy += w * y;
				sx2 += w * x * x;
				sy2 += w * y * y;
				sxy += w * x * y;
			}
		}
		double cxx = sx2 - sx * sx / s0, cyy= sy2 - sy * sy / s0, cxy = sxy - sx * sy / s0; 
		/*
		 * sum(Mi*(Xi-avg(X))^2) =          SX2 - SX^2/S0		
		 * sum(Mi*(Yi-avg(Y))^2) =          SY2 - SY^2/S0
		 * sum(Mi*(Xi-avg(X)*(Yi-avg(Y))) =	SXY - SX*SY / S0	
		 */
		Matrix covar = new Matrix(new double[][] {{cxx, cxy},{cxy,cyy}});
		double [] cent_offs = {sx/s0 + xc,sy/s0 + yc};
		EigenvalueDecomposition eig = covar.eig(); 
		
		double [] eigval = {eig.getD().get(0, 0),eig.getD().get(1, 1)};
		Arrays.sort(eigval); // ascending
		double elong = Math.sqrt(eigval[1]/eigval[0]);
		double eff_rad = Math.sqrt(Math.sqrt(eigval[1]*eigval[0]));
		double dist = Math.sqrt(cent_offs[0]*cent_offs[0] + cent_offs[1]*cent_offs[1]);
		double max_other = 0.0;
		if (other_radius > 0) { // only calculate if asked for
			double or2 = other_radius*other_radius;
			min_x = Math.max(1, (int) Math.floor(best_x-other_radius));
			min_y = Math.max(1, (int) Math.floor(best_y-other_radius));
			max_x = Math.min(size-2, (int) Math.ceil(best_x+other_radius));
			max_y = Math.min(size-2, (int) Math.ceil(best_y+other_radius));
			for (int y = min_y; y <= max_y; y++) { // do not search on very edges
				double dy = (y-best_y);
				double y2 = dy*dy;
				if (y2 < or2) {
					for (int x = min_x; x <= max_x; x++) {
						double dx = x - best_x;
						double r2 = y2 + dx*dx;
						if (r2 < or2) {
							int indx = y * size + x;
							if (clusters[indx] != center_cluster) { // only disconnected from the central area
								double d = data[indx];
								if (d > max_other) {
									max_other = d;
								}
							}
						}
					}
				}
			}
			max_other /= best_d;
		}
		
		if (debug) {
			System.out.println("\ncenter offset ["+(sx/s0)+","+(sy/s0)+"] , from center: ["+cent_offs[0]+","+cent_offs[1]+"]");
			System.out.println("Covariance matrix:");
			covar.print(8, 6);
			System.out.println("eig.getV()");
			eig.getV().print(8, 6);
			System.out.println("eig.getD()");
			eig.getD().print(8, 6);
			System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f, mo=%5.3f",
					best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other));
		}
		
		return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other} ;
	}
	
}
+290 −11
Original line number Diff line number Diff line
@@ -4,12 +4,111 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

import com.elphel.imagej.common.ShowDoubleFloatArrays;

import ij.ImagePlus;
import ij.Prefs;
import ij.gui.PointRoi;
import ij.io.FileSaver;

public class ItemMatch {
	public double [] combo_pxy; // combo image {pixel_x, pixel_y}
	public double [] lla; // add later
	public HashMap<String, ItemPatternMatch> pattern_matches = new HashMap<String, ItemPatternMatch>();
	public double abs_contrast = 0;
	public ItemMatch (double [] combo_pxy) {
	public CorrelationPeakStats[][] filter_data; // [scene][half/full] 
	public double [][]   extracted_objects;        // [scene][pix]
	public double [][]   extracted_nodc;           // [scene][pix]
	public double [][]   extracted_masked;         // [scene][pix]
	public double [][][] extr_corr;                // [scene][pix][patt]
	public double [][]   extr_corr_half;           // [scene][pix][h/f]
	public boolean removed = false;
	
	public ItemMatch (
			int num_scenes,
			double [] combo_pxy) {
		setComboPXY(combo_pxy);
		this.combo_pxy = combo_pxy;
		filter_data =       new CorrelationPeakStats[num_scenes][2];
		extracted_objects = new double [num_scenes][];
		extracted_nodc =    new double [num_scenes][];
		extracted_masked =  new double [num_scenes][];
		extr_corr =         new double [num_scenes][][];
		extr_corr_half =    new double [num_scenes][];
		removed =           false;
	}
	
	public void setRemoved (boolean removed) {
		this.removed = removed;
	}

	public void remove () {
		this.removed = true;
	}
	
	public boolean isRemoved() {
		return removed;
	}
	
	public void setCorrFull(
			int scene_num,
			int num_patt,
			double [] corr_data) {
		extr_corr[scene_num] = new double [num_patt][];
		extr_corr[scene_num][0] = corr_data;
	}

	public void setCorr(
			int scene_num,
			int patt_index,
			double [] corr_data) {
		extr_corr[scene_num][patt_index] = corr_data;
	}
	
	public double [] getCorr(
			int scene_num,
			int patt_index) {
		return extr_corr[scene_num][patt_index];
	}
	public double [][] getCorrs(
			int scene_num) {
		return extr_corr[scene_num];
	}

	public void setCorrHalf(
			int     scene_num,
			int     best_patt, // 0-full
			boolean combine_full) {
		
		extr_corr_half[scene_num] = extr_corr[scene_num][best_patt].clone();
		if (combine_full) {
			double full_max_value = filter_data[scene_num][0].best_d; // [0];
			if (!Double.isNaN(full_max_value)) {
				// multiply by full correlation, delete by full correlation maximum
				for (int i = 0; i < extr_corr_half[scene_num].length; i++){
					extr_corr_half[scene_num][i] *=
							Math.max(0, extr_corr[scene_num][0][i]/full_max_value);
				}
			}

		}
	}
	
	public void setCorrHalf(
			int scene_num,
			double [] corr_data) {
		extr_corr_half[scene_num] = corr_data;
	}
	
	public double [] getCorrHalf(
			int scene_num) {
		return extr_corr_half[scene_num];
	}
	
	
	
	
	public void setComboPXY(double [] combo_pxy) {
		this.combo_pxy = combo_pxy;
	}
	
@@ -27,7 +126,7 @@ public class ItemMatch {
		return new int [] {(int) Math.round(combo_pxy[0]), (int) Math.round(combo_pxy[1])};
	}
	
	public void addPatternMatches(
	public void addPatternMatches( // updates existing too
			GroundObjectPattern groundObjectPattern,
			double [] matches,
			int      best_sub) {
@@ -101,6 +200,8 @@ public class ItemMatch {
		return match.getMatch(indx);
	}

	
	
	/**
	 * Return correlation value as the one of the pattern correlations pointed
	 * by the best subpattern index.
@@ -126,28 +227,206 @@ public class ItemMatch {
	public static ArrayList<Integer> sortByMatch(
			ArrayList<ItemMatch> match_list,
			GroundObjectPattern  groundObjectPattern,
			boolean              keep_removed,
			int                  indx){
		String pattern_path = groundObjectPattern.getPatternPath();
		return sortByMatch(match_list, pattern_path, indx);
		return sortByMatch(match_list, pattern_path, keep_removed, indx);
	}
	
	public static ArrayList<Integer> sortByMatch(
			ArrayList<ItemMatch> match_list,
			String               pattern_path,
			boolean              keep_removed,
			int                  indx){
		double large_enough = 1.0;
		ArrayList<Integer> result_list= new ArrayList<Integer>(match_list.size());
		for (int i = 0; i < match_list.size(); i++) {
			if (keep_removed || !match_list.get(i).isRemoved()) {
				result_list.add(i);
			}
		}
		Collections.sort(result_list, new Comparator<Integer>() {
			@Override
			public int compare(Integer lhs, Integer rhs) {
				double rhsd = match_list.get(rhs).getMatchValue(pattern_path, indx);
				double lhsd = match_list.get(lhs).getMatchValue(pattern_path, indx);
				return (rhsd > lhsd) ? 1 : (rhsd < lhsd) ? -1 : 0; // recreasing
				ItemMatch rhsm = match_list.get(rhs);
				ItemMatch lhsm = match_list.get(lhs);
				double rhsd = rhsm.getMatchValue(pattern_path, indx) - (rhsm.isRemoved() ? large_enough:0 );
				double lhsd = lhsm.getMatchValue(pattern_path, indx) - (lhsm.isRemoved() ? large_enough:0 );
				return (rhsd > lhsd) ? 1 : (rhsd < lhsd) ? -1 : 0; // decreasing
			}
		});
		return result_list;
	}
	
	public static void setExtractedObjects(
			int                   scene_num,
			int                   extr_size,
			GroundObjectPattern   gop,
			ArrayList <ItemMatch> matches_list,
			ArrayList<Integer>    match_sort,
			double[]              data,
			int                   width,
			int                   debugLevel) {
		if (match_sort.isEmpty()) {
			System.out.println("List of detected objects is empty, nothing to process");
			return;
		}
		for (int mn=0; mn < match_sort.size(); mn++) {
			int indx =match_sort.get(mn);
			ItemMatch match = matches_list.get(indx);
			match.extractObject(
					data,       // double [] data,
					width,      // int       width,
					scene_num,  // int       scene_num,
					extr_size); // int       extr_size);
		}
	}
	
	public void extractObject(
			double [] data,
			int       width,
			int       scene_num,
			int       extr_size) {
		double [] center_xy = getXY();
		double [] extr_data = ObjectLocation.extractObjectImage(
				center_xy,  // double [] center_xy,
				extr_size,  // int       size,
				data,       // double [] src_img,
				width);     // int width)
		setExtractedObject(extr_data, scene_num);
	}
	

	public void extractCorrs(
			double [][] corr_data,
			int         width,
			int         scene_num,
			int         extr_size) {
		double [] center_xy = getXY();
		extr_corr[scene_num] = new double [corr_data.length][];
		for (int i = 0; i < corr_data.length; i++) {
			extr_corr[scene_num][i] = ObjectLocation.extractObjectImage(
					center_xy,    // double [] center_xy,
					extr_size,    // int       size,
					corr_data[i], // double [] src_img,
					width);       // int width)
		}
	}
	
	
	
	
	public void setExtractedObject(
			double [] data,
			int       scene_num) {
		extracted_objects[scene_num] = data;
		extracted_nodc[scene_num] = data.clone();
		OrthoMap.removeDC(extracted_nodc[scene_num]); 
	}
	
	public void setMaskedObject(
			double [] data,
			int       scene_num) {
		extracted_masked[scene_num] = data;
	}
	public void setCorrData(
			double [] data,
			int       scene_num,
			int       half_full) { // 1 - half, 0 - full
		extr_corr[scene_num][half_full] = data;
	}
	
	public static ImagePlus getImageExtracts(
			String                prefix, // include PC, filter here
			String                suffix, // w/o .tiff
			boolean               show,
			boolean               save,
			boolean               show_removed,
			String                save_dir,
			int                   scene_num,
			boolean               nodc,
			int                   mode, // 0 - extract, 1 - masked, 2 - corr full, 3 - corr half
			boolean               show_centers,
			int                   extr_size,
			GroundObjectPattern   gop,
			ArrayList <ItemMatch> matches_list,
			ArrayList<Integer>    match_sort,
			int                   debugLevel) {
		if (match_sort.isEmpty()) {
			System.out.println("List of detected objects is empty, nothing to display");
			return null;
		}
		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);
		}
		int num_slices = match_sort.size();
		if (!show_removed) {
			num_slices=0;
			for (int mn=0; mn < match_sort.size(); mn++) {
				if (!matches_list.get(match_sort.get(mn)).isRemoved()) {
					num_slices++;
				}
			}			
		}
		String []   extr_titles = new String [num_slices];
		double [][] extr_data = new double [num_slices][];
		String title = prefix; 
		switch (mode) {
		case 0: title += "_objects_" + scene_num + (nodc ? "_no-DC":"_with-DC"); break;
		case 1: title += "_contrast-masks";  break;
		case 2: title += "_objects_"+scene_num+"_corr_full";  break;
		case 3: title += "_objects_"+scene_num+"_corr_halves";  break;
		}
		if (suffix != null) {
			title += suffix;
		}
		title += ".tiff";
		int indx = 0;
		for (int mn=0; mn < match_sort.size(); mn++) {
			ItemMatch match = matches_list.get(match_sort.get(mn));
			if (show_removed || !matches_list.get(match_sort.get(mn)).isRemoved()) {
				int [] ixy = match.getIntXY();
				extr_titles[indx] = ixy[0]+"/"+ ixy[1]+":"+String.format("%7.5f",	match.getMatchValue(gop));
				switch (mode) {
				case 0: extr_data[indx] = nodc ? match.extracted_nodc[scene_num] : match.extracted_objects[scene_num]; break;
				case 1: extr_data[indx] = match.extracted_masked[scene_num]; break;
				case 2: extr_data[indx] = match.extr_corr[scene_num][0]; break;
				case 3: extr_data[indx] = match.extr_corr_half[scene_num]; break;
				}
				indx++;
			}
		}
		ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
				extr_data,
				extr_size,
				extr_size,
				title, // +"-objects_"+scene_num,				
				extr_titles); // test_titles,
		if (imp == null) {
			return null;
		}
		if (show_centers) {
			imp.setRoi(roi); // null
		}
		if (show) {
			imp.show();
		}
		if (save && (save_dir != null)) {
			if (!save_dir.endsWith(Prefs.getFileSeparator())) {
				save_dir+=Prefs.getFileSeparator();
			}
			String save_path = save_dir+title;
			FileSaver imp_fs = new FileSaver(imp);
			imp_fs.saveAsTiff(save_path);
			if (debugLevel > -4) {
				System.out.println("Saved "+save_path);	
			}
		}
		return imp;
	}
	
	
	
}
+2 −1
Original line number Diff line number Diff line
@@ -13,7 +13,8 @@ public class ItemPatternMatch {
	public void setMatches(double [] matches) {
		sub_matches = matches;
	}
	public void setMatch(int indx, double match_value) {
	
	public void setMatch(int indx, double match_value) { // not used
		if (sub_matches == null) {
			sub_matches = new double [indx+1];
			Arrays.fill(sub_matches, Double.NaN);
Loading