Commit 624f1144 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Orthographic videos generation

parent 8a9605a5
Loading
Loading
Loading
Loading
+9 −32
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ import com.elphel.imagej.ims.EventLogger;
import com.elphel.imagej.ims.Imx5;
import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.lwir.LwirReader;
import com.elphel.imagej.orthomosaic.ComboMap;
import com.elphel.imagej.orthomosaic.ComboMatch;
import com.elphel.imagej.readers.ChangeImageResolution;
import com.elphel.imagej.readers.DumpImageMetadata;
@@ -847,6 +848,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
			addButton("Warp pair",  panelLWIRWorld, color_process);
			addButton("Read Tiff",  panelLWIRWorld, color_process);
			addButton("Set pair GPS",  panelLWIRWorld, color_process);
			addButton("Test video",  panelLWIRWorld, color_process);
			plugInFrame.add(panelLWIRWorld);
			
		}
@@ -5705,21 +5707,6 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
		} else if (label.equals("Set pair GPS")) {
			DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
			EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
			/*
			boolean run_pre = true; // false;
			if (run_pre) {
				String path = loadProperties(null, CORRECTION_PARAMETERS.resultsDirectory, true, PROPERTIES);
				if (path != null) {
					getAllProperties(PROPERTIES);
					if (DEBUG_LEVEL > -3)
						System.out.println("Configuration parameters are restored from " + path);
				} else {
					if (DEBUG_LEVEL > -10)
						System.out.println("Failed to restore configuration parameters");
					return;
				}
			}
			*/
			if (GPU_TILE_PROCESSOR == null) {
				try {
					GPU_TILE_PROCESSOR = new GPUTileProcessor(CORRECTION_PARAMETERS.tile_processor_gpu);
@@ -5730,23 +5717,6 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
					return;
				} // final int debugLevel);
			}
			/*
			if (!run_pre) {
				String path = loadProperties(null, CORRECTION_PARAMETERS.resultsDirectory, true, PROPERTIES);
				if (path != null) {
					getAllProperties(PROPERTIES);
					if (DEBUG_LEVEL > -3)
						System.out.println("Configuration parameters are restored from " + path);
				} else {
					if (DEBUG_LEVEL > -10)
						System.out.println("Failed to restore configuration parameters");
					return;
				}
			}
			*/
			
//////////////////////
// Temporarily initialize on scene GPU
			
			boolean init_scene = false; // true;
			if (init_scene) {
@@ -5756,6 +5726,13 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
					CLT_PARAMETERS,     // CLTParameters    clt_parameters,
					GPU_TILE_PROCESSOR,
					DEBUG_LEVEL);
		} else if (label.equals("Test video")) {
			ImagePlus imp_sel = WindowManager.getCurrentImage();
			if (imp_sel == null) {
				IJ.showMessage("Error", "No images selected");
				return;
			}
			ComboMap.testVideo(imp_sel);
		}
		
	}
+325 −1
Original line number Diff line number Diff line
package com.elphel.imagej.orthomosaic;

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;

import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.ims.Imx5;
import com.elphel.imagej.readers.ElphelTiffReader;
import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import com.elphel.imagej.tileprocessor.QuadCLT;

import Jama.Matrix;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.gui.PointRoi;
import ij.plugin.filter.AVI_Writer;
import ij.plugin.filter.GaussianBlur;
import ij.process.FloatProcessor;
import ij.process.ImageConverter;
import ij.process.ImageProcessor;

public class ComboMap {
	public static boolean FIX_VERT_Y = false; // true; // temporarily fix vertical Y coordinate bug (use -GCORR in the filename?)
@@ -97,6 +109,10 @@ public class ComboMap {
		images = new HashMap <Integer, FloatImageData>();
	}
	
	
	public LocalDateTime getLocalDateTime() {
		return dt;
	}
	public static ComboMap[] initializeComboMaps(
			String [] image_paths) { // full paths, including ext
		double [][] affine = {{1,0,0},{0,1,0}}; // maybe later calculate from mage_enuatr
@@ -595,7 +611,7 @@ public class ComboMap {
				centers); // double [][] centers)
		String [] map_names = new String[maps.length];
		for (int n = 0; n < maps.length; n++) { 
			map_names[n] = maps[n].getName();
			map_names[n] = maps[n].getName()+"_"+maps[n].getLocalDateTime().toString().replace("T","_")+"_UTC";
		}
		
        ImageStack stack = ShowDoubleFloatArrays.makeStack( 
@@ -750,5 +766,313 @@ public class ComboMap {
		
		return null;
	}
	public static void testVideo(ImagePlus imp) {
		String path_prefix = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/videos/video_";
		boolean   keep_original =        true;
		boolean   um_apply =             true;
		double    um_sigma =             10.0;
		double    um_weight =            0.9;
		boolean   auto_range =           false;
		double    mono_range =           300.0; 
		boolean   annotate   =           true;
		Color     annotate_color =       new Color( 255, 180,  50);
		boolean   annotate_transparent = false;
		int       annotate_font_size =   36;
		boolean   annotate_font_bold =   true;
		double    video_fps =            10;
		boolean   avi_compress_jpeg =    false;
		int       aviJpegQuality =       95;
		boolean   run_ffmpeg =           true;
		String    video_ext =            ".webm";
		String    video_codec =          "vp8";
		int       video_crf =            10; // lower - better, larger file size
		boolean   remove_avi =           true;
		int       debugLevel =           0;
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Parameters for video from orthographic imges",1200,800);
		gd.addStringField ("Output video path prefix",  path_prefix, 180,
				"Absolute path prefix for the video (image title will be added).");
		gd.addCheckbox    ("Keep original image", keep_original, "If true, will generate new RGB image, if false - replace existent.");
		gd.addCheckbox    ("Apply unsharp mask filter", um_apply, "Apply unsharp mask filter.");
		gd.addNumericField("Unsharp mask sigma", um_sigma,  3,7,"",	"Unsharp mask sigma.");
		gd.addNumericField("Unsharp mask weight", um_weight,  3,7,"",	"Unsharp mask weight.");
		gd.addCheckbox    ("Auto range while congerting to RGB", auto_range, "Autorange 32-bit floating point image when converting to RGB.");
		gd.addNumericField("Fixed range during conversion to RGB", mono_range,  3,7,"",	"Fixed range.");
		gd.addCheckbox    ("Annotate each frame with timestamp+date/time", annotate,
				"Embed annotation in the bottom-right corner of each frame of the converted image file and video.");
		{
			String scolor = (annotate_color==null)?"none":String.format("%08x", IntersceneMatchParameters.getLongColor(annotate_color));
			gd.addStringField ("Annotation color (hex number)",scolor, 8, "Any invalid hex number disables annotation");
		}
		gd.addCheckbox    ("Annotation transparent background", annotate_transparent, "Put annotation text directly over images.");
		gd.addNumericField("Annotation font size", annotate_font_size, 0, 4, "", "Annotation font size.");
		gd.addCheckbox    ("Bold annotation", annotate_font_bold, "Use bold font for annotations.");
		gd.addNumericField("Video output frame rate", video_fps,  3,7,"fps", "Frame rate of the video.");
		gd.addCheckbox    ("Compress AVI with JPEG", avi_compress_jpeg, "Use JPEG for AVI compression (false - use raw).");
		gd.addNumericField("AVI JPEG quality", aviJpegQuality, 0, 4, "", "AVI JPEG quality if JPEG compression is used.");
		gd.addCheckbox    ("Convert AVI to WEBM", run_ffmpeg, "Use ffmped to convert intermediate AVI video to WEBM.");
		gd.addStringField ("WEBM output extension",  video_ext, 5,"WEBM output file extension including dot, normally \".webm\".");
		gd.addStringField ("WEBM codec",  video_codec, 5,"WEBM codec \"vp8\" or \"vp9\"(vp9 had problems).");
		gd.addNumericField("WEBM CRF", video_crf, 0, 4, "", "WEBM compression quality (lower - better, 10 - good).");
		gd.addCheckbox    ("Remove AVI", remove_avi, "Remove AVI (large file) after WEBM generation.");
		gd.addNumericField("Debug level", debugLevel, 0, 4, "", "Debug level (not yet used).");
		gd.showDialog();
		if (gd.wasCanceled()) return;
		path_prefix =          gd.getNextString();
		keep_original =        gd.getNextBoolean();
		um_apply =             gd.getNextBoolean();
		um_sigma=              gd.getNextNumber();
		um_weight=             gd.getNextNumber();
		auto_range =           gd.getNextBoolean();
		mono_range =           gd.getNextNumber();
		annotate =             gd.getNextBoolean();
        {
			String scolor =             gd.getNextString();
			long lcolor = -1;
			try {
				lcolor = Long.parseLong(scolor,16);
				annotate_color = IntersceneMatchParameters.setLongColor(lcolor);
			} catch(NumberFormatException e){
				annotate_color = null;
			}
        }
		annotate_transparent =     gd.getNextBoolean();
		annotate_font_size = (int) gd.getNextNumber();		
		annotate_font_bold =       gd.getNextBoolean();
		video_fps =                gd.getNextNumber();
		avi_compress_jpeg =        gd.getNextBoolean();
		aviJpegQuality =     (int) gd.getNextNumber();
		run_ffmpeg =               gd.getNextBoolean();
		video_ext =                gd.getNextString();
		video_codec =              gd.getNextString();
		video_crf =          (int) gd.getNextNumber();
		remove_avi =               gd.getNextBoolean();
		debugLevel =         (int) gd.getNextNumber();
		
		ImagePlus imp_um;
		if (um_apply) {
			imp_um = applyUnsharpMask(
					imp,           // final ImagePlus imp,
					keep_original, // final boolean   keep_original,
					um_sigma,      // 10,            // final double    um_sigma,
					um_weight);    // 0.9);          // final double    um_weight
		} else {
			imp_um = keep_original? imp.duplicate():imp;
		}
        System.out.println("applyUnsharpMask() DONE!");	
    	ImagePlus imp_rgb = convertToColorAnnotate(
    			imp_um,               // ImagePlus imp_src,
    			false,                // boolean   keep_original,
    			auto_range? 0:mono_range, // 300,  // double    mono_range,  // >0 - apply 
    			annotate,             // boolean   annotate,
    			annotate_color,       // Color.RED,  //Color    annotate_color,
    			annotate_transparent, // boolean   annotate_transparent,
    			annotate_font_size,   // int       annotate_font_size, // 12
    			annotate_font_bold,   // boolean   annotate_font_bold,
    			debugLevel);          // int       debugLevel)
    	imp_rgb.show();
        System.out.println("convertToColorAnnotate() DONE!");
        String path = path_prefix+imp_rgb.getTitle();
        int mode_avi = avi_compress_jpeg? 1 : 0;
        saveRGBSlicesAsVideo(
        		imp_rgb,        // ImagePlus  imp,
//    			0,              // int        col_mode, // 0 - mono, 1 - color
    			path,           // String     path,
    			video_fps,      // double     video_fps,
    			mode_avi,       // int        mode_avi, // 0 - raw, 1 - JPEG, 2 - PNG
    			aviJpegQuality, // int        aviJpegQuality,
    			run_ffmpeg,     // boolean    run_ffmpeg,
    			video_ext,      // ".webm",   // String     video_ext,
    			video_codec,    // "vp8",     // String     video_codec,
    			video_crf,      // 10,        // int        video_crf, // lower - better, larger file size
    			remove_avi,     // boolean    remove_avi,
    			debugLevel);    // final int  debugLevel
    			        
        System.out.println("saveRGBSlicesAsVideo() DONE!");
	}
	
	
	public static ImagePlus applyUnsharpMask(
			final ImagePlus imp_src,
			final boolean   keep_original, 
			final double    um_sigma,
			final double    um_weight
			) {
		final float fum_weight=(float) um_weight;
		final ImagePlus imp = keep_original? imp_src.duplicate() : imp_src;
		final ImageStack fstack_scenes = imp.getStack();
		final int nSlices = fstack_scenes.getSize();
		final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
		final AtomicInteger ai = new AtomicInteger(0);
		for (int ithread = 0; ithread < threads.length; ithread++) {
			threads[ithread] = new Thread() {
				public void run() {
					for (int nSlice = ai.getAndIncrement(); nSlice < nSlices; nSlice = ai.getAndIncrement()) {
						FloatProcessor fp = (FloatProcessor) fstack_scenes.getProcessor(nSlice+1);
						float [] fpixels = (float[]) fstack_scenes.getPixels(nSlice+1);
						float [] fpixels_orig = fpixels.clone();
						(new GaussianBlur()).blurFloat(
								fp,       // FloatProcessor ip,
								um_sigma, // double sigmaX,
								um_sigma, // double sigmaY,
								0.01);    // double accuracy)
						for (int i = 0; i < fpixels.length; i++) {
							fpixels[i] = fpixels_orig[i] - fum_weight * fpixels[i];
						}
					}
				}
			};
		}		      
		ImageDtt.startAndJoin(threads);
		imp.setTitle(removeKnownExtension(imp.getTitle())+String.format("-UM%.1f_%.2f",um_sigma,um_weight));
		return imp;
	}
	
	public static ImagePlus convertToColorAnnotate(
			ImagePlus imp_src,
			boolean   keep_original,
			double    mono_range,  // >0 - apply 
			boolean   annotate,
			Color     annotate_color,
			boolean   annotate_transparent,
			int       annotate_font_size, // 12
			boolean   annotate_font_bold,
			int       debugLevel) {
		final ImagePlus imp = keep_original? imp_src.duplicate() : imp_src;
		if (imp.getType() != ImagePlus.COLOR_RGB) {
			if (mono_range > 0) {
				imp.getProcessor().setMinAndMax(-mono_range/2, mono_range/2);
			}
			ImageConverter imageConverter = new ImageConverter(imp);
			imageConverter.convertToRGB();
		}
		final Color fcolor = annotate_color;
		final ImageStack fstack_scenes = imp.getImageStack();
		int title_len = 0;
		final int nSlices = fstack_scenes.getSize();
		for (int i = 0; i < nSlices; i++) {
			if (fstack_scenes.getSliceLabel(i+1).length() > title_len) {
				title_len=fstack_scenes.getSliceLabel(i+1).length();
			}
		}
		final int annotate_size = title_len; //
		final int width =  imp_src.getWidth();
		final int height = imp_src.getHeight();
		final double char_wtoh = 0.6;
		final int posX= width - ((int) (char_wtoh* annotate_size * annotate_font_size)); //  119; // 521;
		final int posY= height + 1;  // 513;
		final Font font = new Font("Monospaced", Font.PLAIN | (annotate_font_bold ? Font.BOLD: 0), annotate_font_size);
		final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
		final AtomicInteger ai = new AtomicInteger(0);
		for (int ithread = 0; ithread < threads.length; ithread++) {
			threads[ithread] = new Thread() {
				public void run() {
					for (int nSlice = ai.getAndIncrement(); nSlice < nSlices; nSlice = ai.getAndIncrement()) {
						String scene_title = fstack_scenes.getSliceLabel(nSlice+1);
						ImageProcessor ip = fstack_scenes.getProcessor(nSlice+1);
						ip.setColor(fcolor); // Color.BLUE);
						ip.setFont(font);
						if (!annotate_transparent) { // toRGB || !annotate_transparent_mono) {
							ip.drawString(scene_title, posX, posY,Color.BLACK);
						} else {
							ip.drawString(scene_title, posX, posY); // transparent
						}
					}
				}
			};
		}		      
		ImageDtt.startAndJoin(threads);
		imp.setTitle(removeKnownExtension(imp.getTitle())+((mono_range > 0) ? String.format("_%.0f",mono_range):"_A"));
		return imp;
	}
	
	public static String removeKnownExtension(String path) {
		String [] remove_ext = {".tiff", ".tif", ".avi"};
		for (String ext:remove_ext) {
			if (path.endsWith(ext)) {
				path = path.substring(0,path.length()-ext.length());
			}
		}
		return path;

	}
	public static boolean saveRGBSlicesAsVideo(
			ImagePlus  imp,
//			int        col_mode, // 0 - mono, 1 - color
			String     path,
			double     video_fps,
			int        mode_avi, // compression
			int        aviJpegQuality,
			boolean    run_ffmpeg,
			String     video_ext,
			String     video_codec,
			int        video_crf,
			boolean    remove_avi,
			final int  debugLevel
			) {
		boolean generate_mapped = true; // false - here just simulate
		// no_combine, stereo_2_images, stereo_anaglyth
		String avi_path = removeKnownExtension(path)+String.format("-FPS%04.1f",video_fps)+".avi";
		imp.getCalibration().fps = video_fps;
		video:
		{
			try {
				(new AVI_Writer()).writeImage (
						imp, // ImagePlus imp,
						avi_path, // String path,
						mode_avi, // int compression,
						aviJpegQuality); //int jpegQuality)
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				break video;
			}
			System.out.println("saveAVIInModelDirectory(): saved "+avi_path);
			if (!run_ffmpeg) {
				break video; // webm not requested
			}

			String webm_path = avi_path.substring(0, avi_path.length()-4)+video_ext;
			// added -y not to as "overwrite y/n?"
			//ffmpeg -i input_file.mkv -c copy -metadata:s:v:0 stereo_mode=1 output_file.mkv 
			//https://ffmpeg.org/ffmpeg-formats.html
			//ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
			//anaglyph_cyan_red 
			String stereo_meta = ""; // used in OpticalFlow
			String shellCommand = String.format("ffmpeg -y -i %s -c %s -b:v 0 -crf %d %s %s",
					avi_path, video_codec, video_crf, stereo_meta, webm_path);
			Process p = null;
			if (generate_mapped) {
				int exit_code = -1;
				try {
					p = Runtime.getRuntime().exec(shellCommand);
				} catch (IOException e) {
					System.out.println("Failed shell command: \""+shellCommand+"\"");
				}
				if (p != null) {
					try {
						p.waitFor();
					} catch (InterruptedException e) {
						System.out.println("saveRGBSlicesAsVideo(): failed waiting for process to finish.");
						// TODO Auto-generated catch block
						e.printStackTrace();
						return false;
					}
					exit_code = p.exitValue();
				}
				System.out.println("Ran shell command: \""+shellCommand+"\" -> "+exit_code);
				// Check if webm file exists
				if ((exit_code != 0) || !(new File(webm_path)).exists()) {
					System.out.println("Failed to create : \""+webm_path+"\"");
					break video;
				}
			} else {
				System.out.println("Simulated shell command: \""+shellCommand);
			}
			if (remove_avi && generate_mapped) {
				(new File(avi_path)).delete();
				System.out.println("Deleted AVI video file: \""+avi_path+"\"");
			}
		}
		return true;
	}
}
+7 −29
Original line number Diff line number Diff line
@@ -43,29 +43,9 @@ public class ComboMatch {
			 GPUTileProcessor gpu_tile_processor, // initialized by the caller
			 final int        debugLevel) {
		GPU_TILE_PROCESSOR = gpu_tile_processor;
		String [] image_paths_pre_0 = {
//				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-b/1697877410_420287/1697877410_420287-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
//				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-b/1697877412_004148/1697877412_004148-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877409_353265/1697877409_353265-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877410_403615/1697877410_403615-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877411_987476/1697877411_987476-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877413_137859/1697877413_137859-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877414_404948/1697877414_404948-RECT-PIX0.01-FLAT_CLN-VERT-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877415_521986/1697877415_521986-RECT-PIX0.01-FLAT_CLN-VERT-GEO"
		};

		String [] image_paths_pre = {
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877409_353265/1697877409_353265-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877410_403615/1697877410_403615-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877411_987476/1697877411_987476-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877413_137859/1697877413_137859-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877414_404948/1697877414_404948-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO",
				"/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-c/1697877415_521986/1697877415_521986-RECT-PIX0.01-FLAT_CLN-VERT-GCORR-GEO"
		};
		// find -L /media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-b/ -type f -name "*-GCORR-GEO.tiff" | sort  > GCORR-GEO.list

		String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/linked/linked_1697875868-1697879449-b/maps_01.list";
		String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_berdich2.list";
		
		double [][][] image_enuatr = {{{0,0,0},{0,0,0}},{{0,0,0},{0,0,0}}};
		int gpu_width=  clt_parameters.imp.rln_gpu_width; // 3008;
@@ -122,10 +102,6 @@ public class ComboMatch {
		
		show_centers =              gd.getNextBoolean();
		use_alt =                   gd.getNextBoolean();
		String [] full_paths = new String[image_paths_pre.length];
		for (int n = 0; n < full_paths.length; n++) { 
			full_paths[n] = image_paths_pre[n]+".tiff";
		}		
//		ComboMap[] combo_maps = ComboMap.initializeComboMaps(
//				full_paths); // String [] image_paths);
		ComboMap[] combo_maps = ComboMap.initializeComboMaps(
@@ -170,14 +146,14 @@ public class ComboMatch {
        		true,
        		"gpu_pair-zoom"+zoom_lev+"-"+combo_maps[gpu_pair[0]].getName()+"-"+combo_maps[gpu_pair[1]].getName(),
        		map_names);
		if (image_paths_pre.length > 2) {
		if (debugLevel <1000) {
			return true;
		}
		/* */
		int [] widths = new int[imp_src.length];
		int [] heights = new int[imp_src.length];
		for (int n = 0; n < imp_src.length; n++) { 
			imp_src[n] = new ImagePlus(image_paths_pre[n]+".tiff"); // may use +"-ALT.tiff"
//			imp_src[n] = new ImagePlus(image_paths_pre[n]+".tiff"); // may use +"-ALT.tiff"
			widths[n] = imp_src[n].getWidth();
			heights[n] = imp_src[n].getHeight();
		}
@@ -187,12 +163,14 @@ public class ComboMatch {
		double [][] xy_pix_centers = new double [2][];
		double [] pix_sizes = new double[2]; // ElphelTiffReader.getPixelSize(imp_prop[0])[0];
		for (int n = 0; n < imp_src.length; n++) {
			/*
			try {
				imp_prop[n] = ElphelTiffReader.getTiffMeta(image_paths_pre[n]+".tiff");				
//				imp_prop[n] = ElphelTiffReader.getTiffMeta(image_paths_pre[n]+".tiff");				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			*/
			llas[n] = ElphelTiffReader.getLLA(imp_prop[n]);
			dts[n] = ElphelTiffReader.getLocalDateTime(imp_prop[n]);
			xy_pix_centers[n] = ElphelTiffReader.getXYOffsetPixels(imp_prop[n]);
+5 −5
Original line number Diff line number Diff line
@@ -5907,7 +5907,7 @@ public class OpticalFlow {
	        								imp_scenes_pair[nstereo].getProcessor().setMinAndMax(-mono_range/2, mono_range/2);
	        							}
	        							ImageConverter imageConverter = new ImageConverter(imp_scenes_pair[nstereo]);
	        							imageConverter.convertToRGB(); // Did it convert imp_scenes ?
	        							imageConverter.convertToRGB(); // Did it convert imp_scenes ? YES
	        						}
	        						final Color fcolor = toRGB ? annotate_color_color: annotate_color_mono;
@@ -6079,13 +6079,13 @@ public class OpticalFlow {
	        				    		//https://ffmpeg.org/ffmpeg-formats.html
	        				    		//ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
	        				    		//anaglyph_cyan_red 
	        							String streo_meta = "";
	        							String stereo_meta = "";
	        							if ((webm_path.contains("-STEREO-")) || (webm_path.contains("-SBS-"))) {
	        								if (stereo_gap == 0) {
	        									if (debugLevel > -3) {
	        										System.out.println("Adding 3D meta: stereo_mode=left_right");
	        									}
	        									streo_meta = " -metadata:s:v:0 stereo_mode=left_right ";
	        									stereo_meta = " -metadata:s:v:0 stereo_mode=left_right ";
	        								} else {
	        									if (debugLevel > -3) {
	        										System.out.println("stereo_gap !=0, skipping 3D meta as firefox/vlc halves display width");
@@ -6095,11 +6095,11 @@ public class OpticalFlow {
        									if (debugLevel > -3) {
        										System.out.println("Adding 3D meta: stereo_mode=anaglyph_cyan_red");
        									}
		        							streo_meta = " -metadata:s:v:0 stereo_mode=anaglyph_cyan_red ";
		        							stereo_meta = " -metadata:s:v:0 stereo_mode=anaglyph_cyan_red ";
	        							}
	        							String shellCommand = String.format("ffmpeg -y -i %s -c %s -b:v 0 -crf %d %s %s",
	        									avi_path, video_codec, video_crf, streo_meta, webm_path);
	        									avi_path, video_codec, video_crf, stereo_meta, webm_path);
	        							Process p = null;
	        							if (generate_mapped) {
	        								int exit_code = -1;