Commit 6b986720 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Automatic matching of multiple scene sets

parent ba9466e1
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import ij.IJ;
import ij.Prefs;
import ij.io.OpenDialog;


@@ -187,6 +188,13 @@ public class CalibrationFileManagement {
	  }
	  
	  public static void saveStringToFile (String path,String data, boolean append){
		  int dir_sep = path.lastIndexOf(Prefs.getFileSeparator());
		  if (dir_sep >=0) { // create directory if it does not exist
			  File dir = new File(path.substring(0, dir_sep));
			  if (!dir.exists()) {
				  dir.mkdirs();
			  }
		  }
		  BufferedWriter writer = null;
		  try  {
			  writer = new BufferedWriter( new FileWriter( path, append));
+140 −48
Original line number Diff line number Diff line
@@ -3,13 +3,18 @@ package com.elphel.imagej.orthomosaic;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import com.elphel.imagej.calibration.CalibrationFileManagement;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters;
import com.elphel.imagej.cameras.EyesisCorrectionParameters;
@@ -28,6 +33,7 @@ import com.elphel.imagej.tileprocessor.TDCorrTile;
import Jama.Matrix;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.WindowManager;
import ij.gui.PointRoi;
import ij.process.FloatPolygon;
@@ -166,12 +172,16 @@ public class ComboMatch {
		boolean bounds_to_indices =   true;
		int     temp_mode =           1;
		boolean restore_temp =        true;
		double  frac_remove  =        0.15;
		double  metric_error =        0.05; // 0.02;//  2 cm
		double  frac_remove  =        clt_parameters.imp.pmtch_frac_remove; //   0.15;
		double  metric_error =        clt_parameters.imp.pmtch_metric_err; // 0.05; // 0.02;//  2 cm
		boolean update_lla =          false; // re-read file metadata
		boolean update_kernel_patterns = false;
		boolean update_bl_bc =        false;
		String [] suffixes_bl_bc=     {"","-BL","-BC"};
		boolean log_append =           clt_parameters.imp.pwise_log_append;
		String log_path =              clt_parameters.imp.pwise_log_path;
		
		
		int  suffix_bc_bl_indx =   2;
		if (!use_marked_image) {
			process_correlation=false; // use already adjusted by default
@@ -182,7 +192,7 @@ public class ComboMatch {
		}
		
		
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Set image pair",1200,600);
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Set image pair",1200,700);
		gd.addChoice      ("Files list/data path (w/o extension):", files_lists_paths, files_lists_paths[default_list_choice]);
		gd.addCheckbox    ("Use saved maps collection", use_saved_collection, "If false - use files list.");
		gd.addCheckbox    ("Save maps collection", save_collection, "Save maps collection to be able to restore.");
@@ -235,6 +245,8 @@ public class ComboMatch {
				suffixes_bl_bc,
				suffixes_bl_bc[suffix_bc_bl_indx],
				"Select interpolation mode of the source files: old bilinear (empty), bilinear (-BL), or bicubic (-BC)", 0);
	    gd.addCheckbox    ("Write log file",         log_append, "Enable writing log file with matching results.");
	    gd.addStringField ("Log file full path",     log_path, 150, "Path of the log file to be appended.");	

		
		
@@ -282,6 +294,8 @@ public class ComboMatch {
		update_kernel_patterns=     gd.getNextBoolean();
		update_bl_bc=               gd.getNextBoolean();
		suffix_bc_bl_indx =         gd.getNextChoiceIndex();
		log_append =                gd.getNextBoolean();
		log_path =                  gd.getNextString();
		OrthoMapsCollection maps_collection=null;
		if (use_saved_collection) {
			try {
@@ -656,37 +670,6 @@ public class ComboMatch {
					output_patt_titles); // test_titles,
			imp_inv_patt.show();
			
// select kernel and correlatde with every cut image?			
			
			
			// Test invert patterns
			/*
			
			boolean test_invert = debugLevel > -1000;
			if (test_invert) {
				double invert_fz = 0;
				double [][] inverted_patterns = new double [output_patterns.length][];
				for (int i = 0; i < output_patterns.length; i++) {
					inverted_patterns[i] = output_patterns[i].clone();
					double [] dfr = new double [corr_size*corr_size];
					dfr[corr_size/2*(corr_size+1)] = corr_size*corr_size;
					double [][] data_pair = new double[][] {inverted_patterns[i],dfr};
					inverted_patterns[i]=OrthoMap.deconvolvePair(
							data_pair,
							invert_fz,
							1);


				}
				ImagePlus imp_inv_patt = ShowDoubleFloatArrays.makeArrays(
						inverted_patterns,
						corr_size,
						corr_size,
						OrthoMap.removeKnownExtension(imp_sel.getTitle())+"-INV_PATTERN"+settings_str+"_"+corr_size+"x"+corr_size+".tiff",				
						output_patt_titles); // test_titles,
				imp_inv_patt.show();
			}
			*/
			ImagePlus imp_out_patt = ShowDoubleFloatArrays.makeArrays(
					output_patterns,
					corr_size,
@@ -765,8 +748,30 @@ public class ComboMatch {
			maps_collection.processComboMap(debugLevel);
			return true;
		}
		
		// for all modes - needed for create_overlaps || process_correlation || render_match || pattern_match
    	if (GPU_QUAD_AFFINE == null) {
        	System.out.println("Setting up GPU");
    		try {
    			GPU_QUAD_AFFINE = new GpuQuad(//
    					GPU_TILE_PROCESSOR,   // GPUTileProcessor gpuTileProcessor,
    					gpu_max_width,        // final int        max_width,
    					gpu_max_height,       // final int        max_height,
    					1,                    // final int        num_colors, // normally 1?
    					clt_parameters.gpu_debug_level);
    		} catch (Exception e) {
    			System.out.println("Failed to initialize GpuQuad class");
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			return false;
    		} // final int debugLevel);
    	}

		
		if (create_overlaps) {
			boolean ok =maps_collection.getIntersectedPairs(debugLevel);
			boolean ok =maps_collection.getIntersectedPairs(
					clt_parameters, // CLTParameters    clt_parameters,
					orthoMapsCollection_path); // String orthoMapsCollection_path);
			if (!ok) return false;
		}
        if (process_correlation || render_match || pattern_match) {
@@ -780,6 +785,17 @@ public class ComboMatch {
        						maps_collection.getIndex(other_name)));
        			}
        		}
        		// sort pairs_list by x then y
        		Collections.sort(pairs_list, new Comparator<Point>() {
        			@Override
        			public int compare(Point lhs, Point rhs) {
        				return (rhs.x > lhs.x) ? -1 : (rhs.x < lhs.x) ? 1 :
        					((rhs.y > lhs.y) ? -1 : (rhs.y < lhs.y) ? 1 : 0); // increasing
        			}
        		});
        		
        		
        		
        		int [][] available_pairs = new int [pairs_list.size()][2];
        		for (int i = 0; i < available_pairs.length; i++) {
        			available_pairs[i][0] = pairs_list.get(i).x;
@@ -803,7 +819,7 @@ public class ComboMatch {
				if (pair >= choices.length) {
					int default_choice = 0;
					int num_scene_lines = 50;
					if (process_correlation) { // select a second image to match
					if (process_correlation || render_match) { // select a second image to match
						// select a second image and set gpu_spair
						int default_choice1 = 0;
						gpu_spair = maps_collection.selectTwoScenes(
@@ -843,9 +859,9 @@ public class ComboMatch {
        	double agl_ratio = max_agl/50.0;
        	double metric_error_adj = metric_error * agl_ratio * agl_ratio; // metric_error settings is good for 50m. Increase for higher Maybe squared?
        	int initial_zoom = max_zoom_lev - 4;  // another algorithm?

        	System.out.println("Setting up GPU");
/*
        	if (GPU_QUAD_AFFINE == null) {
            	System.out.println("Setting up GPU");
        		try {
        			GPU_QUAD_AFFINE = new GpuQuad(//
        					GPU_TILE_PROCESSOR,   // GPUTileProcessor gpuTileProcessor,
@@ -860,6 +876,7 @@ public class ComboMatch {
        			return false;
        		} // final int debugLevel);
        	}
*/        	
    		double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same
    		double [][] affine1 = null;

@@ -901,7 +918,7 @@ public class ComboMatch {
        			affine1 = pairwiseOrthoMatch.getAffine();
        			double [][][] affines = {affine0,affine1};
        			int [] zooms = {initial_zoom, min_zoom_lev, 1000,1000}; // make automatic
        			double scale = 2.0; // scale vectors when warping;
//        			double scale = 2.0; // scale vectors when warping;
        			//				int num_tries  = 5; // make configurable
        			if (!process_correlation || !use_marked_image) { // skip low-res
        				zooms = new int[] {min_zoom_lev, 1000};
@@ -912,12 +929,17 @@ public class ComboMatch {
        			}
 //       			debugLevel = 0;
        			boolean  batch_mode = true; // false; //  true;
        			boolean ignore_prev_rms = true;
        			
        			boolean ignore_prev_rms = clt_parameters.imp.pmtch_ignore_rms; // true;
        			Rectangle woi = new Rectangle(); // used to return actual woi from correlateOrthoPair()
        			double [][] ground_planes = null;
					double           max_std = 1.5;      // maximal standard deviation to limit center area  
					double           min_std_rad = 2.0;  // minimal radius of the central area (if less - fail)

					double      max_std =             clt_parameters.imp.pmtch_max_std;     // 1.5;      // maximal standard deviation to limit center area  
					double      min_std_rad =         clt_parameters.imp.pmtch_min_std_rad; // 2.0;  // minimal radius of the central area (if less - fail)
					double      rad_fraction =        clt_parameters.imp.pmtch_cent_rad;    // center circle radius fraction of 0.5* min(width, height) in tiles
					double      max_tile_rad =        clt_parameters.imp.pmtch_max_cent_rad;// maximal center radius in tiles (limit pmtch_cent_rad)
					double      fill_fraction =       clt_parameters.imp.pmtch_cent_fill;   // should be populated not less than this
					double      fill_fraction_final = clt_parameters.imp.pmtch_cent_final;  // should be populated not less than this during final pass
					double      ease_nosfm =          clt_parameters.imp.pmtch_ease_nosfm;  // ease metric_error when no SfM gain == 0;
        			for (int zi = 0; zi < zooms.length; zi++) {
        				zoom_lev = zooms[zi];
        				if (zoom_lev >=1000) {
@@ -947,6 +969,12 @@ public class ComboMatch {
        						zoom_lev,        // int              zoom_lev,
        						show_vf,         // boolean show_vf,
        						ground_planes,   // double [][]      ground_planes, // null or double[2] - will return ground planes
        						rad_fraction,    // double           rad_fraction,
        						max_tile_rad,    // double           max_tile_rad, //  = 30;
        						fill_fraction,   // double           fill_fraction,
        						fill_fraction_final, // double           fill_fraction_final,
        						ease_nosfm,      // double           ease_nosfm,
        						null,            // double []        max_rms_iter, //  = {1.0, 0.6};//        						
        						debugLevel);     // final int        debugLevel)
        				if ((warp == null) || ((pmatch != null) &&  Double.isNaN(pmatch.rms))) {
        					System.out.println("Failed correlateOrthoPair()");
@@ -978,6 +1006,16 @@ public class ComboMatch {
        						}
        						System.out.println();
        					}
        					if (log_append && (log_path != null)) { // assuming directory exists
        						StringBuffer sb = new StringBuffer();
        						sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
        						sb.append(String.format("%d\t%d", gpu_pair[0], gpu_pair[1]));
        						sb.append(String.format("\t%6.4f\t%d\n", pairwiseOrthoMatch.rms, pairwiseOrthoMatch.zoom_lev));
        						CalibrationFileManagement.saveStringToFile (
        								log_path,          //String path,
        								sb.toString(), // data,
        								true); // boolean append)
        					}
        				}

        				if (pattern_match) {
@@ -1053,8 +1091,19 @@ public class ComboMatch {
		int    min_overlap =           clt_parameters.imp.ospir_overlap;  // 3000; // do not try to match if there is too small overlap (scaled pixels)
		int    num_iter_lma =          clt_parameters.imp.ospir_num_iter; // 5;
		boolean ignore_rms =           clt_parameters.imp.ospir_ignore_rms; // false
		int    spiral_debug =          clt_parameters.imp.ospir_debug;    // -3;
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Setup SpiralMatch",1200,300);
		int    spiral_debug =          clt_parameters.imp.ospir_debug;    // 0;
		boolean log_append =           clt_parameters.imp.pwise_log_append;
		String log_path =              clt_parameters.imp.pwise_log_path;
		
		double      max_std =             clt_parameters.imp.pmtch_max_std;    // 1.5;      // maximal standard deviation to limit center area  
		double      min_std_rad =         clt_parameters.imp.pmtch_min_std_rad;// 2.0;  // minimal radius of the central area (if less - fail)
		double      rad_fraction =        clt_parameters.imp.pmtch_cent_rad; // center circle radius fraction of 0.5* min(width, height) in tiles
		double      max_tile_rad =        clt_parameters.imp.pmtch_max_cent_rad;// maximal center radius in tiles (limit pmtch_cent_rad)
		double      fill_fraction =       clt_parameters.imp.pmtch_cent_fill; // should be populated not less than this
		double      fill_fraction_final = clt_parameters.imp.pmtch_cent_final; // should be populated not less than this during final pass
		double      ease_nosfm =          clt_parameters.imp.pmtch_ease_nosfm; // ease metric_error when no SfM gain == 0;
		
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Setup Spiral Match",1200,350);
		if (pairwiseOrthoMatch != null) {
			gd.addCheckbox    ("Use existing image pair",  use_existing_pair, "Use existing affine settings for this pair, do not use spiral search.");
		} else {
@@ -1072,8 +1121,20 @@ public class ComboMatch {
		gd.addNumericField("Minimal overlap",        min_overlap,  0,4,"scaled pix ^ 2","Minimal overlap area in square scaled pixels.");
		gd.addNumericField("LMA iterations",         num_iter_lma, 0,2,"",              "Number of LMA iterations.");
		gd.addCheckbox    ("Ignore worsening RMSE",  ignore_rms, "Ignore worsening/not improving RMSE during spiral search.");
	    gd.addCheckbox    ("Write log file",         log_append, "Enable writing log file with matching results.");
	    gd.addStringField ("Log file full path",     log_path, 150, "Path of the log file to be appended.");	
		gd.addNumericField("Spiral search debug level",spiral_debug, 0,3,"","Debug level during Spiral search.");
		
		gd.addMessage("Parameters, common to all matching, not only spiral");
		gd.addNumericField("Central area standard deviation",  max_std,  3,7,"",	"Central area limit by the standard deviation.");
		gd.addNumericField("Central area minimal radius",      min_std_rad,  3,7,"tile",	"Minimal radius of the central area after all LMA passes.");
		gd.addNumericField("Central area radius as fraction",  rad_fraction,   3,7,"",	"Central area radius as fraction of half minimal WOI dimension.");
		gd.addNumericField("Maximal central area radius",      max_tile_rad,   3,7,"tiles",	"Absolute limit to the center area radius (eases bad peripheral matching).");
		gd.addNumericField("Central area minimal fill",        fill_fraction,  3,7,"",	"Central area minimal fill for all but the last iteration.");
		gd.addNumericField("Central area minimal fill final",  fill_fraction_final, 3,7,"",	"Central area minimal fill for the last iteration.");
		gd.addNumericField("Relax metric error for no-SfM",    ease_nosfm, 3,7,"",	"Relax metric error for no-SfM scenes (sfm_gain==0).");
		
		
		gd.showDialog();
		if (gd.wasCanceled()) return null;
		if (pairwiseOrthoMatch != null) {
@@ -1089,7 +1150,18 @@ public class ComboMatch {
		min_overlap =        (int) gd.getNextNumber();
		num_iter_lma =       (int) gd.getNextNumber();
		ignore_rms =               gd.getNextBoolean();
		log_append =               gd.getNextBoolean();
		log_path =                 gd.getNextString();
		spiral_debug =       (int) gd.getNextNumber();
		search_step=               gd.getNextNumber();
		max_std=                   gd.getNextNumber();
		min_std_rad=               gd.getNextNumber();
		rad_fraction=              gd.getNextNumber();
		max_tile_rad   =           gd.getNextNumber();
		fill_fraction=             gd.getNextNumber();
		fill_fraction_final=       gd.getNextNumber();
		ease_nosfm=                gd.getNextNumber();
		
		if (use_existing_pair) {
			if (invert_exixting_pair) {
				System.out.println("Both direct and inverted matches are selected, using direct match");
@@ -1104,11 +1176,17 @@ public class ComboMatch {
		double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same
		double [][] affine1 = {{1,0,0},{0,1,0}}; // here (manual mode) start from the center, may use prediction in auto
		double [][][] affines = new double[][][] {affine0,affine1};

		pairwiseOrthoMatch = maps_collection.SpiralMatch (
				clt_parameters,  // CLTParameters    clt_parameters,
				frac_remove,     // double           frac_remove, //  =        0.25
				metric_error,    // double           metric_error,
				max_std,         // double           max_std,     // maximal standard deviation to limit center area  
				min_std_rad,     // double           min_std_rad, // minimal radius of the central area (if less - fail)
				rad_fraction,    // double           rad_fraction,
				max_tile_rad,    //double           max_tile_rad, //  = 30;			
				fill_fraction,   // double           fill_fraction,
				fill_fraction_final, // double           fill_fraction_final,
				ease_nosfm,      // double           ease_nosfm,
				gpu_pair,        // int []           gpu_pair,
				affines,         // double [][][]    affines_init,  // here in meters, relative to vertical points
				initial_zoom,    // int              zoom_lev,
@@ -1119,12 +1197,26 @@ public class ComboMatch {
				num_iter_lma,    // int              num_tries, //  = 5
				min_overlap,     // int              min_overlap, // 3000
				ignore_rms,      // boolean          ignore_rms,
				null,//double []        max_rms_iter, //  = {1.0, 0.6};//
				spiral_debug);     // int              debugLevel){
		if (log_append && (log_path != null)) { // assuming directory exists
			StringBuffer sb = new StringBuffer();
			sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
			sb.append(String.format("%d\t%d", gpu_pair[0], gpu_pair[1]));
			if ((pairwiseOrthoMatch != null) && !Double.isNaN(pairwiseOrthoMatch.rms)) {
				sb.append(String.format("\t%d\t%d\t%6.4f\t%d\n",
						pairwiseOrthoMatch.nxy[0], pairwiseOrthoMatch.nxy[1], pairwiseOrthoMatch.rms, pairwiseOrthoMatch.zoom_lev));
			} else {
				sb.append("\tFAILED");
			}
			CalibrationFileManagement.saveStringToFile (
					log_path,          //String path,
					sb.toString(), // data,
					true); // boolean append)
		}
		return pairwiseOrthoMatch;
	}
	
	
	
	public static boolean updateBlBcFileNames(
			String suffix,
			String before,
+7 −0
Original line number Diff line number Diff line
@@ -191,6 +191,13 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
			PairwiseOrthoMatch match) {
		pairwise_matches.put(name, match);
	}

	public void unsetMatch(
			String name) {
		pairwise_matches.remove(name);
	}

	
	public PairwiseOrthoMatch getMatch(String name) {
		return pairwise_matches.get(name);
	}
+672 −100

File changed.

Preview size limit exceeded, changes collapsed.

+71 −8
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
package com.elphel.imagej.orthomosaic;

import java.awt.Rectangle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

import com.elphel.imagej.common.ShowDoubleFloatArrays;
@@ -105,6 +106,8 @@ public class OrthoPairLMA {
			int           min_good_tiles,
			double        max_std,      // maximal standard deviation to limit center area  
			double        min_std_rad,  // minimal radius of the central area (if less - fail)
			double        tile_rad,
			int           min_tiles_rad,
			final int     debug_level) {
		tile_centers = centers;
		this.width = width;
@@ -127,16 +130,17 @@ public class OrthoPairLMA {
		origin = new double[2];
		if (origin_center) {
			origin = new double [] {
					woi.x + 0.5 * woi.width  * GPUTileProcessor.DTT_SIZE,
					woi.y + 0.5 * woi.height * GPUTileProcessor.DTT_SIZE};
					(woi.x + 0.5 * woi.width)  * GPUTileProcessor.DTT_SIZE,
					(woi.y + 0.5 * woi.height) * GPUTileProcessor.DTT_SIZE};
		}
		N = woi.width * woi.height;
		parameters_vector = new double [] {1,0,0,1,0,0};
		if (min_std_rad > 0) {
			int         min_tiles = 4;
//			int         min_tiles = 4;
			getCenterRadius(
					max_std,       // final double      max_std,      // maximal standard deviation to limit center area
					min_tiles,     // final int         min_tiles,
					tile_rad,      // min_std_rad,   // final double      min_radius,
					min_tiles_rad, // min_tiles,     // final int         min_tiles,
					vector_XYS,    // final double [][] vector_XYS,
					weights_extra, // final double []   weights_extra, // null or additional weights (such as elevation-based)
					centers);      // final double [][] centers)
@@ -251,6 +255,11 @@ public class OrthoPairLMA {
	 * In that case try to adjust only the central area first, then increase that area
	 * in next iterations. 
	 * @param max_std       maximal standard deviation (average for X and Y) inside center area
	 * @param min_radius    minimal central zone radius that has to have >= min_tiles.
	 *                      Should be increased (with min_tiles) for high resolution images.
	 *                      Also there can be a bush right in the center - need to handle it too.
	 *                      Maybe for the final it should be a fraction of the minimal overlap
	 *                      dimension? 
	 * @param min_tiles     minimal tiles in the center zone
	 * @param vector_XYS    2D correlation-measured X,Y, and strength
	 * @param weights_extra null or optional additional weights of the samples
@@ -258,9 +267,10 @@ public class OrthoPairLMA {
	 * @return maximal radius from the center (in pixels) where standard deviation of the inside samples is
	 *         below max_std. Returns Double.POSITIVE_INFINITY if std is not reached
	 */
	private double getCenterRadius(
	public double getCenterRadius(
	        final double      max_std,      // maximal standard deviation to limit center area  
//	        final double      min_std_rad,  // minimal radius of the central area (if less - fail)
	        final double      min_radius,
	        final int         min_tiles,
			final double [][] vector_XYS,
			final double []   weights_extra, // null or additional weights (such as elevation-based)
@@ -276,7 +286,53 @@ public class OrthoPairLMA {
		final double [][] sy_arr =  new double [threads.length][rad_length];
		final double [][] sy2_arr = new double [threads.length][rad_length];
		final int    [][] sn_arr =  new int [threads.length][rad_length];
		
		boolean dbg = false;
		if (dbg) {
			String [] titles = {"fx","fy","vw","w","cent-x","cent-y","dx","dy","r_t","irt"};
			final double [][] dbg_img = new double [titles.length][woi.width*woi.height];
			for (int i = 0; i < dbg_img.length; i++) {
				Arrays.fill(dbg_img[i], Double.NaN);
			}
			for (int ithread = 0; ithread < threads.length; ithread++) {
				threads[ithread] = new Thread() {
					public void run() {
						for (int iTile = ai.getAndIncrement(); iTile < N; iTile = ai.getAndIncrement()) {
							int tileX = iTile % woi.width + woi.x;
							int tileY = iTile / woi.width + woi.y;
							int aTile = tileY * width + tileX;
							if ((vector_XYS[aTile] != null) && (centers[aTile] != null)) {
								double w = vector_XYS[aTile][2];
								if (weights_extra != null) w *= weights_extra[aTile]; 
								if (Double.isNaN(w)) w = 0;
								double dx = centers[aTile][0] - origin[0];
								double dy = centers[aTile][1] - origin[1];
								double r_t = Math.sqrt(dx*dx+dy*dy)/GPUTileProcessor.DTT_SIZE; // radius in tiles
								int irt = (int) Math.round(r_t);
								dbg_img[0][iTile] = vector_XYS[aTile][0];
								dbg_img[1][iTile] = vector_XYS[aTile][1];
								dbg_img[2][iTile] = vector_XYS[aTile][2];
								dbg_img[3][iTile] = w;
								dbg_img[4][iTile] = centers[aTile][0];
								dbg_img[5][iTile] = centers[aTile][1];
								dbg_img[6][iTile] = dx;
								dbg_img[7][iTile] = dy;
								dbg_img[8][iTile] = r_t;
								dbg_img[9][iTile] = irt;
							}
						}
					}
				};
			}		      
			ImageDtt.startAndJoin(threads);
			ai.set(0);
			ShowDoubleFloatArrays.showArrays(
					dbg_img,
					woi.width,
					woi.height,
					true,
					"getCenterRadius",
					titles);
		}
		for (int ithread = 0; ithread < threads.length; ithread++) {
			threads[ithread] = new Thread() {
				public void run() {
@@ -335,6 +391,7 @@ public class OrthoPairLMA {
		ImageDtt.startAndJoin(threads);
		double sc0=0, scx=0,scx2=0,scy=0,scy2=0,std_prev=0, std=0;
		int    scn=0;
		int    scnc = 0;
		center_radius = Double.POSITIVE_INFINITY; 
		for (int iRad=0; iRad < rad_length; iRad++) {
			sc0+= s0 [iRad];
@@ -343,7 +400,10 @@ public class OrthoPairLMA {
			scy+= sy [iRad];
			scy2+=sy2[iRad];
			scn+= sn [iRad];
			if ((scn > min_tiles) && (sc0 > 0)) {// for one tile gets scrt() of a small negative error
			if (iRad <= ((int) Math.round(min_radius))) {
				scnc = scn;
			}
			if ((scn > min_tiles) && (sc0 > 0)) {// for one tile gets sqcrt() of a small negative error
				std = Math.sqrt((scx2*sc0 - scx*scx + scy2*sc0 - scy*scy)/2)/sc0;
			}
			if ((scn >= min_tiles) && (std >= max_std)) {
@@ -356,6 +416,9 @@ public class OrthoPairLMA {
			}
			std_prev = std;
		}
		if ((min_tiles > 0) && (min_radius > 0) && (scnc < min_tiles)) {
			center_radius = 0;
		}
		return center_radius;
	}
	
Loading