Commit 9b0ad10d authored by Andrey Filippov's avatar Andrey Filippov

Tiff writer, fixed bug in Z interpolation in plane render

parent beaa0851
......@@ -481,6 +481,7 @@ public class CLTParameters {
public double gmap_discard_rdisp = 0.02; // discard above/below this fraction of average height
public double gmap_pix_size = 0.005; // hdr_x0y0, // in meters
public int gmap_max_image_width = 4000; // 3200; // increase pixel size as a power of 2 until image fits
public double gmap_min_sfm = 10.0; // minimal SfM gain to keep ground map
public boolean gmap_crop_empty = true;
public int gmap_crop_extra = 20;
public int [] gmap_tex_pals = {0,1,2};
......@@ -1626,6 +1627,7 @@ public class CLTParameters {
properties.setProperty(prefix+"gmap_discard_rdisp", this.gmap_discard_rdisp+""); // double
properties.setProperty(prefix+"gmap_pix_size", this.gmap_pix_size+""); // double
properties.setProperty(prefix+"gmap_max_image_width", this.gmap_max_image_width+""); // int
properties.setProperty(prefix+"gmap_min_sfm", this.gmap_min_sfm+""); // double
properties.setProperty(prefix+"gmap_crop_empty", this.gmap_crop_empty+""); // boolean
properties.setProperty(prefix+"gmap_crop_extra", this.gmap_crop_extra+""); // int
properties.setProperty(prefix+"gmap_tex_pals", CLTParameters.arr_to_str(this.gmap_tex_pals)); // int[]
......@@ -2644,6 +2646,7 @@ public class CLTParameters {
if (properties.getProperty(prefix+"gmap_discard_rdisp")!=null) this.gmap_discard_rdisp=Double.parseDouble(properties.getProperty(prefix+ "gmap_discard_rdisp"));
if (properties.getProperty(prefix+"gmap_pix_size")!=null) this.gmap_pix_size=Double.parseDouble(properties.getProperty(prefix+ "gmap_pix_size"));
if (properties.getProperty(prefix+"gmap_max_image_width")!=null) this.gmap_max_image_width=Integer.parseInt(properties.getProperty(prefix+ "gmap_max_image_width"));
if (properties.getProperty(prefix+"gmap_min_sfm")!=null) this.gmap_min_sfm=Double.parseDouble(properties.getProperty(prefix+ "gmap_min_sfm"));
if (properties.getProperty(prefix+"gmap_crop_empty")!=null) this.gmap_crop_empty=Boolean.parseBoolean(properties.getProperty(prefix+ "gmap_crop_empty"));
if (properties.getProperty(prefix+"gmap_crop_extra")!=null) this.gmap_crop_extra=Integer.parseInt(properties.getProperty(prefix+ "gmap_crop_extra"));// int
if (properties.getProperty(prefix+"gmap_tex_pals")!=null) this.gmap_tex_pals=CLTParameters.str_to_iarr(properties.getProperty(prefix+"gmap_tex_pals"));
......@@ -3908,6 +3911,8 @@ public class CLTParameters {
"Rendered absolute pixel size in meters.");
gd.addNumericField("Maximal rendered image width", this.gmap_max_image_width, 0,3,"",
"Maximal output image size in pixels. Increase pixel size in the power-of-two ratio if calculated image width exceeds this value.");
gd.addNumericField("Minimal SfM gain", this.gmap_min_sfm, 4,6,"x",
"Minimal SfM gain to keep ground map, lower makes texture transparent.");
gd.addCheckbox ("Crop empty map areas", this.gmap_crop_empty, // true; // enable change FG pixel to opaque from transparent
"Crop the map output from four directions while only undefined pixels are removed.");
gd.addNumericField("Crop maps extra", this.gmap_crop_extra, 0,3,"pix", // minimal neighbors to keep alpha
......@@ -3915,7 +3920,6 @@ public class CLTParameters {
gd.addStringField ("LWIR palettes to render the maps", CLTParameters.arr_to_str(this.gmap_tex_pals), 40,
"Enter space-separated list of the palette numbers, such as, such as '0 1 2'");
gd.addMessage ("Earlier 3D generation parameters");
gd.addCheckbox ("Generate background (infinity) image for 3D (not needed for view down)", this.generate_bg);
gd.addCheckbox ("Show generated textures", this.show_textures);
......@@ -5125,13 +5129,12 @@ public class CLTParameters {
this.gmap_discard_high= gd.getNextNumber();
this.gmap_discard_adisp= gd.getNextNumber();
this.gmap_discard_rdisp= gd.getNextNumber();
gmap_pix_size= gd.getNextNumber();
this.gmap_pix_size= gd.getNextNumber();
this.gmap_max_image_width= (int) gd.getNextNumber();
this.gmap_min_sfm= gd.getNextNumber();
this.gmap_crop_empty= gd.getNextBoolean();
this.gmap_crop_extra= (int) gd.getNextNumber();
this.gmap_tex_pals = CLTParameters.str_to_iarr(gd.getNextString());
this.generate_bg= gd.getNextBoolean();
this.show_textures= gd.getNextBoolean();
this.debug_filters= gd.getNextBoolean();
......
......@@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
......@@ -58,6 +59,7 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.elphel.imagej.correction.Eyesis_Correction;
import com.elphel.imagej.ims.Did_ins;
import com.elphel.imagej.tileprocessor.QuadCLTCPU;
//import org.apache.log4j.Logger;
......@@ -306,9 +308,20 @@ the type of pixel data in this file getPixelType()
boolean imageJTags,
int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{
double [] lla = { 49.9476514222895,28.5547846609957,323.750316821841};
LocalDateTime dt = Did_ins.getLocalDateTime(2286, 491072.634526699);
double pix_in_meters = 0.01;
if (imp.getType()==ImagePlus.COLOR_RGB) { // 4*8 bit - type = 0
if (debugLevel>1) System.out.println("Saving 8-bit TIFF with alpha-channel: "+path); // is it possible to just add alpha to high bytes?
ElphelTiffWriter.saveTiffARGB32(imp, path, imageJTags, debugLevel);
ElphelTiffWriter.saveTiffARGB32(
imp,
path,
lla, // double [] lla, // latitude, longitude, altitude (or null)
dt, // LocalDateTime dt, // local date/time or null
pix_in_meters, //double pix_in_meters, // resolution or Double.NaN
imageJTags,
debugLevel);
// saveTiffARGB32(imp, path, imageJTags, debugLevel);
return;
} else if (imp.getStackSize()==4) {
......@@ -341,7 +354,14 @@ the type of pixel data in this file getPixelType()
if (debugLevel>1) System.out.println("Saving 8-bit RGBA TIFF with alpha-channel: "+path); // is it possible to just add alpha to high bytes?
ElphelTiffWriter.saveTiffARGB32(imp_rgb, path, imageJTags, debugLevel);
ElphelTiffWriter.saveTiffARGB32(
imp_rgb,
path,
lla, // double [] lla, // latitude, longitude, altitude (or null)
dt, // LocalDateTime dt, // local date/time or null
pix_in_meters, //double pix_in_meters, // resolution or Double.NaN
imageJTags,
debugLevel);
// saveTiffARGB32(imp_rgb, path, imageJTags, debugLevel);
return;
}
......
......@@ -5351,6 +5351,11 @@ public class OpticalFlow {
quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...)
null, // String path, // full name with extension or w/o path to use x3d directory
debugLevel+1);
} else {
if (debugLevel> -3) {
System.out.println("Failed to perform attitude correction with QuaternionLma.");
}
}
}
......@@ -5946,7 +5951,6 @@ public class OpticalFlow {
int [] whs = new int[3];
double [] x0y0 = new double[2];
if (export3d) { //combo_dsn_final had strength 1.0e-4 where it should not? Reset it?
boolean ok_3d = TexturedModel.output3d( // quadCLTs have same image name, and everything else
clt_parameters, // CLTParameters clt_parameters,
colorProcParameters, // ColorProcParameters colorProcParameters,
......
......@@ -696,6 +696,7 @@ public class QuadCLTCPU {
System.out.println("getGroundIns(): no INS data available.");
return null;
}
double min_sfm_gain = clt_parameters.gmap_min_sfm ; //10.0 minimal SfM gain to keep ground map
double [] ims_ortho = clt_parameters.imp.ims_ortho;
double [] ims_mount_atr = clt_parameters.imp.getImsMountATR(); // converts to radians
double [] ims_mount_xyz = clt_parameters.imp.ims_mount_xyz; // not yet used
......@@ -721,6 +722,14 @@ public class QuadCLTCPU {
}
double [] scene_abs_atr_enu = Imx5.quatToCamAtr(cam_quat_enu);
double [][] dls = getDLS();
if ((min_sfm_gain> 0) && (dls[3] != null)) {
dls[2]=dls[2].clone();
for (int i = 0; i <dls[2].length; i++) {
if (dls[3][i] < min_sfm_gain) {
dls[2][i] = 0; // zero strength if low SfM gain
}
}
}
if (dls==null) {
return null;
}
......@@ -941,15 +950,16 @@ public class QuadCLTCPU {
public double [][] getDLS(){ // get disparity, disparity_lma, strength
public double [][] getDLS(){ // get disparity, disparity_lma, strength, sfm_gain
if (dsi == null) {
// System.out.println("dsi== null, use spawnQuadCLT(), restoreFromModel(), ... to set it");
return null;
}
double [][] dls = new double[3][];
double [][] dls = new double[4][];
dls[0] = dsi[isAux()? TwoQuadCLT.DSI_DISPARITY_AUX : TwoQuadCLT.DSI_DISPARITY_MAIN];
dls[1] = dsi[isAux()? TwoQuadCLT.DSI_DISPARITY_AUX_LMA : TwoQuadCLT.DSI_DISPARITY_MAIN_LMA];
dls[2] = dsi[isAux()? TwoQuadCLT.DSI_STRENGTH_AUX : TwoQuadCLT.DSI_STRENGTH_MAIN];
dls[3] = dsi[isAux()? TwoQuadCLT.DSI_SFM_GAIN_AUX : TwoQuadCLT.DSI_SFM_GAIN_MAIN];
return dls;
}
......
......@@ -2464,6 +2464,7 @@ public class TexturedModel {
final double discard_rdisp = clt_parameters.gmap_discard_rdisp ; //0.02; // discard above/below this fraction of average height
final double pix_size = clt_parameters.gmap_pix_size ; //0.005; // hdr_x0y0, // in meters
final int max_image_width = clt_parameters.gmap_max_image_width ; //4000; // 3200; // increase pixel size as a power of 2 until image fits
final double min_sfm_gain = clt_parameters.gmap_min_sfm ; //10.0 minimal SfM gain to keep ground map
final boolean crop_empty = clt_parameters.gmap_crop_empty ; //true;
final int crop_extra = clt_parameters.gmap_crop_extra ; //20;
final int [] tex_pals = clt_parameters.gmap_tex_pals ; //{0,1,2};
......@@ -2559,7 +2560,7 @@ public class TexturedModel {
combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_LMA],
combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_STRENGTH]
};
double [] sfm_gain = (min_sfm_gain > 0.0) ? combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_SFM_GAIN] : null;
// currently conditionInitialDS() zeroes disparity for blue_sky. TODO: allow some FG over blue_sky?
// gets Blue Sky from scene.dsi , not from the file!
double [][] ds_fg = OpticalFlow.conditionInitialDS(
......@@ -2584,9 +2585,17 @@ public class TexturedModel {
dls_bg, // double [][] dls
scenes[ref_index], // QuadCLT scene,
debugLevel); // int debug_level)
if (sfm_gain != null) {
for (int i = 0; i < ds_fg[0].length; i++) if (sfm_gain[i] < min_sfm_gain){
ds_fg[0][i] = Double.NaN;
ds_bg[0][i] = Double.NaN;
ds_fg[1][i] = 0.0;
ds_bg[1][i] = 0.0;
}
}
double[][] ds_fg_bg = {ds_fg[0], ds_bg[0].clone()};
double[][] ss_fg_bg = {ds_fg[1], ds_bg[1]};
if (show_bs_debug) {
String [] dbg_titles = {"FG","BG","BS"};
double [][] dbg_img = {ds_fg_bg[0], ds_fg_bg[1],combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_BLUE_SKY].clone()};
......@@ -2612,10 +2621,10 @@ public class TexturedModel {
}
for (int i = 0; i < ss_fg_bg[0].length; i++) {
if (Double.isNaN(dls_fg[1][i])){
ss_fg_bg[0][i] = 0.0001;
ss_fg_bg[0][i] = Math.min(ss_fg_bg[0][i],0.0001); // do not increase if it was already 0
}
if (Double.isNaN(dls_bg[1][i])){
ss_fg_bg[1][i] = 0.0001;
ss_fg_bg[1][i] = Math.min(ss_fg_bg[1][i],0.0001); // do not increase if it was already 0
}
}
}
......@@ -2979,7 +2988,7 @@ public class TexturedModel {
}
// if (imp_textures[nslice] != null)
} // for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (render_hdr) {
if (render_hdr) { //
int [] hdr_whs = new int[3];
double [] hdr_x0y0 = new double[2];
double [][] to_ground_xyzatr = scenes[ref_index].getGround(
......
......@@ -254,6 +254,7 @@ public class Render3D {
if ((tri_meshes == null) || tri_meshes.isEmpty() || (tri_meshes.get(0).getTexturePixels() == null)) {
return null;
}
final boolean export_z = true;
final int dbg_ipix=1673752;
// get total number of triangles
int num_tri=0;
......@@ -276,7 +277,7 @@ public class Render3D {
System.out.println("Prepare to render "+num_tri+" triangles in "+num_mesh+" meshes");
}
final int z_index = tri_meshes.get(0).getTexturePixels().length;
final double [][] full_rendered = new double[z_index][out_width * out_height];
final double [][] full_rendered = new double[z_index+ (export_z? 1:0)][out_width * out_height];
int alpha_index = last_is_alpha ? (z_index - 1) : z_index;
for (int chn = 0; chn < alpha_index; chn++) {
Arrays.fill(full_rendered[chn], Double.NaN);
......@@ -361,12 +362,12 @@ public class Render3D {
double kx = dot2(d0p, orto2[0]);
double ky = dot2(d0p, orto2[1]);
// interpolate z
double z_interp = tri_out2[0][2] + kx * (tri_out2[1][2]-tri_out2[0][2]) + ky*(tri_out2[1][2]-tri_out2[0][2]);
double z_interp = tri_out2[0][2] +
kx * (tri_out2[1][2]-tri_out2[0][2]) +
ky * (tri_out2[2][2]-tri_out2[0][2]);
if ((rend[ipix] != null ) && (rend[ipix][z_index] < z_interp)) {
continue;
}
// Get corresponding texture coordinates
double text_x = tri_text2[0][0] + kx * t01[0] + ky*t02[0]; // texture relative coordinates (0,1)
double text_y = tri_text2[0][1] + kx * t01[1] + ky*t02[1]; // y - up!
......@@ -426,7 +427,7 @@ public class Render3D {
for (int sub_render = 0; sub_render < rendered.length; sub_render++) if (rendered[sub_render][indx] != null){
if (!(rendered[sub_render][indx][z_index] <= z)) { // OK previous NaN
z = rendered[sub_render][indx][z_index];
for (int chn = 0; chn < z_index; chn++) {
for (int chn = 0; chn < full_rendered.length; chn++) { // z_index; chn++) {
full_rendered[chn][indx] = rendered[sub_render][indx][chn];
}
}
......@@ -549,12 +550,12 @@ public class Render3D {
double kx = dot2(d0p, orto2[0]);
double ky = dot2(d0p, orto2[1]);
// interpolate z
double z_interp = tri_out2[0][2] + kx * (tri_out2[1][2]-tri_out2[0][2]) + ky*(tri_out2[1][2]-tri_out2[0][2]);
double z_interp = tri_out2[0][2] +
kx * (tri_out2[1][2]-tri_out2[0][2]) +
ky * (tri_out2[2][2]-tri_out2[0][2]);
if ((rend[ipix] != null ) && (rend[ipix][z_index] < z_interp)) {
continue;
}
// Get corresponding texture coordinates
double text_x = tri_text2[0][0] + kx * t01[0] + ky*t02[0]; // texture relative coordinates (0,1)
double text_y = tri_text2[0][1] + kx * t01[1] + ky*t02[1]; // y - up!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment