Loading src/main/java/com/elphel/imagej/cameras/CLTParameters.java +78 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,19 @@ public class CLTParameters { public double tex_distort = 0.8; // Maximal texture distortion to accumulate multiple scenes (0 - any) public double tex_mb = 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length) public boolean tex_um = true; // Use unsharp mask filter for textures public double tex_um_sigma = 10.0; // Unsharp mask sigma for textures public double tex_um_weight = 0.97;// Unsharp mask weight public boolean tex_lwir_autorange = true; // Autorange LWIR textures public boolean tex_um_fixed = false; // Use fixed range after unsharp mask instead of autorange public double tex_um_range = 500; // Full range after unsharp mask public boolean tex_hist_norm = true; // Normalize texture histogram public double tex_hist_amount = 0.7; // Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization) public int tex_hist_bins = 1024; // Number of histogram bins to use for texture histograms public int tex_hist_segments = 32; // Number of evenly-spaced percentiles to use for histogram normalization public boolean tex_color = true; // Use pseudo-colored textures public int tex_palette = 2; // Palette number for pseudo colors public boolean show_textures = true; // show generated textures public boolean debug_filters = false;// show intermediate results of filtering // not used anywhere so far Loading Loading @@ -1394,6 +1407,19 @@ public class CLTParameters { properties.setProperty(prefix+"tex_distort", this.tex_distort+""); // double properties.setProperty(prefix+"tex_mb", this.tex_mb+""); // double properties.setProperty(prefix+"tex_um", this.tex_um+""); // boolean properties.setProperty(prefix+"tex_um_sigma", this.tex_um_sigma+""); // double properties.setProperty(prefix+"tex_um_weight", this.tex_um_weight+""); // double properties.setProperty(prefix+"tex_lwir_autorange", this.tex_lwir_autorange+""); // boolean properties.setProperty(prefix+"tex_um_fixed", this.tex_um_fixed+""); // boolean properties.setProperty(prefix+"tex_um_range", this.tex_um_range+""); // double properties.setProperty(prefix+"tex_hist_norm", this.tex_hist_norm+""); // boolean properties.setProperty(prefix+"tex_hist_amount", this.tex_hist_amount+""); // double properties.setProperty(prefix+"tex_hist_bins", this.tex_hist_bins+""); // int properties.setProperty(prefix+"tex_hist_segments", this.tex_hist_segments+""); // int properties.setProperty(prefix+"tex_color", this.tex_color+""); // boolean properties.setProperty(prefix+"tex_palette", this.tex_palette+""); // int properties.setProperty(prefix+"show_textures", this.show_textures+""); properties.setProperty(prefix+"debug_filters", this.debug_filters+""); Loading Loading @@ -2274,6 +2300,19 @@ public class CLTParameters { if (properties.getProperty(prefix+"tex_distort")!=null) this.tex_distort=Double.parseDouble(properties.getProperty(prefix+"tex_distort")); if (properties.getProperty(prefix+"tex_mb")!=null) this.tex_mb=Double.parseDouble(properties.getProperty(prefix+"tex_mb")); if (properties.getProperty(prefix+"tex_um")!=null) this.tex_um=Boolean.parseBoolean(properties.getProperty(prefix+"tex_um")); if (properties.getProperty(prefix+"tex_um_sigma")!=null) this.tex_um_sigma=Double.parseDouble(properties.getProperty(prefix+"tex_um_sigma")); if (properties.getProperty(prefix+"tex_um_weight")!=null) this.tex_um_weight=Double.parseDouble(properties.getProperty(prefix+"tex_um_weight")); if (properties.getProperty(prefix+"tex_lwir_autorange")!=null) this.tex_lwir_autorange=Boolean.parseBoolean(properties.getProperty(prefix+"tex_lwir_autorange")); if (properties.getProperty(prefix+"tex_um_fixed")!=null) this.tex_um_fixed=Boolean.parseBoolean(properties.getProperty(prefix+"tex_um_fixed")); if (properties.getProperty(prefix+"tex_um_range")!=null) this.tex_um_range=Double.parseDouble(properties.getProperty(prefix+"tex_um_range")); if (properties.getProperty(prefix+"tex_hist_norm")!=null) this.tex_hist_norm=Boolean.parseBoolean(properties.getProperty(prefix+"tex_hist_norm")); if (properties.getProperty(prefix+"tex_hist_amount")!=null) this.tex_hist_amount=Double.parseDouble(properties.getProperty(prefix+"tex_hist_amount")); if (properties.getProperty(prefix+"tex_hist_bins")!=null) this.tex_hist_bins=Integer.parseInt(properties.getProperty(prefix+"tex_hist_bins")); if (properties.getProperty(prefix+"tex_hist_segments")!=null) this.tex_hist_segments=Integer.parseInt(properties.getProperty(prefix+"tex_hist_segments")); if (properties.getProperty(prefix+"tex_color")!=null) this.tex_color=Boolean.parseBoolean(properties.getProperty(prefix+"tex_color")); if (properties.getProperty(prefix+"tex_palette")!=null) this.tex_palette=Integer.parseInt(properties.getProperty(prefix+"tex_palette")); if (properties.getProperty(prefix+"show_textures")!=null) this.show_textures=Boolean.parseBoolean(properties.getProperty(prefix+"show_textures")); if (properties.getProperty(prefix+"debug_filters")!=null) this.debug_filters=Boolean.parseBoolean(properties.getProperty(prefix+"debug_filters")); Loading Loading @@ -3313,6 +3352,32 @@ public class CLTParameters { "Maximal texture distortion to accumulate multiple scenes (neighbor tile center offset from the uniform grid. 0 - do not filter"); gd.addNumericField("Maximal motion blur to reduce weight",this.tex_mb, 5,7,"pix", "Reduce texture weight if motion blur exceeds this (as square of MB length)."); gd.addMessage ("Textures rendering"); gd.addCheckbox ("Apply unsharp mask", this.tex_um, "Use unsharp mask filter for texture."); gd.addNumericField("Unsharp mask sigma", this.tex_um_sigma, 5,7,"pix", "Unsharp mask sigma for textures."); gd.addNumericField("Unsharp mask weight", this.tex_um_weight, 5,7,"", "Unsharp mask weight."); gd.addCheckbox ("Autorange LWIR textures", this.tex_lwir_autorange, "Autorange LWIR textures (inluding after unsharp mask)."); gd.addCheckbox ("Fixed range (after unsharp only)", this.tex_um_fixed, "Use fixed range after unsharp mask instead of autorange."); gd.addNumericField("Full range", this.tex_um_range, 5,7,"counts", "Full range after unsharp mask."); gd.addCheckbox ("Normalize texture histogram", this.tex_hist_norm, "Normalize texture histogram."); gd.addNumericField("Histogram normalization amount", this.tex_hist_amount, 5,7,"", "Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization)."); gd.addNumericField("Number of histogram bins", this.tex_hist_bins, 0,3,"", "Number of histogram bins to use for texture histograms."); gd.addNumericField("Number of histogram percentiles", this.tex_hist_segments, 0,3,"", "Number of evenly-spaced percentiles to use for histogram normalization."); gd.addCheckbox ("Use pseudo-color", this.tex_color, "Use pseudo-colored textures (false - monochrome, float)."); gd.addNumericField("Palette number", this.tex_palette, 0,3,"", "Palette number for pseudo colors."); gd.addMessage ("Earlier 3D generation parameters"); gd.addCheckbox ("Show generated textures", this.show_textures); gd.addCheckbox ("show intermediate results of filtering", this.debug_filters); Loading Loading @@ -4329,6 +4394,19 @@ public class CLTParameters { this.tex_distort = gd.getNextNumber(); this.tex_mb = gd.getNextNumber(); this.tex_um = gd.getNextBoolean(); this.tex_um_sigma = gd.getNextNumber(); this.tex_um_weight = gd.getNextNumber(); this.tex_lwir_autorange = gd.getNextBoolean(); this.tex_um_fixed = gd.getNextBoolean(); this.tex_um_range = gd.getNextNumber(); this.tex_hist_norm = gd.getNextBoolean(); this.tex_hist_amount = gd.getNextNumber(); this.tex_hist_bins = (int) gd.getNextNumber(); this.tex_hist_segments = (int) gd.getNextNumber(); this.tex_color = gd.getNextBoolean(); this.tex_palette = (int) gd.getNextNumber(); this.show_textures= gd.getNextBoolean(); this.debug_filters= gd.getNextBoolean(); this.min_smth= gd.getNextNumber(); Loading src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java +3 −1 Original line number Diff line number Diff line Loading @@ -5296,10 +5296,12 @@ public class OpticalFlow { clt_parameters, // CLTParameters clt_parameters, colorProcParameters, // ColorProcParameters colorProcParameters, rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters, quadCLTs[quadCLTs.length-1], // quadCLT_main, // final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene quadCLTs, // QuadCLT [] scenes, combo_dsn_final, //double [][] combo_dsn_final, // null OK, will read file updateStatus, // final boolean updateStatus, debugLevel + 1); // final int debugLevel) debugLevel); // + 1); // final int debugLevel) System.out.println ("TexturedModel.output3d() -> "+ok_3d); } Loading src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java +434 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java +135 −70 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.ColorProcParameters; import com.elphel.imagej.cameras.EyesisCorrectionParameters; import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.correction.EyesisCorrections; import com.elphel.imagej.gpu.GpuQuad; import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.x3d.export.WavefrontExport; Loading Loading @@ -528,6 +529,8 @@ public class TexturedModel { CLTParameters clt_parameters, ColorProcParameters colorProcParameters, EyesisCorrectionParameters.RGBParameters rgbParameters, final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene QuadCLT [] scenes, double [][] combo_dsn_final, // null OK, will read file // final int threadsMax, // maximal number of threads to launch Loading Loading @@ -619,17 +622,41 @@ public class TexturedModel { for (int i = 0; i < scenes.length; i++) { // start with just one (reference) scene scenes_sel[i] = true; } boolean renormalize = true;// false - use normalizations from previous scenes to keep consistent colors ImagePlus[] combined_textures = getInterCombinedTextures( // return ImagePlus[] matching tileClusters[], with alpha clt_parameters, // final CLTParameters clt_parameters, colorProcParameters, // ColorProcParameters colorProcParameters, rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters, parameter_scene, // final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene scenes, // final QuadCLT [] scenes, scenes_sel, // final boolean [] scenes_sel, // null or which scenes to process null, // final boolean [] selection, // may be null, if not null do not process unselected tiles tileClusters, // final TileCluster [] tileClusters, // disparities, borders, selections for texture passes // final int margin, renormalize, // final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors debugLevel); // final int debug_level) boolean save_full_textures = true; if (save_full_textures) { EyesisCorrectionParameters.CorrectionParameters correctionsParameters = ref_scene.correctionsParameters; for (int nslice = 0; nslice < combined_textures.length; nslice++) { String path= correctionsParameters.selectX3dDirectory( //TODO: Which one to use - name or this.image_name ? correctionsParameters.getModelName(ref_scene.getImageName()), // quad timestamp. Will be ignored if correctionsParameters.use_x3d_subdirs is false correctionsParameters.x3dModelVersion, true, // smart, true); //newAllowed, // save EyesisCorrections.saveAndShow( combined_textures[nslice], // imp_texture_cluster, path, correctionsParameters.png, false, // (nslice < 4), // clt_parameters.show_textures, -1, // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG 1); // } } if (debugLevel > -100) { return true; } Loading Loading @@ -885,16 +912,21 @@ public class TexturedModel { final CLTParameters clt_parameters, ColorProcParameters colorProcParameters, EyesisCorrectionParameters.RGBParameters rgbParameters, QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene final QuadCLT [] scenes, final boolean [] scenes_sel, // null or which scenes to process final boolean [] selection, // may be null, if not null do not process unselected tiles final TileCluster [] tileClusters, // disparities, borders, selections for texture passes // final int margin, final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors final int debug_level) { // TODO: ***** scenes with high motion blur also have high ERS to be corrected ! ***** final int ref_index = scenes.length -1; final QuadCLT ref_scene = scenes[ref_index]; if (parameter_scene == null) { parameter_scene = ref_scene; } final int earliestScene = ref_scene.getEarliestScene(scenes); final ErsCorrection ers_reference = ref_scene.getErsCorrection(); final int tilesX = ref_scene.getTileProcessor().getTilesX(); Loading @@ -912,7 +944,23 @@ public class TexturedModel { final double tex_mb = clt_parameters.tex_mb; // 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length) final boolean sharp_alpha = clt_parameters.sharp_alpha; final boolean is_lwir = ref_scene.isLwir(); final boolean lwir_autorange = is_lwir && colorProcParameters.lwir_autorange; final boolean tex_um = clt_parameters.tex_um; // imp.um_mono; // TODO: add own parameter final double tex_um_sigma = clt_parameters.tex_um_sigma; // imp.um_sigma; final double tex_um_weight = clt_parameters.tex_um_weight; // imp.um_weight; // TODO: - make texture variants, tex_um_fixed/tex_um_range apply only to unsharp mask, regardless of colors final boolean lwir_autorange = is_lwir && clt_parameters.tex_lwir_autorange; // colorProcParameters.lwir_autorange; final boolean tex_um_fixed = clt_parameters.tex_um_fixed; // imp.mono_fixed; // true; // normalize to fixed range when converting to 8 bits final double tex_um_range = clt_parameters.tex_um_range; // imp.mono_range; // 500.0; // monochrome full-scale range (+/- half) final boolean tex_hist_norm = clt_parameters.tex_hist_norm; // true; final double tex_hist_amount = clt_parameters.tex_hist_amount; // clt_parameters. 0.7; final int tex_hist_bins = clt_parameters.tex_hist_bins; // 1024 ; final int tex_hist_segments =clt_parameters.tex_hist_segments; // 32 ; final boolean tex_color = clt_parameters.tex_color; // true; final int tex_palette = clt_parameters.tex_palette; // 2 ; ImageDtt image_dtt; image_dtt = new ImageDtt( Loading @@ -932,7 +980,6 @@ public class TexturedModel { double [][][] inter_weights = new double [num_slices][tilesY][tilesX]; // per-tile texture weights for inter-scene accumulation; double [][][][][] inter_textures= new double [num_slices][tilesY][tilesX][][]; // [channel][256] - non-overlapping textures /// double [][] scene_pXpYD; /// final double disparity_corr = 0.00; // (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction); /// TpTask[] tp_tasks_ref = null; double [][][] ref_pXpYDs = new double [num_slices][][]; // individual for each slice Loading Loading @@ -1118,14 +1165,35 @@ public class TexturedModel { } } } // Optionally apply UM (before auto/manual range) if (tex_um) { QuadCLTCPU.umTextures( faded_textures, // final double [][][] textures, // [nslices][nchn][i] tilesX * transform_size, // final int width, tex_um_sigma, // final double um_sigma, tex_um_weight); // final double um_weight) } //renormalize // normalize all slices together if LWIR // FIXME: Should it be here? Will setColdHot() change photometric calibration ? Or should it be disabled? double [] norm_table = null; // first try, then make save to properties with cold/hot if (renormalize) { if (lwir_autorange) { double rel_low = colorProcParameters.lwir_low; double rel_high = colorProcParameters.lwir_high; if (!Double.isNaN(ref_scene.getLwirOffset())) { rel_low -= ref_scene.getLwirOffset(); rel_high -= ref_scene.getLwirOffset(); double rel_low; double rel_high; boolean force_min_max = true; if (!tex_um && !force_min_max) { // for UM will use min/max rel_low = colorProcParameters.lwir_low; rel_high = colorProcParameters.lwir_high; if (!Double.isNaN(parameter_scene.getLwirOffset())) { // ref_scene or parameter_scene? Or both? rel_low -= parameter_scene.getLwirOffset(); rel_high -= parameter_scene.getLwirOffset(); } } else { // for UM need to calculate min and max (probably OK for non-UM too !) double [] minmax = QuadCLTCPU.getMinMaxTextures( faded_textures ); //double [][][] textures // [nslices][nchn][i] rel_low = minmax[0]; rel_high = minmax[1]; } double [] cold_hot = QuadCLTCPU.autorangeTextures( faded_textures, // double [][][] textures, // [nslices][nchn][i] Loading @@ -1133,15 +1201,41 @@ public class TexturedModel { rel_high, // double hard_hot, // matches data, DC (this.lwir_offset) subtracted colorProcParameters.lwir_too_cold, // double too_cold, // pixels per image colorProcParameters.lwir_too_hot, // double too_hot, // pixels per image 1024); // int num_bins) if (cold_hot != null) { if (!Double.isNaN(ref_scene.getLwirOffset())) { cold_hot[0] += ref_scene.getLwirOffset(); cold_hot[1] += ref_scene.getLwirOffset(); tex_hist_bins); // int num_bins) if ((cold_hot != null) && !tex_um && !force_min_max) { if (!Double.isNaN(parameter_scene.getLwirOffset())) { cold_hot[0] += parameter_scene.getLwirOffset(); cold_hot[1] += parameter_scene.getLwirOffset(); } } parameter_scene.setColdHot(cold_hot); // will be used for shifted images and for texture tiles } else if (tex_um && tex_um_fixed) { // apply fixed range, but for UM only (what about RGB?) parameter_scene.setColdHot(-0.5*tex_um_range, 0.5*tex_um_range); } ref_scene.setColdHot(cold_hot); // will be used for shifted images and for texture tiles if (tex_hist_norm) { // will normalize (0..1) keeping cold_hot to apply during rendering // last norm_table element is <=1.0, first >=0; norm_table = QuadCLTCPU.getHistogramNormalization( faded_textures, // double [][][] textures, // [nslices][nchn][i] parameter_scene.getColdHot(), // double [] minmax, tex_hist_bins, // int num_bins, tex_hist_segments, //int num_nodes tex_hist_amount); //double hist_normalize_amount // 1.0 - full } } if (tex_hist_norm && (norm_table != null)) { // apply histogram normalization double [] cold_hot = parameter_scene.getColdHot(); // used in linearStackToColor double [] inverted_table = QuadCLTCPU.invertHistogramNormalization( norm_table, // double [] direct_table, // last is <1.0, first > 0 tex_hist_bins); // int num_bins) QuadCLTCPU.applyTexturesNormHist( faded_textures, // final double [][][] textures, // [nslices][nchn][i] cold_hot, // final double [] min_max, inverted_table); // final double [] inv_table) } if (debug_level > -1) { double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; String [] dbg_titles = new String[dbg_textures.length]; Loading Loading @@ -1182,57 +1276,28 @@ public class TexturedModel { } } double [] minmax = parameter_scene.getColdHot(); // used in linearStackToColor ImagePlus [] imp_tex = new ImagePlus[num_slices]; EyesisCorrectionParameters.CorrectionParameters correctionsParameters = ref_scene.correctionsParameters; for (int nslice = 0; nslice < num_slices; nslice++) { // See how textures where processed with alpha /* // Prepare 4-channel images ImagePlus [] imps_RGB = new ImagePlus[iclt_fimg.length]; for (int ncam = 0; ncam < iclt_fimg.length; ncam++) if (iclt_fimg[ncam] != null){ String title=String.format("%s%s-%02d",image_name, sAux(), ncam); imps_RGB[ncam] = linearStackToColor( // probably no need to separate and process the second half with quadCLT_aux (!) clt_parameters, colorProcParameters, rgbParameters, String title=String.format("%s-texture-%02d",ref_scene.getImageName(), nslice); imp_tex[nslice] = QuadCLTCPU.linearStackToColorLWIR( clt_parameters, // CLTParameters clt_parameters, tex_palette, // int lwir_palette, // <0 - do not convert minmax, // double [] minmax, title, // String name, "-D"+clt_parameters.disparity, //String suffix, // such as disparity=... toRGB, // does not work here? !correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result false, // true, // boolean saveShowIntermediate, // save/show if set globally false, // boolean saveShowFinal, // save/show result (color image?) iclt_fimg[ncam], out_width, out_height, 1.0, // scaleExposures[iAux][iSubCam], // double scaleExposure, // is it needed? -1); // debugLevel ); } // combine to a sliced color image int [] slice_seq = {0,1,3,2}; //clockwise if (imps_RGB.length > 4) { slice_seq = new int [imps_RGB.length]; for (int i = 0; i < slice_seq.length; i++) { slice_seq[i] = i; } } int width = imps_RGB[0].getWidth(); int height = imps_RGB[0].getHeight(); ImageStack array_stack=new ImageStack(width,height); for (int i = 0; i<slice_seq.length; i++) if (imps_RGB[slice_seq[i]] != null){ array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels()); } ImagePlus imp_stack = new ImagePlus(image_name+sAux()+suffix, array_stack); imp_stack.getProcessor().resetMinAndMax(); return imp_stack; */ // convert to color or apply UM, "", // String suffix, // such as disparity=... tex_color, // boolean toRGB, faded_textures[nslice], // double [][] texture_data, tilesX * transform_size, // int width, // int tilesX, tilesY * transform_size, // int height, // int tilesY, debug_level); // int debugLevel ) // Add synthetic mesh only with higher resolution? or just any by a specified period?what king of mesh - vertical random, ... // Split and save as png } // Process accumulated textures: average, apply borders, convert to color or apply UM, add synthetic mesh, ... return null; // ImagePlus[] ? with alpha, to be split into png and saved with alpha. return imp_tex; // ImagePlus[] ? with alpha, to be split into png and saved with alpha. } Loading Loading
src/main/java/com/elphel/imagej/cameras/CLTParameters.java +78 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,19 @@ public class CLTParameters { public double tex_distort = 0.8; // Maximal texture distortion to accumulate multiple scenes (0 - any) public double tex_mb = 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length) public boolean tex_um = true; // Use unsharp mask filter for textures public double tex_um_sigma = 10.0; // Unsharp mask sigma for textures public double tex_um_weight = 0.97;// Unsharp mask weight public boolean tex_lwir_autorange = true; // Autorange LWIR textures public boolean tex_um_fixed = false; // Use fixed range after unsharp mask instead of autorange public double tex_um_range = 500; // Full range after unsharp mask public boolean tex_hist_norm = true; // Normalize texture histogram public double tex_hist_amount = 0.7; // Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization) public int tex_hist_bins = 1024; // Number of histogram bins to use for texture histograms public int tex_hist_segments = 32; // Number of evenly-spaced percentiles to use for histogram normalization public boolean tex_color = true; // Use pseudo-colored textures public int tex_palette = 2; // Palette number for pseudo colors public boolean show_textures = true; // show generated textures public boolean debug_filters = false;// show intermediate results of filtering // not used anywhere so far Loading Loading @@ -1394,6 +1407,19 @@ public class CLTParameters { properties.setProperty(prefix+"tex_distort", this.tex_distort+""); // double properties.setProperty(prefix+"tex_mb", this.tex_mb+""); // double properties.setProperty(prefix+"tex_um", this.tex_um+""); // boolean properties.setProperty(prefix+"tex_um_sigma", this.tex_um_sigma+""); // double properties.setProperty(prefix+"tex_um_weight", this.tex_um_weight+""); // double properties.setProperty(prefix+"tex_lwir_autorange", this.tex_lwir_autorange+""); // boolean properties.setProperty(prefix+"tex_um_fixed", this.tex_um_fixed+""); // boolean properties.setProperty(prefix+"tex_um_range", this.tex_um_range+""); // double properties.setProperty(prefix+"tex_hist_norm", this.tex_hist_norm+""); // boolean properties.setProperty(prefix+"tex_hist_amount", this.tex_hist_amount+""); // double properties.setProperty(prefix+"tex_hist_bins", this.tex_hist_bins+""); // int properties.setProperty(prefix+"tex_hist_segments", this.tex_hist_segments+""); // int properties.setProperty(prefix+"tex_color", this.tex_color+""); // boolean properties.setProperty(prefix+"tex_palette", this.tex_palette+""); // int properties.setProperty(prefix+"show_textures", this.show_textures+""); properties.setProperty(prefix+"debug_filters", this.debug_filters+""); Loading Loading @@ -2274,6 +2300,19 @@ public class CLTParameters { if (properties.getProperty(prefix+"tex_distort")!=null) this.tex_distort=Double.parseDouble(properties.getProperty(prefix+"tex_distort")); if (properties.getProperty(prefix+"tex_mb")!=null) this.tex_mb=Double.parseDouble(properties.getProperty(prefix+"tex_mb")); if (properties.getProperty(prefix+"tex_um")!=null) this.tex_um=Boolean.parseBoolean(properties.getProperty(prefix+"tex_um")); if (properties.getProperty(prefix+"tex_um_sigma")!=null) this.tex_um_sigma=Double.parseDouble(properties.getProperty(prefix+"tex_um_sigma")); if (properties.getProperty(prefix+"tex_um_weight")!=null) this.tex_um_weight=Double.parseDouble(properties.getProperty(prefix+"tex_um_weight")); if (properties.getProperty(prefix+"tex_lwir_autorange")!=null) this.tex_lwir_autorange=Boolean.parseBoolean(properties.getProperty(prefix+"tex_lwir_autorange")); if (properties.getProperty(prefix+"tex_um_fixed")!=null) this.tex_um_fixed=Boolean.parseBoolean(properties.getProperty(prefix+"tex_um_fixed")); if (properties.getProperty(prefix+"tex_um_range")!=null) this.tex_um_range=Double.parseDouble(properties.getProperty(prefix+"tex_um_range")); if (properties.getProperty(prefix+"tex_hist_norm")!=null) this.tex_hist_norm=Boolean.parseBoolean(properties.getProperty(prefix+"tex_hist_norm")); if (properties.getProperty(prefix+"tex_hist_amount")!=null) this.tex_hist_amount=Double.parseDouble(properties.getProperty(prefix+"tex_hist_amount")); if (properties.getProperty(prefix+"tex_hist_bins")!=null) this.tex_hist_bins=Integer.parseInt(properties.getProperty(prefix+"tex_hist_bins")); if (properties.getProperty(prefix+"tex_hist_segments")!=null) this.tex_hist_segments=Integer.parseInt(properties.getProperty(prefix+"tex_hist_segments")); if (properties.getProperty(prefix+"tex_color")!=null) this.tex_color=Boolean.parseBoolean(properties.getProperty(prefix+"tex_color")); if (properties.getProperty(prefix+"tex_palette")!=null) this.tex_palette=Integer.parseInt(properties.getProperty(prefix+"tex_palette")); if (properties.getProperty(prefix+"show_textures")!=null) this.show_textures=Boolean.parseBoolean(properties.getProperty(prefix+"show_textures")); if (properties.getProperty(prefix+"debug_filters")!=null) this.debug_filters=Boolean.parseBoolean(properties.getProperty(prefix+"debug_filters")); Loading Loading @@ -3313,6 +3352,32 @@ public class CLTParameters { "Maximal texture distortion to accumulate multiple scenes (neighbor tile center offset from the uniform grid. 0 - do not filter"); gd.addNumericField("Maximal motion blur to reduce weight",this.tex_mb, 5,7,"pix", "Reduce texture weight if motion blur exceeds this (as square of MB length)."); gd.addMessage ("Textures rendering"); gd.addCheckbox ("Apply unsharp mask", this.tex_um, "Use unsharp mask filter for texture."); gd.addNumericField("Unsharp mask sigma", this.tex_um_sigma, 5,7,"pix", "Unsharp mask sigma for textures."); gd.addNumericField("Unsharp mask weight", this.tex_um_weight, 5,7,"", "Unsharp mask weight."); gd.addCheckbox ("Autorange LWIR textures", this.tex_lwir_autorange, "Autorange LWIR textures (inluding after unsharp mask)."); gd.addCheckbox ("Fixed range (after unsharp only)", this.tex_um_fixed, "Use fixed range after unsharp mask instead of autorange."); gd.addNumericField("Full range", this.tex_um_range, 5,7,"counts", "Full range after unsharp mask."); gd.addCheckbox ("Normalize texture histogram", this.tex_hist_norm, "Normalize texture histogram."); gd.addNumericField("Histogram normalization amount", this.tex_hist_amount, 5,7,"", "Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization)."); gd.addNumericField("Number of histogram bins", this.tex_hist_bins, 0,3,"", "Number of histogram bins to use for texture histograms."); gd.addNumericField("Number of histogram percentiles", this.tex_hist_segments, 0,3,"", "Number of evenly-spaced percentiles to use for histogram normalization."); gd.addCheckbox ("Use pseudo-color", this.tex_color, "Use pseudo-colored textures (false - monochrome, float)."); gd.addNumericField("Palette number", this.tex_palette, 0,3,"", "Palette number for pseudo colors."); gd.addMessage ("Earlier 3D generation parameters"); gd.addCheckbox ("Show generated textures", this.show_textures); gd.addCheckbox ("show intermediate results of filtering", this.debug_filters); Loading Loading @@ -4329,6 +4394,19 @@ public class CLTParameters { this.tex_distort = gd.getNextNumber(); this.tex_mb = gd.getNextNumber(); this.tex_um = gd.getNextBoolean(); this.tex_um_sigma = gd.getNextNumber(); this.tex_um_weight = gd.getNextNumber(); this.tex_lwir_autorange = gd.getNextBoolean(); this.tex_um_fixed = gd.getNextBoolean(); this.tex_um_range = gd.getNextNumber(); this.tex_hist_norm = gd.getNextBoolean(); this.tex_hist_amount = gd.getNextNumber(); this.tex_hist_bins = (int) gd.getNextNumber(); this.tex_hist_segments = (int) gd.getNextNumber(); this.tex_color = gd.getNextBoolean(); this.tex_palette = (int) gd.getNextNumber(); this.show_textures= gd.getNextBoolean(); this.debug_filters= gd.getNextBoolean(); this.min_smth= gd.getNextNumber(); Loading
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java +3 −1 Original line number Diff line number Diff line Loading @@ -5296,10 +5296,12 @@ public class OpticalFlow { clt_parameters, // CLTParameters clt_parameters, colorProcParameters, // ColorProcParameters colorProcParameters, rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters, quadCLTs[quadCLTs.length-1], // quadCLT_main, // final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene quadCLTs, // QuadCLT [] scenes, combo_dsn_final, //double [][] combo_dsn_final, // null OK, will read file updateStatus, // final boolean updateStatus, debugLevel + 1); // final int debugLevel) debugLevel); // + 1); // final int debugLevel) System.out.println ("TexturedModel.output3d() -> "+ok_3d); } Loading
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java +434 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java +135 −70 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.ColorProcParameters; import com.elphel.imagej.cameras.EyesisCorrectionParameters; import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.correction.EyesisCorrections; import com.elphel.imagej.gpu.GpuQuad; import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.x3d.export.WavefrontExport; Loading Loading @@ -528,6 +529,8 @@ public class TexturedModel { CLTParameters clt_parameters, ColorProcParameters colorProcParameters, EyesisCorrectionParameters.RGBParameters rgbParameters, final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene QuadCLT [] scenes, double [][] combo_dsn_final, // null OK, will read file // final int threadsMax, // maximal number of threads to launch Loading Loading @@ -619,17 +622,41 @@ public class TexturedModel { for (int i = 0; i < scenes.length; i++) { // start with just one (reference) scene scenes_sel[i] = true; } boolean renormalize = true;// false - use normalizations from previous scenes to keep consistent colors ImagePlus[] combined_textures = getInterCombinedTextures( // return ImagePlus[] matching tileClusters[], with alpha clt_parameters, // final CLTParameters clt_parameters, colorProcParameters, // ColorProcParameters colorProcParameters, rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters, parameter_scene, // final QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene scenes, // final QuadCLT [] scenes, scenes_sel, // final boolean [] scenes_sel, // null or which scenes to process null, // final boolean [] selection, // may be null, if not null do not process unselected tiles tileClusters, // final TileCluster [] tileClusters, // disparities, borders, selections for texture passes // final int margin, renormalize, // final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors debugLevel); // final int debug_level) boolean save_full_textures = true; if (save_full_textures) { EyesisCorrectionParameters.CorrectionParameters correctionsParameters = ref_scene.correctionsParameters; for (int nslice = 0; nslice < combined_textures.length; nslice++) { String path= correctionsParameters.selectX3dDirectory( //TODO: Which one to use - name or this.image_name ? correctionsParameters.getModelName(ref_scene.getImageName()), // quad timestamp. Will be ignored if correctionsParameters.use_x3d_subdirs is false correctionsParameters.x3dModelVersion, true, // smart, true); //newAllowed, // save EyesisCorrections.saveAndShow( combined_textures[nslice], // imp_texture_cluster, path, correctionsParameters.png, false, // (nslice < 4), // clt_parameters.show_textures, -1, // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG 1); // } } if (debugLevel > -100) { return true; } Loading Loading @@ -885,16 +912,21 @@ public class TexturedModel { final CLTParameters clt_parameters, ColorProcParameters colorProcParameters, EyesisCorrectionParameters.RGBParameters rgbParameters, QuadCLT parameter_scene, // to use for rendering parameters in multi-series sequences // if null - use reference scene final QuadCLT [] scenes, final boolean [] scenes_sel, // null or which scenes to process final boolean [] selection, // may be null, if not null do not process unselected tiles final TileCluster [] tileClusters, // disparities, borders, selections for texture passes // final int margin, final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors final int debug_level) { // TODO: ***** scenes with high motion blur also have high ERS to be corrected ! ***** final int ref_index = scenes.length -1; final QuadCLT ref_scene = scenes[ref_index]; if (parameter_scene == null) { parameter_scene = ref_scene; } final int earliestScene = ref_scene.getEarliestScene(scenes); final ErsCorrection ers_reference = ref_scene.getErsCorrection(); final int tilesX = ref_scene.getTileProcessor().getTilesX(); Loading @@ -912,7 +944,23 @@ public class TexturedModel { final double tex_mb = clt_parameters.tex_mb; // 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length) final boolean sharp_alpha = clt_parameters.sharp_alpha; final boolean is_lwir = ref_scene.isLwir(); final boolean lwir_autorange = is_lwir && colorProcParameters.lwir_autorange; final boolean tex_um = clt_parameters.tex_um; // imp.um_mono; // TODO: add own parameter final double tex_um_sigma = clt_parameters.tex_um_sigma; // imp.um_sigma; final double tex_um_weight = clt_parameters.tex_um_weight; // imp.um_weight; // TODO: - make texture variants, tex_um_fixed/tex_um_range apply only to unsharp mask, regardless of colors final boolean lwir_autorange = is_lwir && clt_parameters.tex_lwir_autorange; // colorProcParameters.lwir_autorange; final boolean tex_um_fixed = clt_parameters.tex_um_fixed; // imp.mono_fixed; // true; // normalize to fixed range when converting to 8 bits final double tex_um_range = clt_parameters.tex_um_range; // imp.mono_range; // 500.0; // monochrome full-scale range (+/- half) final boolean tex_hist_norm = clt_parameters.tex_hist_norm; // true; final double tex_hist_amount = clt_parameters.tex_hist_amount; // clt_parameters. 0.7; final int tex_hist_bins = clt_parameters.tex_hist_bins; // 1024 ; final int tex_hist_segments =clt_parameters.tex_hist_segments; // 32 ; final boolean tex_color = clt_parameters.tex_color; // true; final int tex_palette = clt_parameters.tex_palette; // 2 ; ImageDtt image_dtt; image_dtt = new ImageDtt( Loading @@ -932,7 +980,6 @@ public class TexturedModel { double [][][] inter_weights = new double [num_slices][tilesY][tilesX]; // per-tile texture weights for inter-scene accumulation; double [][][][][] inter_textures= new double [num_slices][tilesY][tilesX][][]; // [channel][256] - non-overlapping textures /// double [][] scene_pXpYD; /// final double disparity_corr = 0.00; // (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction); /// TpTask[] tp_tasks_ref = null; double [][][] ref_pXpYDs = new double [num_slices][][]; // individual for each slice Loading Loading @@ -1118,14 +1165,35 @@ public class TexturedModel { } } } // Optionally apply UM (before auto/manual range) if (tex_um) { QuadCLTCPU.umTextures( faded_textures, // final double [][][] textures, // [nslices][nchn][i] tilesX * transform_size, // final int width, tex_um_sigma, // final double um_sigma, tex_um_weight); // final double um_weight) } //renormalize // normalize all slices together if LWIR // FIXME: Should it be here? Will setColdHot() change photometric calibration ? Or should it be disabled? double [] norm_table = null; // first try, then make save to properties with cold/hot if (renormalize) { if (lwir_autorange) { double rel_low = colorProcParameters.lwir_low; double rel_high = colorProcParameters.lwir_high; if (!Double.isNaN(ref_scene.getLwirOffset())) { rel_low -= ref_scene.getLwirOffset(); rel_high -= ref_scene.getLwirOffset(); double rel_low; double rel_high; boolean force_min_max = true; if (!tex_um && !force_min_max) { // for UM will use min/max rel_low = colorProcParameters.lwir_low; rel_high = colorProcParameters.lwir_high; if (!Double.isNaN(parameter_scene.getLwirOffset())) { // ref_scene or parameter_scene? Or both? rel_low -= parameter_scene.getLwirOffset(); rel_high -= parameter_scene.getLwirOffset(); } } else { // for UM need to calculate min and max (probably OK for non-UM too !) double [] minmax = QuadCLTCPU.getMinMaxTextures( faded_textures ); //double [][][] textures // [nslices][nchn][i] rel_low = minmax[0]; rel_high = minmax[1]; } double [] cold_hot = QuadCLTCPU.autorangeTextures( faded_textures, // double [][][] textures, // [nslices][nchn][i] Loading @@ -1133,15 +1201,41 @@ public class TexturedModel { rel_high, // double hard_hot, // matches data, DC (this.lwir_offset) subtracted colorProcParameters.lwir_too_cold, // double too_cold, // pixels per image colorProcParameters.lwir_too_hot, // double too_hot, // pixels per image 1024); // int num_bins) if (cold_hot != null) { if (!Double.isNaN(ref_scene.getLwirOffset())) { cold_hot[0] += ref_scene.getLwirOffset(); cold_hot[1] += ref_scene.getLwirOffset(); tex_hist_bins); // int num_bins) if ((cold_hot != null) && !tex_um && !force_min_max) { if (!Double.isNaN(parameter_scene.getLwirOffset())) { cold_hot[0] += parameter_scene.getLwirOffset(); cold_hot[1] += parameter_scene.getLwirOffset(); } } parameter_scene.setColdHot(cold_hot); // will be used for shifted images and for texture tiles } else if (tex_um && tex_um_fixed) { // apply fixed range, but for UM only (what about RGB?) parameter_scene.setColdHot(-0.5*tex_um_range, 0.5*tex_um_range); } ref_scene.setColdHot(cold_hot); // will be used for shifted images and for texture tiles if (tex_hist_norm) { // will normalize (0..1) keeping cold_hot to apply during rendering // last norm_table element is <=1.0, first >=0; norm_table = QuadCLTCPU.getHistogramNormalization( faded_textures, // double [][][] textures, // [nslices][nchn][i] parameter_scene.getColdHot(), // double [] minmax, tex_hist_bins, // int num_bins, tex_hist_segments, //int num_nodes tex_hist_amount); //double hist_normalize_amount // 1.0 - full } } if (tex_hist_norm && (norm_table != null)) { // apply histogram normalization double [] cold_hot = parameter_scene.getColdHot(); // used in linearStackToColor double [] inverted_table = QuadCLTCPU.invertHistogramNormalization( norm_table, // double [] direct_table, // last is <1.0, first > 0 tex_hist_bins); // int num_bins) QuadCLTCPU.applyTexturesNormHist( faded_textures, // final double [][][] textures, // [nslices][nchn][i] cold_hot, // final double [] min_max, inverted_table); // final double [] inv_table) } if (debug_level > -1) { double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; String [] dbg_titles = new String[dbg_textures.length]; Loading Loading @@ -1182,57 +1276,28 @@ public class TexturedModel { } } double [] minmax = parameter_scene.getColdHot(); // used in linearStackToColor ImagePlus [] imp_tex = new ImagePlus[num_slices]; EyesisCorrectionParameters.CorrectionParameters correctionsParameters = ref_scene.correctionsParameters; for (int nslice = 0; nslice < num_slices; nslice++) { // See how textures where processed with alpha /* // Prepare 4-channel images ImagePlus [] imps_RGB = new ImagePlus[iclt_fimg.length]; for (int ncam = 0; ncam < iclt_fimg.length; ncam++) if (iclt_fimg[ncam] != null){ String title=String.format("%s%s-%02d",image_name, sAux(), ncam); imps_RGB[ncam] = linearStackToColor( // probably no need to separate and process the second half with quadCLT_aux (!) clt_parameters, colorProcParameters, rgbParameters, String title=String.format("%s-texture-%02d",ref_scene.getImageName(), nslice); imp_tex[nslice] = QuadCLTCPU.linearStackToColorLWIR( clt_parameters, // CLTParameters clt_parameters, tex_palette, // int lwir_palette, // <0 - do not convert minmax, // double [] minmax, title, // String name, "-D"+clt_parameters.disparity, //String suffix, // such as disparity=... toRGB, // does not work here? !correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result false, // true, // boolean saveShowIntermediate, // save/show if set globally false, // boolean saveShowFinal, // save/show result (color image?) iclt_fimg[ncam], out_width, out_height, 1.0, // scaleExposures[iAux][iSubCam], // double scaleExposure, // is it needed? -1); // debugLevel ); } // combine to a sliced color image int [] slice_seq = {0,1,3,2}; //clockwise if (imps_RGB.length > 4) { slice_seq = new int [imps_RGB.length]; for (int i = 0; i < slice_seq.length; i++) { slice_seq[i] = i; } } int width = imps_RGB[0].getWidth(); int height = imps_RGB[0].getHeight(); ImageStack array_stack=new ImageStack(width,height); for (int i = 0; i<slice_seq.length; i++) if (imps_RGB[slice_seq[i]] != null){ array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels()); } ImagePlus imp_stack = new ImagePlus(image_name+sAux()+suffix, array_stack); imp_stack.getProcessor().resetMinAndMax(); return imp_stack; */ // convert to color or apply UM, "", // String suffix, // such as disparity=... tex_color, // boolean toRGB, faded_textures[nslice], // double [][] texture_data, tilesX * transform_size, // int width, // int tilesX, tilesY * transform_size, // int height, // int tilesY, debug_level); // int debugLevel ) // Add synthetic mesh only with higher resolution? or just any by a specified period?what king of mesh - vertical random, ... // Split and save as png } // Process accumulated textures: average, apply borders, convert to color or apply UM, add synthetic mesh, ... return null; // ImagePlus[] ? with alpha, to be split into png and saved with alpha. return imp_tex; // ImagePlus[] ? with alpha, to be split into png and saved with alpha. } Loading