Commit 3cb7b435 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging illustrations

parent 7c9b8ed9
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -667,7 +667,9 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
	public static Goniometer GONIOMETER=null;
	public static LwirReaderParameters   LWIR_PARAMETERS =   new LwirReaderParameters();
	public static CalibrationIllustrationParameters CALIBRATION_ILLUSTRATION_PARAMETERS = new CalibrationIllustrationParameters(LWIR_PARAMETERS);
	public static CalibrationIllustrationParameters CALIBRATION_ILLUSTRATION_PARAMETERS = new CalibrationIllustrationParameters(
			LWIR_PARAMETERS,
			EYESIS_CAMERA_PARAMETERS);
//	new CalibrationHardwareInterface.LaserPointers();
	public class SyncCommand{
	    public boolean isRunning=      false;
@@ -1069,6 +1071,7 @@ if (MORE_BUTTONS) {
		panelIllustrations.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
		addButton("Illustrations Configure",    panelIllustrations,color_configure);
		addButton("Illustrations",              panelIllustrations,color_bundle);
		addButton("Remove Bad grids",           panelIllustrations,color_stop);
		add(panelIllustrations);
		
		
@@ -9434,20 +9437,27 @@ if (MORE_BUTTONS) {
					LENS_DISTORTIONS,            // Distortions       distortions,
					SYNC_COMMAND.stopRequested,  // 	AtomicInteger                  stopRequested,
					MASTER_DEBUG_LEVEL);         // 		int                            debug_level);
			/*
		}
		CALIBRATION_ILLUSTRATION.convertSourceFiles();
		return;
	}
/* ======================================================================== */
	if       (label.equals("Remove Bad grids")) {
		if (LENS_DISTORTIONS==null) {
			IJ.showMessage("LENS_DISTORTION is not set"); // to use all grids imported
			return;
		}
		EYESIS_ABERRATIONS.setDistortions(LENS_DISTORTIONS);
		if (CALIBRATION_ILLUSTRATION == null) {
			CALIBRATION_ILLUSTRATION = new CalibrationIllustration(
				LWIR_PARAMETERS, // LwirReaderParameters           lwirReaderParameters,
				LENS_DISTORTION_PARAMETERS, // LensDistortionParameters       lensDistortionParameters,
				PATTERN_PARAMETERS, // PatternParameters              patternParameters,
				REFINE_PARAMETERS, // 		RefineParameters               refineParameters,
				DISTORTION_PROCESS_CONFIGURATION, // DistortionProcessConfiguration distortionProcessConfiguration,
				EYESIS_CAMERA_PARAMETERS, // EyesisCameraParameters         eyesisCameraParameters,
					CALIBRATION_ILLUSTRATION_PARAMETERS, // CalibrationIllustrationParameters illustrationParameters,			
					EYESIS_ABERRATIONS,          // EyesisAberrations eyesisAberrations,
					LENS_DISTORTIONS,            // Distortions       distortions,
					SYNC_COMMAND.stopRequested,  // 	AtomicInteger                  stopRequested,
					MASTER_DEBUG_LEVEL);         // 		int                            debug_level);
				*/
		}
//		CALIBRATION_ILLUSTRATION.selectUsefulGrids();
		CALIBRATION_ILLUSTRATION.convertSourceFiles();
		CALIBRATION_ILLUSTRATION.removeBadGrids();
		return;
	}
	
+328 −151
Original line number Diff line number Diff line
package com.elphel.imagej.calibration;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Rectangle;
import java.io.File;
@@ -20,6 +21,9 @@ import ij.gui.Line;
import ij.process.ImageProcessor;

public class CalibrationIllustration {
	public static final int MAX_THREADS = 100; // combine from all classes?
	public static final int CONTRAST_INDEX = 2;

	EyesisAberrations              eyesisAberrations;
	Distortions                    distortions;
	CalibrationIllustrationParameters illustrationParameters;	
@@ -49,18 +53,23 @@ public class CalibrationIllustration {

	public void plotGrid(
			int       numImg,
			int       line_width,
			ImagePlus imp,
			Color     color_grid,
			Color color_grid_extra // at least one end points to extra (unreliable) nodes (may be null)
			Color     color_grid_weak,
			Color     color_grid_extra, // at least one end points to extra (unreliable) nodes (may be null)
			double    weak_threshold
			) {
		int line_width =  1; //https://imagej.nih.gov/ij/developer/api/ij/ij/gui/Line.html#drawPixels(ij.process.ImageProcessor)
//		int line_width =  3; //https://imagej.nih.gov/ij/developer/api/ij/ij/gui/Line.html#drawPixels(ij.process.ImageProcessor)
		DistortionCalibrationData dcd = distortions.fittingStrategy.distortionCalibrationData;
		GridImageParameters gip = dcd.gIP[numImg];
		int [][] pUV =          gip.pixelsUV;
		int [][] pUV_extra =    gip.pixelsUV_extra;
		double [][] pXY =       gip.pixelsXY;
		double [][] pXY_extra = gip.pixelsXY_extra;
		
		if ((pUV == null) || (pUV.length==0)) {
			return;
		}
		int minU=pUV[0][0],maxU=minU,minV=pUV[0][1],maxV=minV;
		for (int i = 0; i < pUV.length; i++) {
			if      (pUV[i][0] < minU) minU = pUV[i][0];
@@ -93,6 +102,17 @@ public class CalibrationIllustration {
		}
		ImageProcessor ip = imp.getProcessor();
		ip.setLineWidth(line_width);
//		only use stroke for line_width>1
		/*
		BasicStroke stroke = null;
		if (line_width>1) {
			stroke = new BasicStroke(line_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
		}
		*/
//		BasicStroke stroke = new BasicStroke(line_width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
//		BasicStroke stroke = new BasicStroke(line_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
//		roi.setStrokeColor(new Color(red, green, blue, alpha));
//		roi.setStroke(stroke);		
//		int upper = dimsUV.width * (dimsUV.height-1);
		int upper = dimsUV.width * dimsUV.height;
		for (int indx = dimsUV.width + 1; indx < upper; indx++) if (grid[indx] >= 0){
@@ -103,40 +123,92 @@ public class CalibrationIllustration {
				if (indx1 < grid.length) {
					int g1 = grid[indx1];
					if (g1 >= 0) {
						double [] pXY0 =  (g0 < main_len) ? pXY[g0] : pXY_extra[g0 - main_len];
						double [] pXY1 =  (g1 < main_len) ? pXY[g1] : pXY_extra[g1 - main_len];
//						Line line = new Line(pXY0[0], pXY0[1], pXY1[0],pXY1[1]);
						if ((g0 < main_len) && (g1 < main_len)) {
							if ((pXY0[CONTRAST_INDEX] >= weak_threshold) && (pXY1[CONTRAST_INDEX] >= weak_threshold)) {
								if (color_grid == null) {
									continue;
								}
								ip.setColor(color_grid);
							} else {
								if (color_grid_weak == null) {
									continue;
								}
								ip.setColor(color_grid_weak);
							}
						} else {
							if (color_grid_extra == null) {
								continue;
							}
							ip.setColor(color_grid_extra); // should not get here with color_grid_extra==null
						}
						double [] pXY0 =  (g0 < main_len) ? pXY[g0] : pXY_extra[g0 - main_len];
						double [] pXY1 =  (g1 < main_len) ? pXY[g1] : pXY_extra[g1 - main_len];
						Line line = new Line(pXY0[0], pXY0[1], pXY1[0],pXY1[1]);
						/*
						if (stroke != null) {
							if ((g0 < main_len) && (g1 < main_len)) {
								line.setStrokeColor(color_grid);
							} else {
								line.setStrokeColor(color_grid_extra); // should not get here with color_grid_extra==null
							}
							line.setStroke(stroke);
						}
						line.setStrokeWidth(1.0);
						*/
						for (int dy = -line_width+1; dy < line_width; dy+=2) {
							for (int dx = -line_width+1; dx < line_width; dx+=2) {
								Line line = new Line(pXY0[0] + 0.5*dx, pXY0[1] + 0.5*dy, pXY1[0] + 0.5*dx,pXY1[1] + 0.5*dy);
								line.drawPixels(ip);
							}
						}
//						Line line = new Line(pXY0[0], pXY0[1], pXY1[0],pXY1[1]);
//						line.drawPixels(ip);
						/*
						for (double lw = 0.5; lw <= line_width; lw+=0.5) {
							line.setStrokeWidth(lw);
							line.drawPixels(ip);
						}
						*/
					}
				}
			}
		}
	}
	
	public boolean convertSourceFiles() {
		double threshold_contrast = 10.0;
		int    threshold_number =   10; // grid should have this number of nodes with above-threshold contrast
		int    CONTRAST_INDEX = 2;
		//this.eyesisCameraParameters.numStations
		boolean [] selectedChannels = eyesisAberrations.aberrationParameters.getChannelSelection(distortions);
		DistortionCalibrationData dcd = distortions.fittingStrategy.distortionCalibrationData;
		int numStations = dcd.eyesisCameraParameters.getNumStations();
		boolean [] station_sel = new  boolean[numStations];
//		Arrays.fill(station_sel,  true);
		station_sel[0]= true; // only 06-L
		MultipleExtensionsFileFilter sourceFilter =
		long startTime=System.nanoTime(); // restart timer after possible interactive dialogs
		final boolean [] selectedChannels = eyesisAberrations.aberrationParameters.getChannelSelection(distortions);
		final DistortionCalibrationData dcd = distortions.fittingStrategy.distortionCalibrationData;
		final MultipleExtensionsFileFilter sourceFilter =
				new MultipleExtensionsFileFilter("",src_extensions,"Source calibration images");
		int lwir0 = illustrationParameters.getLwirReaderParameters().getLwirChn0();
		int eo0 =   illustrationParameters.getLwirReaderParameters().getEoChn0();
		for (int nChn = 0; nChn < selectedChannels.length; nChn++) if (selectedChannels[nChn]) {
		final int lwir0 = illustrationParameters.getLwirReaderParameters().getLwirChn0();
		final int eo0 =   illustrationParameters.getLwirReaderParameters().getEoChn0();
   		final Thread[] threads = newThreadArray(MAX_THREADS);
   		final AtomicInteger indxAtomic = new AtomicInteger(0);
		for (int iChn = 0; iChn < selectedChannels.length; iChn++) if (selectedChannels[iChn]) {
			final int nChn=iChn;
			indxAtomic.set(0);
			// Create directory before threads
			String illustrations_dir = eyesisAberrations.aberrationParameters.illustrationsDirectory;
			String chn_ill_dir = illustrations_dir+Prefs.getFileSeparator()+ illustrationParameters.getChannelPrefix()+String.format("%02d", nChn);
			// create directory if it does not exist
			File destDir= new File (chn_ill_dir);
			if (!destDir.exists()){
				if (!destDir.mkdirs()) {
					IJ.showMessage("Error","Failed to create results directory "+chn_ill_dir);
					continue;
				}
			}
			
			for (int ithread = 0; ithread < threads.length; ithread++) {
				threads[ithread] = new Thread() {
					@Override
					public void run() {
						//   					for (int nChn = indxAtomic.getAndIncrement(); nChn < selectedChannels.length; nChn = indxAtomic.getAndIncrement()) if (selectedChannels[nChn]) {
						// iterate through all image set (some grids may be missing)
			for (int nSet = 0; nSet < dcd.gIS.length; nSet++) {
				if (station_sel[dcd.gIS[nSet].getStationNumber()]) { // some stations only
						for (int nSet = indxAtomic.getAndIncrement(); nSet < dcd.gIS.length; nSet = indxAtomic.getAndIncrement()) {
							int station = dcd.gIS[nSet].getStationNumber();
							if (illustrationParameters.useStation(station)) { // some stations only
								// construct source file name
								String srcPath = null;
								int numImg = -1;
@@ -177,18 +249,28 @@ public class CalibrationIllustration {
									title = title.substring(0, title.lastIndexOf("."));
								}
								String title_annot = title+"-annot";
								if (illustrationParameters.useStationInFilenames()) {
									title_annot = "station-"+station+"_"+title_annot;
								}
								if (numImg >=0) { // check if it is a bad image
									int num_above = 0; 
									GridImageParameters gip = dcd.gIP[numImg];
									double [][] pXY =       gip.pixelsXY;
									for (int i = 0; i < pXY.length; i++ ) {
							if (pXY[i][CONTRAST_INDEX] > threshold_contrast) num_above++;
						}
						if (num_above < threshold_number) {
							title_annot = title+"-annot"+"-BAD";
										if (pXY[i][CONTRAST_INDEX] > illustrationParameters.getThresholdContrast()) num_above++;
									}
									if (num_above < illustrationParameters.getThresholdNumber()) {
										title_annot += "-BAD";
									}
					double [][]  pseudo_pixels = new double [4] [pixels.length];
								} else {
									title_annot += "-EMPTY";
								}
								int sensor_type = dcd.eyesisCameraParameters.getSensorType(nChn);
								ImageStack stack = null;
								double [][]  pseudo_pixels;
								int line_width = 1;
								if (sensor_type == 1) {
									pseudo_pixels = new double [4] [pixels.length];
									ThermalColor tc = new ThermalColor(
											illustrationParameters.getPalette(), // 	public int     lwir_palette =           0; // 0 - white - hot, 1 - black - hot, 2+ - colored
											illustrationParameters.getLwirRange(nChn- lwir0)[0],
@@ -201,8 +283,27 @@ public class CalibrationIllustration {
										pseudo_pixels[2][i] = rgb[2]; // blue
										pseudo_pixels[3][i] = 1.0; // alpha
									}
									line_width = illustrationParameters.getLineWidthLwir();
								} else { // eo
									double [][] drgb = MatchSimulatedPattern.simpleDemosaic(
											imp,
											illustrationParameters.eo_rb2g_hi[nChn-eo0][0], // r2g,
											illustrationParameters.eo_rb2g_hi[nChn-eo0][1], // b2g,
											illustrationParameters.getSaturation(),         // saturation,
											illustrationParameters.getGamma(),              // gamma,
											illustrationParameters.getMinLin(),             //minlin_gamma, // do not apply gamma to lower values
											illustrationParameters.eo_rb2g_hi[nChn-eo0][2]); // ,rgb_hi);        // map to 255, gamma will preserve
									pseudo_pixels = new double [4][];
									for (int i = 0; i < drgb.length; i++) {
										pseudo_pixels[i] = drgb[i];
									}
									pseudo_pixels[3] = new double [pseudo_pixels[0].length];
									Arrays.fill(pseudo_pixels[3], 1.0);
									line_width = illustrationParameters.getLineWidthEo();
								}

								String [] rgb_titles =  {"red","green","blue","alpha"};
					ImageStack stack = (new  ShowDoubleFloatArrays()).makeStack(
								stack = (new  ShowDoubleFloatArrays()).makeStack(
										pseudo_pixels, // iclt_data,
										width,         // (tilesX + 0) * clt_parameters.transform_size,
										height,        // (tilesY + 0) * clt_parameters.transform_size,
@@ -222,21 +323,22 @@ public class CalibrationIllustration {
										1.0);  // double alpha_max)
								if (numImg >=0) {
									plotGrid(numImg,
											line_width,
											imp_annot,
								new Color(250, 0,  0), //  color_grid,
								new Color(200, 200,0) // null // //at least one end points to extra (unreliable) nodes
											illustrationParameters.getGridColor(), // new Color(250, 0,  0), //  color_grid,
											illustrationParameters.getGridWeakColor(), // new Color(250, 0,  0), //  color_grid,
											illustrationParameters.getGridExtraColor(), // new Color(200, 200,0) // null // //at least one end points to extra (unreliable) nodes
											illustrationParameters.getThresholdContrast()
											);
								}

//					imp_pseudo.getProcessor().resetMinAndMax();
//					imp_pseudo.show();
								String illustrations_dir = eyesisAberrations.aberrationParameters.illustrationsDirectory;
					String chn_ill_dir = illustrations_dir+Prefs.getFileSeparator()+ illustrationParameters.channel_dir_prefix+String.format("%02d", nChn);
								String chn_ill_dir = illustrations_dir+Prefs.getFileSeparator()+ illustrationParameters.getChannelPrefix()+String.format("%02d", nChn);
								// create directory if it does not exist
								File destDir= new File (chn_ill_dir);
					if (!destDir.exists()){
								if (!destDir.exists()){ // Should be created before threads !
									if (!destDir.mkdirs()) {
							IJ.showMessage("Error","Failed to create results directory "+chn_ill_dir);
										IJ.showMessage("Error","Failed to create results directory "+chn_ill_dir+". *** It should be already created! ***");
										continue;
									}
								}
@@ -250,29 +352,104 @@ public class CalibrationIllustration {
							}
						}
					}
				};
			}
			startAndJoin(threads);
		}
		System.out.println("All done in "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" sec.");
		return true;
	}

/*	
	public CalibrationIllustration (
			LwirReaderParameters           lwirReaderParameters,
			LensDistortionParameters       lensDistortionParameters,
			PatternParameters              patternParameters,
			RefineParameters               refineParameters,
			DistortionProcessConfiguration distortionProcessConfiguration,
			EyesisCameraParameters         eyesisCameraParameters,
			AtomicInteger                  stopRequested,
			int                            debug_level) {
		this.lwirReaderParameters =           lwirReaderParameters;
		this.lensDistortionParameters =       lensDistortionParameters;
		this.patternParameters =              patternParameters;
		this.refineParameters =               refineParameters;
		this.distortionProcessConfiguration = distortionProcessConfiguration;
		this.eyesisCameraParameters =         eyesisCameraParameters;
		this.stopRequested =                  stopRequested;
		this.debug_level =                    debug_level;
	
	public boolean removeBadGrids() {
		long startTime=System.nanoTime(); // restart timer after possible interactive dialogs
		final boolean [] selectedChannels = eyesisAberrations.aberrationParameters.getChannelSelection(distortions);
		final DistortionCalibrationData dcd = distortions.fittingStrategy.distortionCalibrationData;
   		final Thread[] threads = newThreadArray(MAX_THREADS);
   		final AtomicInteger indxAtomic = new AtomicInteger(0);
   		final AtomicInteger numRemoved = new AtomicInteger(0);
		for (int iChn = 0; iChn < selectedChannels.length; iChn++) if (selectedChannels[iChn]) {
			final int nChn=iChn;
			indxAtomic.set(0);
			// Create directory before threads
			String illustrations_dir = eyesisAberrations.aberrationParameters.illustrationsDirectory;
			String chn_ill_dir = illustrations_dir+Prefs.getFileSeparator()+ illustrationParameters.getChannelPrefix()+String.format("%02d", nChn);
			// create directory if it does not exist
			File destDir= new File (chn_ill_dir);
			if (!destDir.exists()){
				if (!destDir.mkdirs()) {
					IJ.showMessage("Error","Failed to create results directory "+chn_ill_dir);
					continue;
				}
			}
			for (int ithread = 0; ithread < threads.length; ithread++) {
				threads[ithread] = new Thread() {
					@Override
					public void run() {
						//   					for (int nChn = indxAtomic.getAndIncrement(); nChn < selectedChannels.length; nChn = indxAtomic.getAndIncrement()) if (selectedChannels[nChn]) {
						// iterate through all image set (some grids may be missing)
						for (int nSet = indxAtomic.getAndIncrement(); nSet < dcd.gIS.length; nSet = indxAtomic.getAndIncrement()) {
							int station = dcd.gIS[nSet].getStationNumber();
							if (illustrationParameters.useStation(station)) { // some stations only
								// construct source file name
								if (dcd.gIS[nSet].imageSet[nChn] != null) {
									int numImg = dcd.gIS[nSet].imageSet[nChn].getImageNumber();
									int num_above = 0; 
									GridImageParameters gip = dcd.gIP[numImg];
									double [][] pXY =       gip.pixelsXY;
									for (int i = 0; i < pXY.length; i++ ) {
										if (pXY[i][CONTRAST_INDEX] > illustrationParameters.getThresholdContrast()) num_above++;
									}
									if (num_above < illustrationParameters.getThresholdNumber()) {
										String grid_path = dcd.getImagePath(numImg);
										System.out.println("Removing bad grid file: "+grid_path);
										new File(dcd.getImagePath(numImg)).delete();
										numRemoved.getAndIncrement();
									}
								}
							}
						}
					}
				};
			}
			startAndJoin(threads);
		}
		System.out.println("Remoded "+(numRemoved.get())+" bad grid files in "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" sec.");
		return true;
	}

	
	
	
	/* Create a Thread[] array as large as the number of processors available.
	 * From Stephan Preibisch's Multithreading.java class. See:
	 * http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
	 */
	private static Thread[] newThreadArray(int maxCPUs) {
		int n_cpus = Runtime.getRuntime().availableProcessors();
		if (n_cpus>maxCPUs)n_cpus=maxCPUs;
		return new Thread[n_cpus];
	}
/* Start all given threads and wait on each of them until all are done.
	 * From Stephan Preibisch's Multithreading.java class. See:
	 * http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
	 */
	private static void startAndJoin(Thread[] threads)
	{
		for (int ithread = 0; ithread < threads.length; ++ithread)
		{
			threads[ithread].setPriority(Thread.NORM_PRIORITY);
			threads[ithread].start();
		}

		try
		{
			for (int ithread = 0; ithread < threads.length; ++ithread)
				threads[ithread].join();
		} catch (InterruptedException ie)
		{
			throw new RuntimeException(ie);
		}
	}
	
}
Loading