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

Tiff writer, fixed bug in Z interpolation in plane render

parent beaa0851
...@@ -480,7 +480,8 @@ public class CLTParameters { ...@@ -480,7 +480,8 @@ public class CLTParameters {
public double gmap_discard_adisp = 0.2; // discard above/below this fraction of average height public double gmap_discard_adisp = 0.2; // discard above/below this fraction of average height
public double gmap_discard_rdisp = 0.02; // discard above/below this fraction of average height 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 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 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 boolean gmap_crop_empty = true;
public int gmap_crop_extra = 20; public int gmap_crop_extra = 20;
public int [] gmap_tex_pals = {0,1,2}; public int [] gmap_tex_pals = {0,1,2};
...@@ -1626,6 +1627,7 @@ public class CLTParameters { ...@@ -1626,6 +1627,7 @@ public class CLTParameters {
properties.setProperty(prefix+"gmap_discard_rdisp", this.gmap_discard_rdisp+""); // double 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_pix_size", this.gmap_pix_size+""); // double
properties.setProperty(prefix+"gmap_max_image_width", this.gmap_max_image_width+""); // int 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_empty", this.gmap_crop_empty+""); // boolean
properties.setProperty(prefix+"gmap_crop_extra", this.gmap_crop_extra+""); // int 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[] properties.setProperty(prefix+"gmap_tex_pals", CLTParameters.arr_to_str(this.gmap_tex_pals)); // int[]
...@@ -2644,6 +2646,7 @@ public class CLTParameters { ...@@ -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_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_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_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_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_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")); 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 { ...@@ -3908,6 +3911,8 @@ public class CLTParameters {
"Rendered absolute pixel size in meters."); "Rendered absolute pixel size in meters.");
gd.addNumericField("Maximal rendered image width", this.gmap_max_image_width, 0,3,"", 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."); "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 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."); "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 gd.addNumericField("Crop maps extra", this.gmap_crop_extra, 0,3,"pix", // minimal neighbors to keep alpha
...@@ -3915,7 +3920,6 @@ public class CLTParameters { ...@@ -3915,7 +3920,6 @@ public class CLTParameters {
gd.addStringField ("LWIR palettes to render the maps", CLTParameters.arr_to_str(this.gmap_tex_pals), 40, 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'"); "Enter space-separated list of the palette numbers, such as, such as '0 1 2'");
gd.addMessage ("Earlier 3D generation parameters"); gd.addMessage ("Earlier 3D generation parameters");
gd.addCheckbox ("Generate background (infinity) image for 3D (not needed for view down)", this.generate_bg); gd.addCheckbox ("Generate background (infinity) image for 3D (not needed for view down)", this.generate_bg);
gd.addCheckbox ("Show generated textures", this.show_textures); gd.addCheckbox ("Show generated textures", this.show_textures);
...@@ -5125,13 +5129,12 @@ public class CLTParameters { ...@@ -5125,13 +5129,12 @@ public class CLTParameters {
this.gmap_discard_high= gd.getNextNumber(); this.gmap_discard_high= gd.getNextNumber();
this.gmap_discard_adisp= gd.getNextNumber(); this.gmap_discard_adisp= gd.getNextNumber();
this.gmap_discard_rdisp= 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_max_image_width= (int) gd.getNextNumber();
this.gmap_min_sfm= gd.getNextNumber();
this.gmap_crop_empty= gd.getNextBoolean(); this.gmap_crop_empty= gd.getNextBoolean();
this.gmap_crop_extra= (int) gd.getNextNumber(); this.gmap_crop_extra= (int) gd.getNextNumber();
this.gmap_tex_pals = CLTParameters.str_to_iarr(gd.getNextString()); this.gmap_tex_pals = CLTParameters.str_to_iarr(gd.getNextString());
this.generate_bg= gd.getNextBoolean(); this.generate_bg= gd.getNextBoolean();
this.show_textures= gd.getNextBoolean(); this.show_textures= gd.getNextBoolean();
this.debug_filters= gd.getNextBoolean(); this.debug_filters= gd.getNextBoolean();
......
...@@ -69,114 +69,42 @@ public class ElphelTiffWriter { ...@@ -69,114 +69,42 @@ public class ElphelTiffWriter {
public static void saveTiffARGB32( public static void saveTiffARGB32(
ImagePlus imp, ImagePlus imp,
String path, String path, // full path to save image
boolean imageJTags, double [] lla, // latitude, longitude, altitude (or null)
int debugLevel LocalDateTime dt, // local date/time or null
double pix_in_meters, // resolution or Double.NaN
boolean imageJTags, // later will use it to encode from properties
int debugLevel
) { ) {
// ImageWriter tiffWriter;
// ImageWriteParam tiffWriteParam;
IIOMetadata tiffStreamMetadata;
IIOMetadata primaryIFD;
BufferedImage bufferedImage = (BufferedImage) imp.getImage(); // properties=null
BufferedImage thumbnail;
File outputFile = new File(path); File outputFile = new File(path);
System.out.println("saveTiffARGB32(): will write to "+outputFile); if (debugLevel > 0) {
System.out.println("ElphelTiffWriter.saveTiffARGB32"); System.out.println("saveTiffARGB32(): will write to "+outputFile);
// Write only the primary IFD and image data. System.out.println("ElphelTiffWriter.saveTiffARGB32");
// Specify uncompressed output. }
ImageWriter tiffWriter = ImageIO.getImageWritersByFormatName("tiff").next(); ImageWriter tiffWriter = ImageIO.getImageWritersByFormatName("tiff").next();
ImageWriteParam tiffWriteParam = tiffWriter.getDefaultWriteParam(); ImageWriteParam tiffWriteParam = tiffWriter.getDefaultWriteParam();
// tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
// https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html
// tiffWriteParam.setCompressionType("Exif JPEG");
tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED); tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
// tiffWriteParam.setSourceSubsampling(param.getSourceXSubsampling(), param.getSourceYSubsampling(), param.getSubsamplingXOffset(), param.getSubsamplingYOffset()); /* ImagePlus image removes alpha, so we need to create a new ARGB BufferedImage
// tiffWriteParam.setSourceRegion(param.getSourceRegion()); * and copy data (it is correct in imp.getImage() */
// tiffWriteParam.setSourceBands(param.getSourceBands()); BufferedImage bufferedImage = (BufferedImage) imp.getImage(); // properties=null
/*
* https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/javax/imageio/metadata/doc-files/tiff_metadata.html
Setting up the image metadata to write to a TIFF stream may be simplified by using
the TIFFDirectory class which represents a TIFF IFD. A field in a TIFF IFD is represented
by an instance of TIFFField. For each field to be written a TIFFField may be added to
the TIFFDirectory and the latter converted to an IIOMetadata object by invoking
TIFFDirectory.getAsMetadata. The IIOMetadata object so obtained may then be passed to
the TIFF writer.
ImageTypeSpecifier
ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel)
Constructs an ImageTypeSpecifier directly from a ColorModel and a SampleModel.
static long computeImageSize(RenderedImage image) {
long bits = 0;
final int bands = image.getSampleModel().getNumBands();
for (int i = 0; i < bands; i++) {
bits += image.getSampleModel().getSampleSize(i);
}
return (long) Math.ceil(bits / 8) * image.getWidth() * image.getHeight();
}
void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)
Sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) and default sRGB color space, into a portion of the image data.
*/
// Raster raster = bufferedImage.getData(); // use pixels from IJ
BufferedImage bufferedImageAlpha = new BufferedImage( BufferedImage bufferedImageAlpha = new BufferedImage(
bufferedImage.getWidth(), bufferedImage.getWidth(),
bufferedImage.getHeight(), bufferedImage.getHeight(),
BufferedImage.TYPE_INT_ARGB BufferedImage.TYPE_INT_ARGB);
);
int [] ipixels = (int[])imp.getProcessor().getPixels(); int [] ipixels = (int[])imp.getProcessor().getPixels();
final int[] bia_as_arr = ( (DataBufferInt) bufferedImageAlpha.getRaster().getDataBuffer() ).getData(); final int[] bia_as_arr = ( (DataBufferInt) bufferedImageAlpha.getRaster().getDataBuffer() ).getData();
System.arraycopy(ipixels, 0, bia_as_arr, 0, bia_as_arr.length); System.arraycopy(ipixels, 0, bia_as_arr, 0, bia_as_arr.length);
/*
bufferedImageAlpha.setRGB( // slow
0, // int startX,
0, // int startY,
bufferedImage.getWidth(), // int w,
bufferedImage.getHeight(), // int h,
ipixels, // int[] rgbArray,
0, // int offset,
bufferedImage.getWidth()); // int scansize);
*/
// bufferedImageAlpha.setData(raster);
//BufferedImage.TYPE_INT_ARGB
// ColorModel colorModel = ColorModel.getRGBdefault();
// SampleModel samleModel = bufferedImage.getSampleModel();
// ImageTypeSpecifier imageType = ImageTypeSpecifier.createFromRenderedImage(bufferedImage);
ImageTypeSpecifier imageType = ImageTypeSpecifier.createFromRenderedImage(bufferedImageAlpha); ImageTypeSpecifier imageType = ImageTypeSpecifier.createFromRenderedImage(bufferedImageAlpha);
IIOMetadata imageMetadata = tiffWriter.getDefaultImageMetadata(imageType, tiffWriteParam); IIOMetadata imageMetadata = tiffWriter.getDefaultImageMetadata(imageType, tiffWriteParam);
// just for testing: // just for testing:
double [] lla = { 49.9476514222895,28.5547846609957,323.750316821841};
LocalDateTime dt = Did_ins.getLocalDateTime(2286, 491072.634526699);
double pix_in_meters = 0.01;
int cm_dig_after = 9; int cm_dig_after = 9;
// Here is a way adding tag sets through TIFFDirectory
/* /*
ExifGPSTagSet exif_tag_set = ExifGPSTagSet.getInstance();
TIFFTagSet [] tag_sets = {ExifGPSTagSet.getInstance()} ;
ExifParentTIFFTagSet eptts = ExifParentTIFFTagSet.getInstance();
TIFFDirectory gps_directory = new TIFFDirectory(
tag_sets, eptts.getTag(
ExifParentTIFFTagSet.TAG_GPS_INFO_IFD_POINTER));
TIFFTagSet tag_set = ExifGPSTagSet.getInstance();
TIFFField gps_ifd = null;
// int df = TIFFField.TIFF_IFD_POINTER; // 13
gps_ifd = new TIFFField(
eptts.getTag(
ExifParentTIFFTagSet.TAG_GPS_INFO_IFD_POINTER), // 'ExifIFDPointer', // TIFFTag tag,
13, // TIFFField.TIFF_IFD_POINTER, // int type,
(long) 0, // long offset,
(TIFFDirectory) gps_directory); // TIFFDirectory dir)
directory.addTIFFField(gps_ifd);
directory.addTagSet(tag_set); // ExifGPSTagSet.getInstance());
*/
/* */
TIFFDirectory directory = null; TIFFDirectory directory = null;
try { try {
directory = TIFFDirectory.createFromMetadata(imageMetadata); directory = TIFFDirectory.createFromMetadata(imageMetadata);
...@@ -191,122 +119,41 @@ Sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) a ...@@ -191,122 +119,41 @@ Sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) a
directory.addTagSet(eptts); // ExifParentTIFFTagSet.getInstance()); directory.addTagSet(eptts); // ExifParentTIFFTagSet.getInstance());
//ExifGPSTagSet //ExifGPSTagSet
imageMetadata = directory.getAsMetadata(); imageMetadata = directory.getAsMetadata();
/* */ */
IIOMetadataNode root_new = (IIOMetadataNode) imageMetadata.getAsTree(TIFF_METADATA_FORMAT);//? IIOMetadataNode root_new = (IIOMetadataNode) imageMetadata.getAsTree(TIFF_METADATA_FORMAT);//?
if (debugLevel > 0) {System.out.println("\n=== root_new ===:");DumpImageMetadata.displayMetadataNode(root_new, 1);}
System.out.println("\n=== root_new ===:");
DumpImageMetadata.displayMetadataNode(root_new, 1);
// createGpsMetadata(double [] lla, LocalDateTime dt)
IIOMetadataNode ifd = (IIOMetadataNode) root_new.getFirstChild(); IIOMetadataNode ifd = (IIOMetadataNode) root_new.getFirstChild();
String ifd_attr = ifd.getAttribute("tagSets"); ifd.setAttribute("tagSets",
// set it to ifd_attr "javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.ExifGPSTagSet,javax.imageio.plugins.tiff.ExifParentTIFFTagSet" (id=187) "javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.ExifGPSTagSet,javax.imageio.plugins.tiff.ExifParentTIFFTagSet");
// remove directory above and addTagSet if ((lla != null) || (dt!=null)) {
IIOMetadataNode gpsRootNode = createGpsMetadata(lla, dt); IIOMetadataNode gpsRootNode = createGpsMetadata(lla, dt);
/* if (debugLevel > 0) {System.out.println("\n=== gpsRootNode ===:");DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);}
IIOMetadataNode gpsRootNode = new IIOMetadataNode("TIFFIFD"); ifd.appendChild(gpsRootNode);
gpsRootNode.setAttribute("parentTagNumber", "34853"); }
gpsRootNode.setAttribute("parentTagName", "GPSInfoIFDPointer"); addResolutionMetadata(ifd,pix_in_meters,cm_dig_after); // NOP if pix_in_meters is NaN
gpsRootNode.setAttribute("tagSets", "javax.imageio.plugins.tiff.ExifGPSTagSet");
IIOMetadataNode childNode = new IIOMetadataNode(TIFF_FIELD_TAG);
childNode.setAttribute("number", "1");
childNode.setAttribute("name", "GPSLatitudeRef");
IIOMetadataNode asciiNode = new IIOMetadataNode(TIFF_ASCIIS_TAG);
IIOMetadataNode childAsciiNode = new IIOMetadataNode(TIFF_ASCII_TAG);
childAsciiNode.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, "N");
asciiNode.appendChild(childAsciiNode);
childNode.appendChild(asciiNode);
gpsRootNode.appendChild(childNode);
*/
System.out.println("\n=== gpsRootNode ===:");
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
addResolutionMetadata(ifd,pix_in_meters,cm_dig_after);
ifd.appendChild(gpsRootNode);
System.out.println("\n=== ifd ===:");
DumpImageMetadata.displayMetadataNode(ifd, 1);
/*
IIOMetadataNode childNode = new IIOMetadataNode(FileConstants.TIFF_FIELD_TAG);
childNode.setAttribute(FileConstants.TIFF_FIELD_NUMBER_ATTRIBUTE, "1");
childNode.setAttribute(FileConstants.TIFF_FIELD_NAME_ATTRIBUTE, "GPSLatitudeRef");
IIOMetadataNode asciiNode = new IIOMetadataNode("TIFFAsciis");
IIOMetadataNode childAsciiNode = new IIOMetadataNode("TIFFAscii");
childAsciiNode.setAttribute(FileConstants.TIFF_FIELD_VALUE_ATTRIBUTE, "N");
asciiNode.appendChild(childAsciiNode);
childNode.appendChild(asciiNode);
gpsRootNode.appendChild(childNode);
ifd.appendChild(gpsRootNode);
//Update metadata with new tree
metadata.setFromTree(FileConstants.TIFF_METADATA_FORMAT, root);
ImageOutputStream outstr = ImageIO.createImageOutputStream(writeTarget);
writer.setOutput(outstr);
//Write the image
IIOImage img = new IIOImage(renderedImage, Collections.<BufferedImage> emptyList(), metadata);
writer.write(img);
outstr.close();
public static String TIFF_METADATA_FORMAT = "javax_imageio_tiff_image_1.0";
public static String TIFF_FIELD_TAG = "TIFFField";
public static String TIFF_ASCIIS_TAG = "TIFFAsciis";
public static String TIFF_ASCII_TAG = "TIFFAscii";
public static String TIFF_RATIONALS_TAG = "TIFFRationals";
public static String TIFF_RATIONAL_TAG = "TIFFRational";
public static String TIFF_FIELD_VALUE_ATTRIBUTE = "value";
*/
// imageMetadata.appendChild(dimension);
//// IIOMetadataNode root_dimension = new IIOMetadataNode(TIFF_METADATA_FORMAT); // IIOMetadataFormatImpl.standardMetadataFormatName); if (debugLevel > 0) {
// root_dimension.appendChild(dimension); System.out.println("\n=== ifd ===:");DumpImageMetadata.displayMetadataNode(ifd, 1);
//// root_dimension.appendChild(root_new); System.out.println("\n=== root_new ===:"); DumpImageMetadata.displayMetadataNode(root_new, 1);
//// System.out.println("\n=== root_new ===:"); // should have 2 tagSets, but has only baseline System.out.println("\n=== imageMetadata - before merge ===:"); DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
/* }
<javax_imageio_tiff_image_1.0>
<TIFFIFD tagSets='javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.GeoTIFFTagSet'>
*/
System.out.println("\n=== root_new ===:");
DumpImageMetadata.displayMetadataNode(root_new, 1);
System.out.println("\n=== imageMetadata - before merge ===:");
DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
// lost GPS data after merge
try { try {
imageMetadata.mergeTree(TIFF_METADATA_FORMAT, root_new); // dimension); // Root must have "TIFFIFD" child imageMetadata.mergeTree(TIFF_METADATA_FORMAT, root_new); // dimension); // Root must have "TIFFIFD" child
// imageMetadata.setFromTree(TIFF_METADATA_FORMAT, root_dimension); // dimension);
} catch (IIOInvalidTreeException e1) { } catch (IIOInvalidTreeException e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
return; return;
} }
System.out.println("\n=== imageMetadata - after merge ===:"); if (debugLevel > 0) {System.out.println("\n=== imageMetadata - after merge ===:");DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);}
DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
System.out.println();
FileImageOutputStream outputStream; FileImageOutputStream outputStream;
try { try {
outputStream = new FileImageOutputStream(outputFile); outputStream = new FileImageOutputStream(outputFile);
} catch (IOException e1) { } catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
return; return;
} }
tiffWriter.setOutput(outputStream); tiffWriter.setOutput(outputStream);
// IIOImage image_with_metadata = new IIOImage(bufferedImage, null, primaryIFD);
// IIOImage image_with_metadata = new IIOImage(bufferedImage, null, null);
IIOImage image_with_metadata = new IIOImage(bufferedImageAlpha, null, imageMetadata); IIOImage image_with_metadata = new IIOImage(bufferedImageAlpha, null, imageMetadata);
System.out.println(); System.out.println();
try { try {
...@@ -315,12 +162,11 @@ outstr.close(); ...@@ -315,12 +162,11 @@ outstr.close();
image_with_metadata, image_with_metadata,
tiffWriteParam); tiffWriteParam);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
System.out.println(); System.out.println();
} }
private static IIOMetadataNode createRationalDegrees(double d, int digits_after) { // 8 private static IIOMetadataNode createRationalDegrees(double d, int digits_after) { // 8
int denom = 1; int denom = 1;
for (int i = 0; i < digits_after; i++) denom *= 10; for (int i = 0; i < digits_after; i++) denom *= 10;
...@@ -380,7 +226,9 @@ outstr.close(); ...@@ -380,7 +226,9 @@ outstr.close();
return node_date; return node_date;
} }
private static IIOMetadataNode createGpsMetadata(double [] lla, LocalDateTime dt) { private static IIOMetadataNode createGpsMetadata(
double [] lla,
LocalDateTime dt) {
int ang_sec_after = 5; int ang_sec_after = 5;
int meters_after = 3; int meters_after = 3;
int seconds_after = 3; int seconds_after = 3;
...@@ -390,71 +238,62 @@ outstr.close(); ...@@ -390,71 +238,62 @@ outstr.close();
gpsRootNode.setAttribute("parentTagNumber", "34853"); gpsRootNode.setAttribute("parentTagNumber", "34853");
gpsRootNode.setAttribute("parentTagName", "GPSInfoIFDPointer"); gpsRootNode.setAttribute("parentTagName", "GPSInfoIFDPointer");
gpsRootNode.setAttribute("tagSets", "javax.imageio.plugins.tiff.ExifGPSTagSet"); gpsRootNode.setAttribute("tagSets", "javax.imageio.plugins.tiff.ExifGPSTagSet");
boolean lat_south = lla[0] < 0; boolean lat_south, long_west, alt_down;
double lat_abs = Math.abs(lla[0]); double lat_abs, long_abs, alt_abs;
boolean long_west = lla[1] < 0; if (lla != null) {
double long_abs = Math.abs(lla[1]); lat_south = lla[0] < 0;
boolean alt_down = lla[2] < 0; lat_abs = Math.abs(lla[0]);
double alt_abs = Math.abs(lla[2]); long_west = lla[1] < 0;
long_abs = Math.abs(lla[1]);
// Latitude alt_down = lla[2] < 0;
IIOMetadataNode node_lat_ref = new IIOMetadataNode(TIFF_FIELD_TAG); alt_abs = Math.abs(lla[2]);
node_lat_ref.setAttribute("number", "1"); // Latitude
node_lat_ref.setAttribute("name", "GPSLatitudeRef"); IIOMetadataNode node_lat_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
IIOMetadataNode node_lat_ref_asciis = new IIOMetadataNode(TIFF_ASCIIS_TAG); node_lat_ref.setAttribute("number", "1");
IIOMetadataNode node_lat_ref_ascii = new IIOMetadataNode(TIFF_ASCII_TAG); node_lat_ref.setAttribute("name", "GPSLatitudeRef");
node_lat_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, lat_south?"S":"N"); IIOMetadataNode node_lat_ref_asciis = new IIOMetadataNode(TIFF_ASCIIS_TAG);
node_lat_ref_asciis.appendChild(node_lat_ref_ascii); IIOMetadataNode node_lat_ref_ascii = new IIOMetadataNode(TIFF_ASCII_TAG);
node_lat_ref.appendChild(node_lat_ref_asciis); node_lat_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, lat_south?"S":"N");
gpsRootNode.appendChild(node_lat_ref); node_lat_ref_asciis.appendChild(node_lat_ref_ascii);
IIOMetadataNode node_lat = new IIOMetadataNode(TIFF_FIELD_TAG); node_lat_ref.appendChild(node_lat_ref_asciis);
node_lat.setAttribute("number", "2"); gpsRootNode.appendChild(node_lat_ref);
node_lat.setAttribute("name", "GPSLatitude"); IIOMetadataNode node_lat = new IIOMetadataNode(TIFF_FIELD_TAG);
node_lat.appendChild(createRationalDegrees(lat_abs, ang_sec_after)); node_lat.setAttribute("number", "2");
gpsRootNode.appendChild(node_lat); node_lat.setAttribute("name", "GPSLatitude");
node_lat.appendChild(createRationalDegrees(lat_abs, ang_sec_after));
System.out.println("\n=== gpsRootNode after latitude ===:"); gpsRootNode.appendChild(node_lat);
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1); // Longitude
IIOMetadataNode node_long_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
// Longitude node_long_ref.setAttribute("number", "3");
IIOMetadataNode node_long_ref = new IIOMetadataNode(TIFF_FIELD_TAG); node_long_ref.setAttribute("name", "GPSLongitudeRef");
node_long_ref.setAttribute("number", "3"); IIOMetadataNode node_long_ref_asciis = new IIOMetadataNode(TIFF_ASCIIS_TAG);
node_long_ref.setAttribute("name", "GPSLongitudeRef"); IIOMetadataNode node_long_ref_ascii = new IIOMetadataNode(TIFF_ASCII_TAG);
IIOMetadataNode node_long_ref_asciis = new IIOMetadataNode(TIFF_ASCIIS_TAG); node_long_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, long_west?"W":"E");
IIOMetadataNode node_long_ref_ascii = new IIOMetadataNode(TIFF_ASCII_TAG); node_long_ref_asciis.appendChild(node_long_ref_ascii);
node_long_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, long_west?"W":"E"); node_long_ref.appendChild(node_long_ref_asciis);
node_long_ref_asciis.appendChild(node_long_ref_ascii); gpsRootNode.appendChild(node_long_ref);
node_long_ref.appendChild(node_long_ref_asciis); IIOMetadataNode node_long = new IIOMetadataNode(TIFF_FIELD_TAG);
gpsRootNode.appendChild(node_long_ref); node_long.setAttribute("number", "4");
IIOMetadataNode node_long = new IIOMetadataNode(TIFF_FIELD_TAG); node_long.setAttribute("name", "GPSLongitude");
node_long.setAttribute("number", "4"); node_long.appendChild(createRationalDegrees(long_abs, ang_sec_after));
node_long.setAttribute("name", "GPSLongitude"); gpsRootNode.appendChild(node_long);
node_long.appendChild(createRationalDegrees(long_abs, ang_sec_after)); // Altitude
gpsRootNode.appendChild(node_long); IIOMetadataNode node_alt_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
node_alt_ref.setAttribute("number", "5");
System.out.println("\n=== gpsRootNode after longitude ===:"); node_alt_ref.setAttribute("name", "GPSAltitudeRef");
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1); IIOMetadataNode node_alt_ref_asciis = new IIOMetadataNode(TIFF_BYTES_TAG);
IIOMetadataNode node_alt_ref_ascii = new IIOMetadataNode(TIFF_BYTE_TAG);
// Altitude node_alt_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, alt_down?"1":"0");
IIOMetadataNode node_alt_ref = new IIOMetadataNode(TIFF_FIELD_TAG); node_alt_ref_ascii.setAttribute(TIFF_FIELD_DESCRIPTION_ATTRIBUTE, "Sea level");
node_alt_ref.setAttribute("number", "5"); node_alt_ref_asciis.appendChild(node_alt_ref_ascii);
node_alt_ref.setAttribute("name", "GPSAltitudeRef"); node_alt_ref.appendChild(node_alt_ref_asciis);
IIOMetadataNode node_alt_ref_asciis = new IIOMetadataNode(TIFF_BYTES_TAG); gpsRootNode.appendChild(node_alt_ref);
IIOMetadataNode node_alt_ref_ascii = new IIOMetadataNode(TIFF_BYTE_TAG); IIOMetadataNode node_alt = new IIOMetadataNode(TIFF_FIELD_TAG);
node_alt_ref_ascii.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, alt_down?"1":"0"); node_alt.setAttribute("number", "6");
node_alt_ref_ascii.setAttribute(TIFF_FIELD_DESCRIPTION_ATTRIBUTE, "Sea level"); node_alt.setAttribute("name", "GPSAltitude");
node_alt_ref_asciis.appendChild(node_alt_ref_ascii); node_alt.appendChild(createRationalMeters(alt_abs, meters_after));
node_alt_ref.appendChild(node_alt_ref_asciis); gpsRootNode.appendChild(node_alt);
gpsRootNode.appendChild(node_alt_ref); }
IIOMetadataNode node_alt = new IIOMetadataNode(TIFF_FIELD_TAG);
node_alt.setAttribute("number", "6");
node_alt.setAttribute("name", "GPSAltitude");
node_alt.appendChild(createRationalMeters(alt_abs, meters_after));
gpsRootNode.appendChild(node_alt);
System.out.println("\n=== gpsRootNode after altitude ===:");
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
if (dt != null) { if (dt != null) {
// Time // Time
IIOMetadataNode node_time = new IIOMetadataNode(TIFF_FIELD_TAG); IIOMetadataNode node_time = new IIOMetadataNode(TIFF_FIELD_TAG);
...@@ -462,8 +301,6 @@ outstr.close(); ...@@ -462,8 +301,6 @@ outstr.close();
node_time.setAttribute("name", "GPSTimeStamp"); node_time.setAttribute("name", "GPSTimeStamp");
node_time.appendChild(createTimeStamp(dt,seconds_after)); node_time.appendChild(createTimeStamp(dt,seconds_after));
gpsRootNode.appendChild(node_time); gpsRootNode.appendChild(node_time);
System.out.println("\n=== gpsRootNode after time ===:");
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
// Date // Date
IIOMetadataNode node_date = new IIOMetadataNode(TIFF_FIELD_TAG); IIOMetadataNode node_date = new IIOMetadataNode(TIFF_FIELD_TAG);
node_date.setAttribute("number", "29"); node_date.setAttribute("number", "29");
...@@ -471,31 +308,16 @@ outstr.close(); ...@@ -471,31 +308,16 @@ outstr.close();
node_date.appendChild(createDateStamp(dt)); node_date.appendChild(createDateStamp(dt));
gpsRootNode.appendChild(node_date); gpsRootNode.appendChild(node_date);
} }
System.out.println("\n=== gpsRootNode after date ===:");
DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
return gpsRootNode; return gpsRootNode;
} }
private static IIOMetadataNode createResolutionMetadataStd(double resolutionPixelInMeters) {
// String pixelSize = Double.toString(25.4 / resolutionDPI);
String pixelSize = Double.toString(1000*resolutionPixelInMeters); // millimeters
IIOMetadataNode horizontal = new IIOMetadataNode("HorizontalPixelSize");
horizontal.setAttribute("value", pixelSize);
IIOMetadataNode vertical = new IIOMetadataNode("VerticalPixelSize");
vertical.setAttribute("value", pixelSize);
IIOMetadataNode dimension = new IIOMetadataNode("Dimension");
dimension.appendChild(horizontal);
dimension.appendChild(vertical);
return dimension;
// IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
// root.appendChild(dimension);
// return root;
}
private static void addResolutionMetadata( private static void addResolutionMetadata(
IIOMetadataNode ifd, IIOMetadataNode ifd,
double resolutionPixelInMeters, double resolutionPixelInMeters, // NaN for undefined
int digits_after) { int digits_after) {
if (Double.isNaN(resolutionPixelInMeters)) {
return;
}
int denom = 1; int denom = 1;
for (int i = 0; i < digits_after; i++) denom *= 10; for (int i = 0; i < digits_after; i++) denom *= 10;
int fppcm = (int) Math.round(denom * 0.01/resolutionPixelInMeters); // pixels per cm int fppcm = (int) Math.round(denom * 0.01/resolutionPixelInMeters); // pixels per cm
...@@ -532,41 +354,6 @@ outstr.close(); ...@@ -532,41 +354,6 @@ outstr.close();
ifd.appendChild(node_y_resolution); ifd.appendChild(node_y_resolution);
} }
/*
*
IIOMetadataNode node_rationals = new IIOMetadataNode(TIFF_RATIONALS_TAG);
IIOMetadataNode node_hrs = new IIOMetadataNode(TIFF_RATIONAL_TAG);
node_hrs.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, dt.getHour()+"/1");
IIOMetadataNode node_mins = new IIOMetadataNode(TIFF_RATIONAL_TAG);
node_mins.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, dt.getMinute()+"/1");
IIOMetadataNode node_secs = new IIOMetadataNode(TIFF_RATIONAL_TAG);
node_secs.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, fsec+"/"+denom);
node_rationals.appendChild(node_hrs);
node_rationals.appendChild(node_mins);
node_rationals.appendChild(node_secs);
*
* The number of pixels per ResolutionUnit in the ImageWidth direction.
<TIFFField number='282' name='XResolution'>
<TIFFRationals>
<TIFFRational value='1/1'/>
</TIFFRationals>
</TIFFField>
<TIFFField number='283' name='YResolution'>
<TIFFRationals>
<TIFFRational value='1/1'/>
</TIFFRationals>
</TIFFField>
<TIFFField number='296' name='ResolutionUnit'>
<TIFFShorts>
<TIFFShort value='1' description='None'/>
</TIFFShorts>
</TIFFField>
public static String TIFF_SHORTS_TAG = "TIFFShorts";
public static String TIFF_SHORT_TAG = "TIFFShort";
*/
/* /*
* *
FileImageOutputStream outputStream = new FileImageOutputStream(outputFile); FileImageOutputStream outputStream = new FileImageOutputStream(outputFile);
......
...@@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException; ...@@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
...@@ -58,6 +59,7 @@ import org.xml.sax.InputSource; ...@@ -58,6 +59,7 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.elphel.imagej.correction.Eyesis_Correction; import com.elphel.imagej.correction.Eyesis_Correction;
import com.elphel.imagej.ims.Did_ins;
import com.elphel.imagej.tileprocessor.QuadCLTCPU; import com.elphel.imagej.tileprocessor.QuadCLTCPU;
//import org.apache.log4j.Logger; //import org.apache.log4j.Logger;
...@@ -306,9 +308,20 @@ the type of pixel data in this file getPixelType() ...@@ -306,9 +308,20 @@ the type of pixel data in this file getPixelType()
boolean imageJTags, boolean imageJTags,
int debugLevel int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{ ) 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 (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? 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); // saveTiffARGB32(imp, path, imageJTags, debugLevel);
return; return;
} else if (imp.getStackSize()==4) { } else if (imp.getStackSize()==4) {
...@@ -341,7 +354,14 @@ the type of pixel data in this file getPixelType() ...@@ -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? 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); // saveTiffARGB32(imp_rgb, path, imageJTags, debugLevel);
return; return;
} }
......
...@@ -5351,6 +5351,11 @@ public class OpticalFlow { ...@@ -5351,6 +5351,11 @@ public class OpticalFlow {
quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...) 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 null, // String path, // full name with extension or w/o path to use x3d directory
debugLevel+1); debugLevel+1);
} else {
if (debugLevel> -3) {
System.out.println("Failed to perform attitude correction with QuaternionLma.");
}
} }
} }
...@@ -5946,7 +5951,6 @@ public class OpticalFlow { ...@@ -5946,7 +5951,6 @@ public class OpticalFlow {
int [] whs = new int[3]; int [] whs = new int[3];
double [] x0y0 = new double[2]; double [] x0y0 = new double[2];
if (export3d) { //combo_dsn_final had strength 1.0e-4 where it should not? Reset it? 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 boolean ok_3d = TexturedModel.output3d( // quadCLTs have same image name, and everything else
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
colorProcParameters, // ColorProcParameters colorProcParameters, colorProcParameters, // ColorProcParameters colorProcParameters,
......
...@@ -696,6 +696,7 @@ public class QuadCLTCPU { ...@@ -696,6 +696,7 @@ public class QuadCLTCPU {
System.out.println("getGroundIns(): no INS data available."); System.out.println("getGroundIns(): no INS data available.");
return null; 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_ortho = clt_parameters.imp.ims_ortho;
double [] ims_mount_atr = clt_parameters.imp.getImsMountATR(); // converts to radians double [] ims_mount_atr = clt_parameters.imp.getImsMountATR(); // converts to radians
double [] ims_mount_xyz = clt_parameters.imp.ims_mount_xyz; // not yet used double [] ims_mount_xyz = clt_parameters.imp.ims_mount_xyz; // not yet used
...@@ -721,6 +722,14 @@ public class QuadCLTCPU { ...@@ -721,6 +722,14 @@ public class QuadCLTCPU {
} }
double [] scene_abs_atr_enu = Imx5.quatToCamAtr(cam_quat_enu); double [] scene_abs_atr_enu = Imx5.quatToCamAtr(cam_quat_enu);
double [][] dls = getDLS(); 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) { if (dls==null) {
return null; return null;
} }
...@@ -941,15 +950,16 @@ public class QuadCLTCPU { ...@@ -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) { if (dsi == null) {
// System.out.println("dsi== null, use spawnQuadCLT(), restoreFromModel(), ... to set it"); // System.out.println("dsi== null, use spawnQuadCLT(), restoreFromModel(), ... to set it");
return null; 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[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[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[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; return dls;
} }
......
...@@ -2464,6 +2464,7 @@ public class TexturedModel { ...@@ -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 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 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 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 boolean crop_empty = clt_parameters.gmap_crop_empty ; //true;
final int crop_extra = clt_parameters.gmap_crop_extra ; //20; final int crop_extra = clt_parameters.gmap_crop_extra ; //20;
final int [] tex_pals = clt_parameters.gmap_tex_pals ; //{0,1,2}; final int [] tex_pals = clt_parameters.gmap_tex_pals ; //{0,1,2};
...@@ -2559,7 +2560,7 @@ public class TexturedModel { ...@@ -2559,7 +2560,7 @@ public class TexturedModel {
combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_LMA], combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_LMA],
combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_STRENGTH] 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? // currently conditionInitialDS() zeroes disparity for blue_sky. TODO: allow some FG over blue_sky?
// gets Blue Sky from scene.dsi , not from the file! // gets Blue Sky from scene.dsi , not from the file!
double [][] ds_fg = OpticalFlow.conditionInitialDS( double [][] ds_fg = OpticalFlow.conditionInitialDS(
...@@ -2584,9 +2585,17 @@ public class TexturedModel { ...@@ -2584,9 +2585,17 @@ public class TexturedModel {
dls_bg, // double [][] dls dls_bg, // double [][] dls
scenes[ref_index], // QuadCLT scene, scenes[ref_index], // QuadCLT scene,
debugLevel); // int debug_level) 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[][] ds_fg_bg = {ds_fg[0], ds_bg[0].clone()};
double[][] ss_fg_bg = {ds_fg[1], ds_bg[1]}; double[][] ss_fg_bg = {ds_fg[1], ds_bg[1]};
if (show_bs_debug) { if (show_bs_debug) {
String [] dbg_titles = {"FG","BG","BS"}; 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()}; 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 { ...@@ -2612,10 +2621,10 @@ public class TexturedModel {
} }
for (int i = 0; i < ss_fg_bg[0].length; i++) { for (int i = 0; i < ss_fg_bg[0].length; i++) {
if (Double.isNaN(dls_fg[1][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])){ 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 { ...@@ -2979,7 +2988,7 @@ public class TexturedModel {
} }
// if (imp_textures[nslice] != null) // if (imp_textures[nslice] != null)
} // for (int nslice = 0; nslice < tileClusters.length; nslice++){ } // for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (render_hdr) { if (render_hdr) { //
int [] hdr_whs = new int[3]; int [] hdr_whs = new int[3];
double [] hdr_x0y0 = new double[2]; double [] hdr_x0y0 = new double[2];
double [][] to_ground_xyzatr = scenes[ref_index].getGround( double [][] to_ground_xyzatr = scenes[ref_index].getGround(
......
...@@ -254,6 +254,7 @@ public class Render3D { ...@@ -254,6 +254,7 @@ public class Render3D {
if ((tri_meshes == null) || tri_meshes.isEmpty() || (tri_meshes.get(0).getTexturePixels() == null)) { if ((tri_meshes == null) || tri_meshes.isEmpty() || (tri_meshes.get(0).getTexturePixels() == null)) {
return null; return null;
} }
final boolean export_z = true;
final int dbg_ipix=1673752; final int dbg_ipix=1673752;
// get total number of triangles // get total number of triangles
int num_tri=0; int num_tri=0;
...@@ -276,7 +277,7 @@ public class Render3D { ...@@ -276,7 +277,7 @@ public class Render3D {
System.out.println("Prepare to render "+num_tri+" triangles in "+num_mesh+" meshes"); System.out.println("Prepare to render "+num_tri+" triangles in "+num_mesh+" meshes");
} }
final int z_index = tri_meshes.get(0).getTexturePixels().length; 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; int alpha_index = last_is_alpha ? (z_index - 1) : z_index;
for (int chn = 0; chn < alpha_index; chn++) { for (int chn = 0; chn < alpha_index; chn++) {
Arrays.fill(full_rendered[chn], Double.NaN); Arrays.fill(full_rendered[chn], Double.NaN);
...@@ -361,12 +362,12 @@ public class Render3D { ...@@ -361,12 +362,12 @@ public class Render3D {
double kx = dot2(d0p, orto2[0]); double kx = dot2(d0p, orto2[0]);
double ky = dot2(d0p, orto2[1]); double ky = dot2(d0p, orto2[1]);
// interpolate z // interpolate z
double z_interp = tri_out2[0][2] +
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]); 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)) { if ((rend[ipix] != null ) && (rend[ipix][z_index] < z_interp)) {
continue; continue;
} }
// Get corresponding texture coordinates // Get corresponding texture coordinates
double text_x = tri_text2[0][0] + kx * t01[0] + ky*t02[0]; // texture relative coordinates (0,1) 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! double text_y = tri_text2[0][1] + kx * t01[1] + ky*t02[1]; // y - up!
...@@ -426,7 +427,7 @@ public class Render3D { ...@@ -426,7 +427,7 @@ public class Render3D {
for (int sub_render = 0; sub_render < rendered.length; sub_render++) if (rendered[sub_render][indx] != null){ 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 if (!(rendered[sub_render][indx][z_index] <= z)) { // OK previous NaN
z = rendered[sub_render][indx][z_index]; 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]; full_rendered[chn][indx] = rendered[sub_render][indx][chn];
} }
} }
...@@ -549,12 +550,12 @@ public class Render3D { ...@@ -549,12 +550,12 @@ public class Render3D {
double kx = dot2(d0p, orto2[0]); double kx = dot2(d0p, orto2[0]);
double ky = dot2(d0p, orto2[1]); double ky = dot2(d0p, orto2[1]);
// interpolate z // interpolate z
double z_interp = tri_out2[0][2] +
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]); 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)) { if ((rend[ipix] != null ) && (rend[ipix][z_index] < z_interp)) {
continue; continue;
} }
// Get corresponding texture coordinates // Get corresponding texture coordinates
double text_x = tri_text2[0][0] + kx * t01[0] + ky*t02[0]; // texture relative coordinates (0,1) 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! 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