Commit 4bdd4cd8 authored by Andrey Filippov's avatar Andrey Filippov

Cleaning up

parent 064ff7ca
...@@ -1221,7 +1221,7 @@ public class PixelMapping { ...@@ -1221,7 +1221,7 @@ public class PixelMapping {
if (saveTiff){ if (saveTiff){
String outPath=((resultDirectory.length()<1)?"":(resultDirectory+Prefs.getFileSeparator()))+impOverlap.getTitle()+".tiff"; String outPath=((resultDirectory.length()<1)?"":(resultDirectory+Prefs.getFileSeparator()))+impOverlap.getTitle()+".tiff";
try { try {
(new EyesisTiff()).saveTiff( EyesisTiff.saveTiff(
impOverlap, impOverlap,
outPath, outPath,
3, // float32 3, // float32
......
...@@ -2743,7 +2743,7 @@ public class EyesisCorrections { ...@@ -2743,7 +2743,7 @@ public class EyesisCorrections {
try { try {
(new EyesisTiff()).saveTiffARGB32( (new EyesisTiff()).saveTiffARGB32(
imp, imp,
path, // +".tiff", path+".tiff", //path, // +".tiff",
false, // correctionsParameters.imageJTags, false, // correctionsParameters.imageJTags,
debugLevel); debugLevel);
} catch (IOException e) { } catch (IOException e) {
......
...@@ -295,7 +295,7 @@ the type of pixel data in this file getPixelType() ...@@ -295,7 +295,7 @@ the type of pixel data in this file getPixelType()
public void saveTiff( public static void saveTiff(
ImagePlus imp, ImagePlus imp,
String path, String path,
int mode, // 0 - 8-bit, 1 - 16-bit, 2 - 32-bit unsigned, 3 - 32FP (only if source image is a 4-stack of FP) int mode, // 0 - 8-bit, 1 - 16-bit, 2 - 32-bit unsigned, 3 - 32FP (only if source image is a 4-stack of FP)
...@@ -316,7 +316,7 @@ the type of pixel data in this file getPixelType() ...@@ -316,7 +316,7 @@ the type of pixel data in this file getPixelType()
IJ.showMessage("Not yet implemented for this image type"); IJ.showMessage("Not yet implemented for this image type");
} }
public void saveTiffARGB( public static void saveTiffARGB(
ImagePlus imp, ImagePlus imp,
String path, String path,
int mode, // 0 - 8-bit, 1 - 16-bit, 2 - 32-bit unsigned, 3 - 32FP (only if source image is a 4-stack of FP) int mode, // 0 - 8-bit, 1 - 16-bit, 2 - 32-bit unsigned, 3 - 32FP (only if source image is a 4-stack of FP)
...@@ -428,12 +428,14 @@ the type of pixel data in this file getPixelType() ...@@ -428,12 +428,14 @@ the type of pixel data in this file getPixelType()
return; return;
} }
// System.out.println("saveTiffARGBFloat32(): mode="+mode+" pixelType="+pixelType+" bw="+bw); // System.out.println("saveTiffARGBFloat32(): mode="+mode+" pixelType="+pixelType+" bw="+bw);
// ExifGPSTagSet gps_set = new ExifGPSTagSet();
// EXIFGPSTagSet gps_set = new EXIFGPSTagSet();
IFD ifd=new IFD(); IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false)); ifd.put(IFD.LITTLE_ENDIAN, false);
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true)); // ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth()); ifd.put(IFD.IMAGE_WIDTH, imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight()); ifd.put(IFD.IMAGE_LENGTH, imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4); ifd.put(IFD.SAMPLES_PER_PIXEL, 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis"); ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description); ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data? // copy some other data?
...@@ -484,7 +486,7 @@ the type of pixel data in this file getPixelType() ...@@ -484,7 +486,7 @@ the type of pixel data in this file getPixelType()
true); // boolean last) true); // boolean last)
} }
public void saveTiffARGB32( public static void saveTiffARGB32(
ImagePlus imp, ImagePlus imp,
String path, String path,
boolean imageJTags, boolean imageJTags,
...@@ -511,18 +513,19 @@ the type of pixel data in this file getPixelType() ...@@ -511,18 +513,19 @@ the type of pixel data in this file getPixelType()
bytes[pIndex++]=(byte) ((iPixels[i]>>24)& 0xff); // alpha bytes[pIndex++]=(byte) ((iPixels[i]>>24)& 0xff); // alpha
} }
IFD ifd=new IFD(); IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false)); ifd.put(IFD.LITTLE_ENDIAN, false);
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true)); // ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth()); ifd.put(IFD.IMAGE_WIDTH, imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight()); ifd.put(IFD.IMAGE_LENGTH, imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4); ifd.put(IFD.SAMPLES_PER_PIXEL, 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis"); ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description); ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data? // copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED); ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra bytes (over 3) meaning Unassociated alpha data // ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra bytes (over 3) meaning Unassociated alpha data
ifd.putIFDValue(IFD.EXTRA_SAMPLES,1); // extra bytes (over 3) meaning Unassociated alpha data
ifd.putIFDValue(IFD.SAMPLE_FORMAT,1); //
// int [] bpsArray={8,8,8,8}; // int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically // ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) { if (imp.getProperty("XPosition")!=null) {
...@@ -548,24 +551,9 @@ the type of pixel data in this file getPixelType() ...@@ -548,24 +551,9 @@ the type of pixel data in this file getPixelType()
int index=0; int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i]; for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ??? for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
/*
StringBuffer sb=new StringBuffer("bInfo: ");
for (int i=0;i<bInfo.length;i++) sb.append(bInfo[i]+" ");
System.out.println(sb.toString());
sb=new StringBuffer("ImageJInfoMagic: ");
for (int i=0;i<ImageJInfoMagic.length;i++) sb.append(ImageJInfoMagic[i]+" ");
System.out.println(sb.toString());
sb=new StringBuffer("bInfoBody: ");
for (int i=0;i<bInfoBody.length;i++) sb.append(bInfoBody[i]+" ");
System.out.println(sb.toString());
System.out.println("info[0]="+info.charAt(0));
System.out.println("info[1]="+info.charAt(1));
System.out.println("info[2]="+info.charAt(2));
*/
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes}; long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts); ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo); ifd.putIFDValue(IFDImageJInfo, bInfo);
} }
(new File(path)).delete(); // Otherwise TiffSaver appends! (new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path); TiffSaver tiffSaver = new TiffSaver(path);
...@@ -584,7 +572,7 @@ the type of pixel data in this file getPixelType() ...@@ -584,7 +572,7 @@ the type of pixel data in this file getPixelType()
public void propertiesTiff(ImagePlus imp){ public static void propertiesTiff(ImagePlus imp){
FileInfo fi = imp.getOriginalFileInfo(); FileInfo fi = imp.getOriginalFileInfo();
if ((fi==null) ||(fi.directory==null) || (fi.fileFormat!=FileInfo.TIFF)) { if ((fi==null) ||(fi.directory==null) || (fi.fileFormat!=FileInfo.TIFF)) {
IJ.error("TIFF Dumper", "File path not available or not TIFF file"); IJ.error("TIFF Dumper", "File path not available or not TIFF file");
......
...@@ -51,11 +51,19 @@ public class IntersceneMatchParameters { ...@@ -51,11 +51,19 @@ public class IntersceneMatchParameters {
public double sfm_same_weight = 0.8; // correction weight when new SfM gain is the same as the old one public double sfm_same_weight = 0.8; // correction weight when new SfM gain is the same as the old one
public int sfm_shrink = 2; // shrink sfm gain area before applying sfm_fade_sigma public int sfm_shrink = 2; // shrink sfm gain area before applying sfm_fade_sigma
public double sfm_fade_sigma = 3.0; // fade SfM gains at the edges public double sfm_fade_sigma = 3.0; // fade SfM gains at the edges
public double sfm_min_str = 0.4; // update if correction strength exceeds public double sfm_min_str1 = 0.2; // update if correction strength exceeds
public double sfm_min_str16 = 0.4; // update if correction strength exceeds (for >=16 pairs)
public boolean sfm_use_neibs = true; // use neighbors if individual corr is too weak public boolean sfm_use_neibs = true; // use neighbors if individual corr is too weak
public double sfm_neib_too_str= 0.4; // do not count neighbors stronger than that public double sfm_neib_too_str1= 0.3; // do not count neighbors stronger than that
public double sfm_neib_str= 0.5; // update if no-individual and neibs correction strength exceeds public double sfm_neib_too_str16= 0.4; // do not count neighbors stronger than that (for >=16 pairs)
public double sfm_neib_str1= 0.2; // update if no-individual and neibs correction strength exceeds
public double sfm_neib_str16= 0.5; // update if no-individual and neibs correction strength exceeds (for >=16 pairs)
public int sfm_extrap_steps = 5; // extrapolate disparity this number over undefined by SfM area
public int sfm_extrap_radius = 5; // find tilt for extrapolation using this radius circle around the new tile
public boolean sfm_average_neibs = false; // Average neighbors disparity among them
public boolean sfm_fill_weak = false; // Fill too weak tiles from nearest neighbors
public boolean sfm_extrapolate = false; // Extrapolate tiles with no SfM data (near edges)
public double [] getImsMountATR() { public double [] getImsMountATR() {
return new double [] { return new double [] {
...@@ -469,14 +477,31 @@ public class IntersceneMatchParameters { ...@@ -469,14 +477,31 @@ public class IntersceneMatchParameters {
"Shrink sfm gain area before applying sfm_fade_sigmas."); "Shrink sfm gain area before applying sfm_fade_sigmas.");
gd.addNumericField("Fade SfM area sigma", this.sfm_fade_sigma, 5,8,"", gd.addNumericField("Fade SfM area sigma", this.sfm_fade_sigma, 5,8,"",
"Fade SfM gains at the edges."); "Fade SfM gains at the edges.");
gd.addNumericField("Minimal correlation strength", this.sfm_min_str, 5,8,"", gd.addNumericField("Minimal correlation strength", this.sfm_min_str1, 5,8,"",
"Update if correction strength of individual tiles exceeds."); "Update if correction strength of individual tiles exceeds.");
gd.addNumericField("Minimal correlation strength >= 16 pairs", this.sfm_min_str16, 5,8,"",
"Update if correction strength of individual tiles exceeds (for >=16 pairs).");
gd.addCheckbox ("Use neighbors", this.sfm_use_neibs, gd.addCheckbox ("Use neighbors", this.sfm_use_neibs,
"Use neighbors if individual corr is too weak."); "Use neighbors if individual corr is too weak.");
gd.addNumericField("Too strong neighbors", this.sfm_neib_too_str, 5,8,"", gd.addNumericField("Too strong neighbors >= 16 pairs", this.sfm_neib_too_str1, 5,8,"",
"Do not accumulate neighbors stronger than that."); "Do not accumulate neighbors stronger than that.");
gd.addNumericField("Minimal neighbors strength", this.sfm_neib_str, 5,8,"", gd.addNumericField("Too strong neighbors", this.sfm_neib_too_str16, 5,8,"",
"Do not accumulate neighbors stronger than that (for >=16 pairs).");
gd.addNumericField("Minimal neighbors strength", this.sfm_neib_str1, 5,8,"",
"Update if no-individual and neighbors correction strength exceeds this."); "Update if no-individual and neighbors correction strength exceeds this.");
gd.addNumericField("Minimal neighbors strength >=16 pairs", this.sfm_neib_str16, 5,8,"",
"Update if no-individual and neighbors correction strength exceeds this (for >=16 pairs).");
gd.addNumericField("Extrapolation steps", this.sfm_extrap_steps, 0,3,"",
"Extrapolate disparity this number of times over the undefined by SfM area.");
gd.addNumericField("Extrapolation radius", this.sfm_extrap_radius, 0,3,"",
"Find tilt for extrapolation using this radius circle around the new tile.");
gd.addCheckbox ("Average neighbors", this.sfm_average_neibs,
"Average neighbors disparity among them.");
gd.addCheckbox ("Fill too weak tiles", this.sfm_fill_weak,
"Fill too weak tiles from nearest neighbors.");
gd.addCheckbox ("Extrapolate no SfM data", this.sfm_extrapolate,
"Extrapolate tiles with no SfM data (near edges).");
gd.addTab ("Scene Series", "Processing series of scenes and multi-series sets"); gd.addTab ("Scene Series", "Processing series of scenes and multi-series sets");
gd.addMessage ("Build series options"); gd.addMessage ("Build series options");
...@@ -1156,10 +1181,19 @@ public class IntersceneMatchParameters { ...@@ -1156,10 +1181,19 @@ public class IntersceneMatchParameters {
this.sfm_same_weight = gd.getNextNumber(); this.sfm_same_weight = gd.getNextNumber();
this.sfm_shrink = (int) gd.getNextNumber(); this.sfm_shrink = (int) gd.getNextNumber();
this.sfm_fade_sigma = gd.getNextNumber(); this.sfm_fade_sigma = gd.getNextNumber();
this.sfm_min_str = gd.getNextNumber(); this.sfm_min_str1 = gd.getNextNumber();
this.sfm_min_str16 = gd.getNextNumber();
this.sfm_use_neibs = gd.getNextBoolean(); this.sfm_use_neibs = gd.getNextBoolean();
this.sfm_neib_too_str = gd.getNextNumber(); this.sfm_neib_too_str1 = gd.getNextNumber();
this.sfm_neib_str = gd.getNextNumber(); this.sfm_neib_too_str16 = gd.getNextNumber();
this.sfm_neib_str1 = gd.getNextNumber();
this.sfm_neib_str16 = gd.getNextNumber();
this.sfm_extrap_steps = (int) gd.getNextNumber();
this.sfm_extrap_radius = (int) gd.getNextNumber();
this.sfm_average_neibs = gd.getNextBoolean();
this.sfm_fill_weak = gd.getNextBoolean();
this.sfm_extrapolate = gd.getNextBoolean();
this.center_reference = gd.getNextBoolean(); this.center_reference = gd.getNextBoolean();
this.force_ref_dsi = gd.getNextBoolean(); this.force_ref_dsi = gd.getNextBoolean();
this.force_orientations = gd.getNextBoolean(); this.force_orientations = gd.getNextBoolean();
...@@ -1522,17 +1556,26 @@ public class IntersceneMatchParameters { ...@@ -1522,17 +1556,26 @@ public class IntersceneMatchParameters {
properties.setProperty(prefix+"sfm_same_weight", this.sfm_same_weight+""); // double properties.setProperty(prefix+"sfm_same_weight", this.sfm_same_weight+""); // double
properties.setProperty(prefix+"sfm_shrink", this.sfm_shrink+""); // int properties.setProperty(prefix+"sfm_shrink", this.sfm_shrink+""); // int
properties.setProperty(prefix+"sfm_fade_sigma", this.sfm_fade_sigma+""); // double properties.setProperty(prefix+"sfm_fade_sigma", this.sfm_fade_sigma+""); // double
properties.setProperty(prefix+"sfm_min_str", this.sfm_min_str+""); // double properties.setProperty(prefix+"sfm_min_str1", this.sfm_min_str1+""); // double
properties.setProperty(prefix+"sfm_min_str16", this.sfm_min_str16+""); // double
properties.setProperty(prefix+"sfm_use_neibs", this.sfm_use_neibs+""); // boolean properties.setProperty(prefix+"sfm_use_neibs", this.sfm_use_neibs+""); // boolean
properties.setProperty(prefix+"sfm_neib_too_str", this.sfm_neib_too_str+""); // double properties.setProperty(prefix+"sfm_neib_too_str1", this.sfm_neib_too_str1+""); // double
properties.setProperty(prefix+"sfm_neib_str", this.sfm_neib_str +""); // double properties.setProperty(prefix+"sfm_neib_too_str16", this.sfm_neib_too_str16+""); // double
properties.setProperty(prefix+"sfm_neib_str1", this.sfm_neib_str1 +""); // double
properties.setProperty(prefix+"sfm_neib_str16", this.sfm_neib_str16 +""); // double
properties.setProperty(prefix+"sfm_extrap_steps", this.sfm_extrap_steps+""); // int
properties.setProperty(prefix+"sfm_extrap_radius", this.sfm_extrap_radius+""); // int
properties.setProperty(prefix+"sfm_average_neibs", this.sfm_average_neibs + ""); // boolean
properties.setProperty(prefix+"sfm_fill_weak", this.sfm_fill_weak + ""); // boolean
properties.setProperty(prefix+"sfm_extrapolate", this.sfm_extrapolate + ""); // boolean
properties.setProperty(prefix+"center_reference", this.center_reference + ""); // boolean properties.setProperty(prefix+"center_reference", this.center_reference + ""); // boolean
properties.setProperty(prefix+"force_ref_dsi", this.force_ref_dsi + ""); // boolean properties.setProperty(prefix+"force_ref_dsi", this.force_ref_dsi + ""); // boolean
properties.setProperty(prefix+"force_orientations", this.force_orientations + ""); // boolean properties.setProperty(prefix+"force_orientations", this.force_orientations + ""); // boolean
properties.setProperty(prefix+"run_ly", this.run_ly + ""); // boolean properties.setProperty(prefix+"run_ly", this.run_ly + ""); // boolean
properties.setProperty(prefix+"min_num_orient", this.min_num_orient+""); // int properties.setProperty(prefix+"min_num_orient", this.min_num_orient+""); // int
properties.setProperty(prefix+"min_num_interscene", this.min_num_interscene+""); // int properties.setProperty(prefix+"min_num_interscene", this.min_num_interscene+""); // int
properties.setProperty(prefix+"generate_egomotion", this.generate_egomotion+""); // boolean properties.setProperty(prefix+"generate_egomotion", this.generate_egomotion+""); // boolean
properties.setProperty(prefix+"generate_mapped", this.generate_mapped+""); // boolean properties.setProperty(prefix+"generate_mapped", this.generate_mapped+""); // boolean
properties.setProperty(prefix+"reuse_video", this.reuse_video+""); // boolean properties.setProperty(prefix+"reuse_video", this.reuse_video+""); // boolean
properties.setProperty(prefix+"save_mapped_color", this.save_mapped_color+""); // boolean properties.setProperty(prefix+"save_mapped_color", this.save_mapped_color+""); // boolean
...@@ -1848,10 +1891,19 @@ public class IntersceneMatchParameters { ...@@ -1848,10 +1891,19 @@ public class IntersceneMatchParameters {
if (properties.getProperty(prefix+"sfm_same_weight")!=null) this.sfm_same_weight=Double.parseDouble(properties.getProperty(prefix+"sfm_same_weight")); if (properties.getProperty(prefix+"sfm_same_weight")!=null) this.sfm_same_weight=Double.parseDouble(properties.getProperty(prefix+"sfm_same_weight"));
if (properties.getProperty(prefix+"sfm_shrink")!=null) this.sfm_shrink=Integer.parseInt(properties.getProperty(prefix+"sfm_shrink")); if (properties.getProperty(prefix+"sfm_shrink")!=null) this.sfm_shrink=Integer.parseInt(properties.getProperty(prefix+"sfm_shrink"));
if (properties.getProperty(prefix+"sfm_fade_sigma")!=null) this.sfm_fade_sigma=Double.parseDouble(properties.getProperty(prefix+"sfm_fade_sigma")); if (properties.getProperty(prefix+"sfm_fade_sigma")!=null) this.sfm_fade_sigma=Double.parseDouble(properties.getProperty(prefix+"sfm_fade_sigma"));
if (properties.getProperty(prefix+"sfm_min_str")!=null) this.sfm_min_str=Double.parseDouble(properties.getProperty(prefix+"sfm_min_str")); if (properties.getProperty(prefix+"sfm_min_str1")!=null) this.sfm_min_str1=Double.parseDouble(properties.getProperty(prefix+"sfm_min_str1"));
if (properties.getProperty(prefix+"sfm_min_str16")!=null) this.sfm_min_str16=Double.parseDouble(properties.getProperty(prefix+"sfm_min_str16"));
if (properties.getProperty(prefix+"sfm_use_neibs")!=null) this.sfm_use_neibs=Boolean.parseBoolean(properties.getProperty(prefix+"sfm_use_neibs")); if (properties.getProperty(prefix+"sfm_use_neibs")!=null) this.sfm_use_neibs=Boolean.parseBoolean(properties.getProperty(prefix+"sfm_use_neibs"));
if (properties.getProperty(prefix+"sfm_neib_too_str")!=null) this.sfm_neib_too_str=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_too_str")); if (properties.getProperty(prefix+"sfm_neib_too_str1")!=null) this.sfm_neib_too_str1=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_too_str1"));
if (properties.getProperty(prefix+"sfm_neib_str")!=null) this.sfm_neib_str=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_str")); if (properties.getProperty(prefix+"sfm_neib_too_str16")!=null) this.sfm_neib_too_str16=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_too_str16"));
if (properties.getProperty(prefix+"sfm_neib_str1")!=null) this.sfm_neib_str1=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_str1"));
if (properties.getProperty(prefix+"sfm_neib_str16")!=null) this.sfm_neib_str16=Double.parseDouble(properties.getProperty(prefix+"sfm_neib_str16"));
if (properties.getProperty(prefix+"sfm_extrap_steps")!=null) this.sfm_extrap_steps=Integer.parseInt(properties.getProperty(prefix+"sfm_extrap_steps"));
if (properties.getProperty(prefix+"sfm_extrap_radius")!=null) this.sfm_extrap_radius=Integer.parseInt(properties.getProperty(prefix+"sfm_extrap_radius"));
if (properties.getProperty(prefix+"sfm_average_neibs")!=null) this.sfm_average_neibs=Boolean.parseBoolean(properties.getProperty(prefix+"sfm_average_neibs"));
if (properties.getProperty(prefix+"sfm_fill_weak")!=null) this.sfm_fill_weak=Boolean.parseBoolean(properties.getProperty(prefix+"sfm_fill_weak"));
if (properties.getProperty(prefix+"sfm_extrapolate")!=null) this.sfm_extrapolate=Boolean.parseBoolean(properties.getProperty(prefix+"sfm_extrapolate"));
if (properties.getProperty(prefix+"center_reference")!=null) this.center_reference=Boolean.parseBoolean(properties.getProperty(prefix+"center_reference")); if (properties.getProperty(prefix+"center_reference")!=null) this.center_reference=Boolean.parseBoolean(properties.getProperty(prefix+"center_reference"));
if (properties.getProperty(prefix+"force_ref_dsi")!=null) this.force_ref_dsi=Boolean.parseBoolean(properties.getProperty(prefix+"force_ref_dsi")); if (properties.getProperty(prefix+"force_ref_dsi")!=null) this.force_ref_dsi=Boolean.parseBoolean(properties.getProperty(prefix+"force_ref_dsi"));
if (properties.getProperty(prefix+"force_orientations")!=null) this.force_orientations=Boolean.parseBoolean(properties.getProperty(prefix+"force_orientations")); if (properties.getProperty(prefix+"force_orientations")!=null) this.force_orientations=Boolean.parseBoolean(properties.getProperty(prefix+"force_orientations"));
...@@ -2201,10 +2253,19 @@ public class IntersceneMatchParameters { ...@@ -2201,10 +2253,19 @@ public class IntersceneMatchParameters {
imp.sfm_same_weight = this.sfm_same_weight; imp.sfm_same_weight = this.sfm_same_weight;
imp.sfm_shrink = this.sfm_shrink; imp.sfm_shrink = this.sfm_shrink;
imp.sfm_fade_sigma = this.sfm_fade_sigma; imp.sfm_fade_sigma = this.sfm_fade_sigma;
imp.sfm_min_str = this.sfm_min_str; imp.sfm_min_str1 = this.sfm_min_str1;
imp.sfm_min_str16 = this.sfm_min_str16;
imp.sfm_use_neibs = this.sfm_use_neibs; imp.sfm_use_neibs = this.sfm_use_neibs;
imp.sfm_neib_too_str = this.sfm_neib_too_str; imp.sfm_neib_too_str1 = this.sfm_neib_too_str1;
imp.sfm_neib_str = this.sfm_neib_str; imp.sfm_neib_too_str16 = this.sfm_neib_too_str16;
imp.sfm_neib_str1 = this.sfm_neib_str1;
imp.sfm_neib_str16 = this.sfm_neib_str16;
imp.sfm_extrap_steps = this.sfm_extrap_steps;
imp.sfm_extrap_radius = this.sfm_extrap_radius;
imp.sfm_average_neibs = this.sfm_average_neibs;
imp.sfm_fill_weak = this.sfm_fill_weak;
imp.sfm_extrapolate = this.sfm_extrapolate;
imp.center_reference = this.center_reference; imp.center_reference = this.center_reference;
imp.force_ref_dsi = this.force_ref_dsi; imp.force_ref_dsi = this.force_ref_dsi;
imp.force_orientations = this.force_orientations; imp.force_orientations = this.force_orientations;
......
...@@ -3070,7 +3070,7 @@ public class TexturedModel { ...@@ -3070,7 +3070,7 @@ public class TexturedModel {
hdr_whs[0], // int width, hdr_whs[0], // int width,
wh, // int [] wh, // should be initialized to int [2] wh, // int [] wh, // should be initialized to int [2]
full_render); // double [][] img_src) full_render); // double [][] img_src)
if (img_cropped != null) { if (img_cropped != null) { // has NaN and alpha 0-1
scenes[ref_index].saveDoubleArrayInModelDirectory( scenes[ref_index].saveDoubleArrayInModelDirectory(
suffix+"-CROP", // String suffix, suffix+"-CROP", // String suffix,
null, // String [] labels, // or null null, // String [] labels, // or null
......
...@@ -131,7 +131,7 @@ public class TileNeibs{ ...@@ -131,7 +131,7 @@ public class TileNeibs{
* @param dy offset in y direction * @param dy offset in y direction
* @return new index or -1 if leaving * @return new index or -1 if leaving
*/ */
int getNeibIndex(int indx, int dx, int dy) { public int getNeibIndex(int indx, int dx, int dy) {
int y = indx / sizeX + dy; int y = indx / sizeX + dy;
int x = indx % sizeX + dx; int x = indx % sizeX + dx;
if ((x < 0) || (y < 0 ) || (x >= sizeX) || (y >= sizeY)) return -1; if ((x < 0) || (y < 0 ) || (x >= sizeX) || (y >= sizeY)) return -1;
......
...@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.DoubleGaussianBlur; import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.gpu.GPUTileProcessor; import com.elphel.imagej.gpu.GPUTileProcessor;
//import com.elphel.imagej.cameras.ColorProcParameters; //import com.elphel.imagej.cameras.ColorProcParameters;
...@@ -51,6 +52,10 @@ import ij.ImagePlus; ...@@ -51,6 +52,10 @@ import ij.ImagePlus;
public class StructureFromMotion { public class StructureFromMotion {
public static double [] ZERO3 = {0.0,0.0,0.0}; public static double [] ZERO3 = {0.0,0.0,0.0};
public static int THREADS_MAX = 100; // maximal number of threads to launch public static int THREADS_MAX = 100; // maximal number of threads to launch
public static final int MODE_STRONG=3;
public static final int MODE_NEIB= 2;
public static final int MODE_WEAK= 1;
public static final int MODE_NONE= 0;
// class SfmCorr{ // class SfmCorr{
// double sfm_gain; // double sfm_gain;
// double [] corr_ind; // {disparity, strength} // double [] corr_ind; // {disparity, strength}
...@@ -496,7 +501,7 @@ public class StructureFromMotion { ...@@ -496,7 +501,7 @@ public class StructureFromMotion {
return combo_dsn_final; return combo_dsn_final;
} }
@Deprecated
public static double [][] sfmPair( // clean this up from extra data public static double [][] sfmPair( // clean this up from extra data
final CLTParameters clt_parameters, final CLTParameters clt_parameters,
final QuadCLT ref_scene, final QuadCLT ref_scene,
...@@ -507,13 +512,16 @@ public class StructureFromMotion { ...@@ -507,13 +512,16 @@ public class StructureFromMotion {
boolean show_disp_corr = false; //true; boolean show_disp_corr = false; //true;
boolean show_disp_seq = true; boolean show_disp_seq = true;
final int num_readjust = clt_parameters.imp.sfm_readjust; // 5; final int num_readjust = clt_parameters.imp.sfm_readjust; // 5;
final double min_strength = clt_parameters.imp.sfm_min_str; // 0.4; // update if correction strength exceeds final double min_strength1 = clt_parameters.imp.sfm_min_str1; // 0.4; // update if correction strength exceeds
final double neib_too_strong = clt_parameters.imp.sfm_neib_too_str; // 0.4; // do not count neighbors stronger than that final double min_strength16= clt_parameters.imp.sfm_min_str16; // 0.4; // update if correction strength exceeds
final double neib_too_strong1 = clt_parameters.imp.sfm_neib_too_str1; // 0.4; // do not count neighbors stronger than that
final double neib_too_strong16 = clt_parameters.imp.sfm_neib_too_str16; // 0.4; // do not count neighbors stronger than that
final int sfm_shrink = clt_parameters.imp.sfm_shrink; // 5; final int sfm_shrink = clt_parameters.imp.sfm_shrink; // 5;
final double fade_sigma = clt_parameters.imp. sfm_fade_sigma; // 3.0; // fade SfM gains at the edges final double fade_sigma = clt_parameters.imp. sfm_fade_sigma; // 3.0; // fade SfM gains at the edges
final boolean use_neibs = clt_parameters.imp.sfm_use_neibs; // true; final boolean use_neibs = clt_parameters.imp.sfm_use_neibs; // true;
final double min_neib_strength= clt_parameters.imp.sfm_neib_str; // 0.5; // update if no-individual and neibs correction strength exceeds final double min_neib_strength1= clt_parameters.imp.sfm_neib_str1; // 0.5; // update if no-individual and neibs correction strength exceeds
final double min_neib_strength16= clt_parameters.imp.sfm_neib_str16; // 0.5; // update if no-individual and neibs correction strength exceeds
final double prev_sfm_frac = clt_parameters.imp.sfm_prev_frac; // 0.6; // update if new sfm gain > this fraction of the old one final double prev_sfm_frac = clt_parameters.imp.sfm_prev_frac; // 0.6; // update if new sfm gain > this fraction of the old one
final double same_weight = clt_parameters.imp.sfm_same_weight; // 0.8; final double same_weight = clt_parameters.imp.sfm_same_weight; // 0.8;
final double range_disparity_offset = clt_parameters.imp.range_disparity_offset; final double range_disparity_offset = clt_parameters.imp.range_disparity_offset;
...@@ -584,7 +592,13 @@ public class StructureFromMotion { ...@@ -584,7 +592,13 @@ public class StructureFromMotion {
if (disp_adj != null) { if (disp_adj != null) {
disp_adj[0] = ref_disparity.clone(); disp_adj[0] = ref_disparity.clone();
} }
final int max_pairs_scale = 16;
final int num_pairs = scene_pairs.length; final int num_pairs = scene_pairs.length;
final double strength_frac16 = (num_pairs < max_pairs_scale)? (Math.sqrt(num_pairs)-1)/(Math.sqrt(max_pairs_scale)-1): 1.0;
final double min_strength = min_strength1 * (1.0-strength_frac16) + min_strength16* strength_frac16;
final double neib_too_strong = neib_too_strong1 * (1.0-strength_frac16) + neib_too_strong16* strength_frac16;
final double min_neib_strength = min_neib_strength1 * (1.0-strength_frac16) + min_neib_strength16* strength_frac16;
final double[][][][] scenes_xyzatr = new double[num_pairs][2][][]; // 2 scenes final double[][][][] scenes_xyzatr = new double[num_pairs][2][][]; // 2 scenes
final double[][][][] scenes_xyzatr_dt = new double[num_pairs][2][][];// 2 scenes final double[][][][] scenes_xyzatr_dt = new double[num_pairs][2][][];// 2 scenes
for (int npair = 0; npair < num_pairs; npair++) { for (int npair = 0; npair < num_pairs; npair++) {
...@@ -763,27 +777,51 @@ public class StructureFromMotion { ...@@ -763,27 +777,51 @@ public class StructureFromMotion {
boolean show_disp_corr_ind = false; //true; boolean show_disp_corr_ind = false; //true;
boolean show_disp_corr = false; //true; boolean show_disp_corr = false; //true;
boolean show_disp_seq = true; boolean show_disp_seq = true;
show_disp_corr_ind &= !batch_mode;
show_disp_corr &= !batch_mode;
show_disp_seq &= !batch_mode;
final int dbg_tile = -( 52+58*80); final int dbg_tile = -( 52+58*80);
final int num_readjust = clt_parameters.imp.sfm_readjust; // 5; final int num_readjust = clt_parameters.imp.sfm_readjust; // 5;
final double min_strength = clt_parameters.imp.sfm_min_str; // 0.4; // update if correction strength exceeds final double min_strength1 = clt_parameters.imp.sfm_min_str1; // 0.4; // update if correction strength exceeds
final double neib_too_strong = clt_parameters.imp.sfm_neib_too_str; // 0.4; // do not count neighbors stronger than that final double min_strength16= clt_parameters.imp.sfm_min_str16; // 0.4; // update if correction strength exceeds
final double neib_too_strong1 = clt_parameters.imp.sfm_neib_too_str1; // 0.4; // do not count neighbors stronger than that
final double neib_too_strong16 = clt_parameters.imp.sfm_neib_too_str16; // 0.4; // do not count neighbors stronger than that
final int sfm_shrink = clt_parameters.imp.sfm_shrink; // 5; final int sfm_shrink = clt_parameters.imp.sfm_shrink; // 5;
final double fade_sigma = clt_parameters.imp. sfm_fade_sigma; // 3.0; // fade SfM gains at the edges final double fade_sigma = clt_parameters.imp. sfm_fade_sigma; // 3.0; // fade SfM gains at the edges
final boolean use_neibs = clt_parameters.imp.sfm_use_neibs; // true; final boolean use_neibs = clt_parameters.imp.sfm_use_neibs; // true;
final double min_neib_strength= clt_parameters.imp.sfm_neib_str; // 0.5; // update if no-individual and neibs correction strength exceeds final double min_neib_strength1= clt_parameters.imp.sfm_neib_str1; // 0.5; // update if no-individual and neibs correction strength exceeds
final double min_neib_strength16= clt_parameters.imp.sfm_neib_str16; // 0.5; // update if no-individual and neibs correction strength exceeds
final double prev_sfm_frac = clt_parameters.imp.sfm_prev_frac; // 0.6; // update if new sfm gain > this fraction of the old one final double prev_sfm_frac = clt_parameters.imp.sfm_prev_frac; // 0.6; // update if new sfm gain > this fraction of the old one
final double same_weight = clt_parameters.imp.sfm_same_weight; // 0.8; final double same_weight = clt_parameters.imp.sfm_same_weight; // 0.8;
final double range_disparity_offset = clt_parameters.imp.range_disparity_offset; final double range_disparity_offset = clt_parameters.imp.range_disparity_offset;
final double centroid_radius = clt_parameters.imp.centroid_radius; // final double centroid_radius, // 0 - use all tile, >0 - cosine window around local max final double centroid_radius = clt_parameters.imp.centroid_radius; // final double centroid_radius, // 0 - use all tile, >0 - cosine window around local max
final int n_recenter = clt_parameters.imp.n_recenter; // when cosine window, re-center window this many times final int n_recenter = clt_parameters.imp.n_recenter; // when cosine window, re-center window this many times
boolean use_lma_dsi = clt_parameters.imp.use_lma_dsi;
// 16 puts scale same as with older code // 16 puts scale same as with older code
final double corr_fz_inter = 16* clt_parameters.getGpuFatZeroInter(ref_scene.isMonochrome()); final double corr_fz_inter = 16* clt_parameters.getGpuFatZeroInter(ref_scene.isMonochrome());
// TODO: assign !
final double inf_disp = clt_parameters.imp.disparity_corr; // disparity at infinity
final int extrapolate_steps = clt_parameters.imp.sfm_extrap_steps;
final int extrapolate_radius = clt_parameters.imp.sfm_extrap_radius;
final boolean average_neibs = clt_parameters.imp.sfm_average_neibs; //false;
final boolean fill_weak = clt_parameters.imp.sfm_fill_weak; // false;
final boolean extrapolate = clt_parameters.imp.sfm_extrapolate; // false;
final int tilesX = ref_scene.getTileProcessor().getTilesX(); final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY(); final int tilesY = ref_scene.getTileProcessor().getTilesY();
ErsCorrection ers_reference = ref_scene.getErsCorrection(); ErsCorrection ers_reference = ref_scene.getErsCorrection();
final double zdisp = ers_reference.getDisparityFromZ(1.0); // product of z and disparity
boolean use_combo_dsi = true; boolean use_combo_dsi = true;
boolean use_lma_dsi = clt_parameters.imp.use_lma_dsi;
double [][] ref_xyzatr = new double [][] {ZERO3,ZERO3}; double [][] ref_xyzatr = new double [][] {ZERO3,ZERO3};
double [][] ref_xyzatr_dt= { double [][] ref_xyzatr_dt= {
ers_reference.getErsXYZ_dt(), ers_reference.getErsXYZ_dt(),
...@@ -844,6 +882,16 @@ public class StructureFromMotion { ...@@ -844,6 +882,16 @@ public class StructureFromMotion {
final int [] num_set_pairs = new int [num_sets]; final int [] num_set_pairs = new int [num_sets];
final double[][][][][] scenes_xyzatr_sets = new double[num_sets][][][][]; final double[][][][][] scenes_xyzatr_sets = new double[num_sets][][][][];
final double[][][][][] scenes_xyzatr_dt_sets = new double[num_sets][][][][]; final double[][][][][] scenes_xyzatr_dt_sets = new double[num_sets][][][][];
final int num_pairs0 = scene_pairs_sets[0].length; // normally each set length is the same. Used for scaling min strengths.
final int max_pairs_scale = 16;
final double strength_frac16 = (num_pairs0 > 1) ?(
(num_pairs0 < max_pairs_scale)? (Math.sqrt(num_pairs0)-1)/(Math.sqrt(max_pairs_scale)-1): 1.0) : 0;
final double min_strength = min_strength1 * (1.0-strength_frac16) + min_strength16* strength_frac16;
final double neib_too_strong = neib_too_strong1 * (1.0-strength_frac16) + neib_too_strong16* strength_frac16;
final double min_neib_strength = min_neib_strength1 * (1.0-strength_frac16) + min_neib_strength16* strength_frac16;
final int min_neibs_fill = 4;
for (int nset=0; nset < num_sets; nset++) { for (int nset=0; nset < num_sets; nset++) {
int num_pairs = scene_pairs_sets[nset].length; int num_pairs = scene_pairs_sets[nset].length;
num_set_pairs[nset] = num_pairs; num_set_pairs[nset] = num_pairs;
...@@ -879,7 +927,17 @@ public class StructureFromMotion { ...@@ -879,7 +927,17 @@ public class StructureFromMotion {
final SfmCorr [] sfmCorrCombo = new SfmCorr [tilesX*tilesY]; final SfmCorr [] sfmCorrCombo = new SfmCorr [tilesX*tilesY];
double [] sum_weights_ind= new double [tilesX*tilesY]; double [] sum_weights_ind= new double [tilesX*tilesY];
double [] sum_weights_neib=new double [tilesX*tilesY]; double [] sum_weights_neib=new double [tilesX*tilesY];
/*
* 0 - not to be modified as SfM gain is lower than threshold
* 1 - weak tile, never got individual or neighbor correction
* 2 - corrected by a neighbor
* 3 - strong tile, corrected individually
*/
final int [] corr_mode = new int [tilesX*tilesY];
for (int nset=0; nset < num_sets; nset++) { for (int nset=0; nset < num_sets; nset++) {
SfmCorr [] sfmCorr = getSfmCorr( SfmCorr [] sfmCorr = getSfmCorr(
clt_parameters, // final CLTParameters clt_parameters, clt_parameters, // final CLTParameters clt_parameters,
ref_scene, // final QuadCLT ref_scene, ref_scene, // final QuadCLT ref_scene,
...@@ -978,7 +1036,10 @@ public class StructureFromMotion { ...@@ -978,7 +1036,10 @@ public class StructureFromMotion {
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
} // for (int nset=0; nset < num_sets; nset++) } // for (int nset=0; nset < num_sets; nset++)
double [][] dbg_extra = show_disp_corr? new double [6][]: null;
if (dbg_extra !=null) {
dbg_extra[0] = ref_disparity.clone();
}
// combine corrections // combine corrections
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
...@@ -1011,11 +1072,15 @@ public class StructureFromMotion { ...@@ -1011,11 +1072,15 @@ public class StructureFromMotion {
ref_disparity[nTile] += w *sfmCorrCombo[nTile].corr_ind[0]; ref_disparity[nTile] += w *sfmCorrCombo[nTile].corr_ind[0];
// TODO: add same (as above) for strengths? // TODO: add same (as above) for strengths?
ref_sfm_gain[nTile] = (1-w) *ref_sfm_gain[nTile] + w * sfmCorrCombo[nTile].sfm_gain; ref_sfm_gain[nTile] = (1-w) *ref_sfm_gain[nTile] + w * sfmCorrCombo[nTile].sfm_gain;
corr_mode[nTile] = MODE_STRONG;
} else if ((sfmCorrCombo[nTile].corr_neib != null) && (sfmCorrCombo[nTile].corr_neib[1] > min_neib_strength)) { } else if ((sfmCorrCombo[nTile].corr_neib != null) && (sfmCorrCombo[nTile].corr_neib[1] > min_neib_strength)) {
ref_disparity[nTile] += w *sfmCorrCombo[nTile].corr_neib[0]; ref_disparity[nTile] += w *sfmCorrCombo[nTile].corr_neib[0];
// TODO: add same (as above) for strengths? // TODO: add same (as above) for strengths?
ref_sfm_gain[nTile] = (1-w) *ref_sfm_gain[nTile] + w * sfmCorrCombo[nTile].sfm_gain; ref_sfm_gain[nTile] = (1-w) *ref_sfm_gain[nTile] + w * sfmCorrCombo[nTile].sfm_gain;
} corr_mode[nTile] = MODE_NEIB;
} else {
corr_mode[nTile] = MODE_WEAK;
}
} }
} }
} }
...@@ -1023,17 +1088,79 @@ public class StructureFromMotion { ...@@ -1023,17 +1088,79 @@ public class StructureFromMotion {
}; };
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
if (dbg_extra !=null) {
dbg_extra[1] = ref_disparity.clone();
}
if (average_neibs) {
averageNeighborsDisparity(
ref_disparity, // final double [] ref_disparity,
corr_mode, // final int [] corr_mode,
tilesX, // final int tilesX,
tilesY); // final int tilesY
}
// now fill weak tiles (MODE_WEAK) from MODE_NEIB neighbors
// repeat until any new tiles
// then - try from strong tiles - repeat until new
// ************************************
if (dbg_extra !=null) {
dbg_extra[2] = ref_disparity.clone();
dbg_extra[3] = new double [corr_mode.length];
for (int i = 0; i < corr_mode.length; i++) {
dbg_extra[3][i] = corr_mode[i];
}
}
boolean [] defined = null;
if (fill_weak) {
defined = fillWeakTiles(
ref_disparity, // final double [] ref_disparity,
corr_mode, // final int [] corr_mode,
min_neibs_fill, // final int min_neibs_fill,
tilesX, // final int tilesX,
tilesY); // final int tilesY
if (dbg_extra !=null) {
dbg_extra[4] = ref_disparity.clone();
dbg_extra[5] = new double [corr_mode.length];
for (int i = 0; i < defined.length; i++) {
dbg_extra[5][i] = defined[i]? 1.0:0.0;
}
}
}
// Can be done once after all iteration, but one row can help neighbors
// may make max_steps= 1 for all but the last run
if (extrapolate) {
if (defined == null) {
defined = new boolean[corr_mode.length];
for (int i = 0; i < corr_mode.length; i++) {
defined[i] = (corr_mode[i] > 0);
}
}
int total_filled = extrapolateEdges(
ref_disparity, // final double [] ref_disparity,
defined, // final boolean [] defined,
extrapolate_radius, // final int radius,
extrapolate_steps, // final int max_steps,
tilesX, // final int tilesX,
tilesY, // final int tilesY,
zdisp, //final double zdisp, // product of z and disparity
inf_disp); // final double inf_disp // disparity at infinity
if (debugLevel > -3) {
System.out.println("extrapolateEdges() -> "+total_filled+" new tiles");
}
}
if (show_disp_corr) { if (show_disp_corr) {
String [] dbg_titles = {"corr", "corr_str","neib_corr", "neib_str","old_sfm","new_sfm"}; String [] dbg_titles = {
"corr", "corr_str","neib_corr", "neib_str", // 0-3
"disp_before","disp_init","disp_avg","disp_weak","disp_extrap", // 4-8
"old_sfm","new_sfm", "corr_mode","defined"}; //9-12
double [][] dbg_2d_corr = new double [dbg_titles.length][sfmCorrCombo.length]; double [][] dbg_2d_corr = new double [dbg_titles.length][sfmCorrCombo.length];
for (int i = 0; i < dbg_2d_corr.length; i++) { for (int i = 0; i < dbg_2d_corr.length; i++) {
Arrays.fill(dbg_2d_corr[i], Double.NaN); Arrays.fill(dbg_2d_corr[i], Double.NaN);
} }
dbg_2d_corr[4] = ref_sfm_gain.clone(); dbg_2d_corr[9] = ref_sfm_gain.clone();
for (int nTile = 0; nTile < sfmCorrCombo.length; nTile++) if (sfmCorrCombo[nTile] != null) { for (int nTile = 0; nTile < sfmCorrCombo.length; nTile++) if (sfmCorrCombo[nTile] != null) {
dbg_2d_corr[5][nTile] = sfmCorrCombo[nTile].sfm_gain; dbg_2d_corr[10][nTile] = sfmCorrCombo[nTile].sfm_gain;
if (sfmCorrCombo[nTile].corr_ind != null) { if (sfmCorrCombo[nTile].corr_ind != null) {
dbg_2d_corr[0][nTile] = sfmCorrCombo[nTile].corr_ind[0]; dbg_2d_corr[0][nTile] = sfmCorrCombo[nTile].corr_ind[0];
dbg_2d_corr[1][nTile] = sfmCorrCombo[nTile].corr_ind[1]; dbg_2d_corr[1][nTile] = sfmCorrCombo[nTile].corr_ind[1];
...@@ -1042,7 +1169,14 @@ public class StructureFromMotion { ...@@ -1042,7 +1169,14 @@ public class StructureFromMotion {
dbg_2d_corr[2][nTile] = sfmCorrCombo[nTile].corr_neib[0]; dbg_2d_corr[2][nTile] = sfmCorrCombo[nTile].corr_neib[0];
dbg_2d_corr[3][nTile] = sfmCorrCombo[nTile].corr_neib[1]; dbg_2d_corr[3][nTile] = sfmCorrCombo[nTile].corr_neib[1];
} }
dbg_2d_corr[11][nTile] = corr_mode[nTile];
} }
dbg_2d_corr[ 4] = dbg_extra[0];
dbg_2d_corr[ 5] = dbg_extra[1];
dbg_2d_corr[ 6] = dbg_extra[2];
dbg_2d_corr[ 7] = dbg_extra[4];
dbg_2d_corr[ 8] = ref_disparity.clone();
dbg_2d_corr[12] = dbg_extra[5];
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
dbg_2d_corr, dbg_2d_corr,
tilesX, tilesX,
...@@ -1052,9 +1186,7 @@ public class StructureFromMotion { ...@@ -1052,9 +1186,7 @@ public class StructureFromMotion {
scene_pairs_sets[0][0][0].getImageName()+"-"+String.format("%02d", ntry), scene_pairs_sets[0][0][0].getImageName()+"-"+String.format("%02d", ntry),
dbg_titles); dbg_titles);
} }
// replace weak tiles with average? // replace weak tiles with average?
if (disp_adj != null) { if (disp_adj != null) {
disp_adj[ntry + 1] = ref_disparity.clone(); disp_adj[ntry + 1] = ref_disparity.clone();
...@@ -1087,6 +1219,241 @@ public class StructureFromMotion { ...@@ -1087,6 +1219,241 @@ public class StructureFromMotion {
return combo_dsn_final; return combo_dsn_final;
} }
public static int extrapolateEdges(
final double [] ref_disparity,
final boolean [] defined,
final int radius,
final int max_steps,
final int tilesX,
final int tilesY,
final double zdisp, // product of z and disparity
final double inf_disp // disparity at infinity
) {
final double [][] weights = new double [radius+1][radius+1];
for (int i =0; i <= radius; i++) {
double y = (1.0 * i) / (radius+1);
for (int j =0; j <= radius; j++) {
double x = (1.0 * j) / (radius+1);
double r = Math.sqrt(x*x + y*y);
if (r < 1.0) {
weights[i][j] = Math.cos(r* Math.PI);
}
}
}
final TileNeibs tn = new TileNeibs(tilesX,tilesY);
final double normal_damping = 0.001; // pull to horizontal if not enough data
final double [] damping = new double [] {normal_damping, normal_damping};
final boolean [] new_defined = defined.clone();
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger acounter = new AtomicInteger(0);
final AtomicInteger afilled = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
int total_filled = 0;
for (int nstep=0; nstep < max_steps; nstep++) {
acounter.set(0); // remains after last step;
afilled.set(0);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [][][] mdata = new double [(2 * radius + 1) * (2 * radius + 1)][][];
PolynomialApproximation pa = new PolynomialApproximation();
for (int nTile = ai.getAndIncrement(); nTile < ref_disparity.length; nTile = ai.getAndIncrement())
if (!defined[nTile]) { // only add new that were not defined before
// find if there is any defined neighbor
boolean got_it = false;
for (int dir = 0; dir < TileNeibs.DIRS; dir++) {
int tile1 = tn.getNeibIndex(nTile, dir);
if ((tile1 >=0) && defined[tile1]){
got_it=true;
break;
}
}
if (got_it) {
Arrays.fill(mdata, null);
int mindx = 0;
for (int idy = -radius; idy <= radius; idy++) {
for (int idx = -radius; idx <= radius; idx++) {
int tile1 = tn.getNeibIndex(nTile, idx, idy);
if ((tile1 >= 0) && defined[tile1]) {
double z = zdisp / (ref_disparity[nTile] + inf_disp);
double w = weights[Math.abs(idy)][Math.abs(idx)];
mdata[mindx] = new double[3][];
mdata[mindx][0] = new double [2];
mdata[mindx][0][0] = idx;
mdata[mindx][0][1] = idy;
mdata[mindx][1] = new double [1];
mdata[mindx][1][0] = z;
mdata[mindx][2] = new double [1];
mdata[mindx][2][0] =w;
mindx++;
}
}
}
double[][] approx2d = pa.quadraticApproximation(
mdata,
true, // boolean forceLinear, // use linear approximation
damping, // double [] damping, null OK
-1); // debug level
new_defined[nTile] = true;
// z_tilts= new double [] { approx2d[0][2], approx2d[0][0], approx2d[0][1]};
// double z = zdisp / (ref_disparity[nTile] + inf_disp);
double z0 = approx2d[0][2];
ref_disparity[nTile] = zdisp / z0 - inf_disp;
afilled.getAndIncrement();
} else {
acounter.getAndIncrement();
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (afilled.get() > 0) {
total_filled+= afilled.get();
System.arraycopy(new_defined, 0, defined, 0, ref_disparity.length);
} else {
break;
}
}
return total_filled; // acounter.get() - remains not filled
}
public static boolean [] fillWeakTiles(
final double [] ref_disparity,
final int [] corr_mode,
final int min_neibs_fill, // = 4;
final int tilesX,
final int tilesY
){
double [] nwo = {0.7, 0.5};
final double [] dir_weights = new double[] {nwo[0],nwo[1],nwo[0],nwo[1],nwo[0],nwo[1],nwo[0],nwo[1]};
final TileNeibs tn = new TileNeibs(tilesX,tilesY);
final double [] ref_disparity_in = ref_disparity.clone();
final boolean [] defined = new boolean [tilesX*tilesY];
final boolean [] new_defined = new boolean [tilesX*tilesY];
final int max_try_fill = tilesX+tilesY;
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger acounter = new AtomicInteger(0);
final AtomicInteger afilled = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
for (boolean weak_only: new boolean[] {true, false}) {
// set initial defined, count number of undefined to be filled, update when switching to all from neibs only
// Arrays.fill(defined, false);
ai.set(0);
acounter.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < corr_mode.length; nTile = ai.getAndIncrement())
if (!defined[nTile]) { // only add new that were not defined before
switch (corr_mode[nTile] ) {
case MODE_STRONG:
if (weak_only) break;
case MODE_NEIB:
defined[nTile] = true;
break;
case MODE_WEAK:
acounter.getAndIncrement();
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (acounter.get() == 0) {
continue; // no points to adjust
}
// System.arraycopy(ref_disparity, 0, ref_disparity_in, 0, ref_disparity.length);
System.arraycopy(defined, 0, new_defined, 0, ref_disparity.length);
for (int nfill = 0; nfill < max_try_fill; nfill++) {
// System.arraycopy(ref_disparity, 0, ref_disparity_in, 0, ref_disparity.length);
// System.arraycopy(defined, 0, new_defined, 0, ref_disparity.length);
ai.set(0);
acounter.set(0);
afilled.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < corr_mode.length; nTile = ai.getAndIncrement())
if ((corr_mode[nTile] == MODE_WEAK ) && !defined[nTile]){
// acounter.getAndIncrement(); // left to fill
// see if any defined neighbor
int num_neibs = 0;
double sw=0, swd=0;
for (int dir = 0; dir < TileNeibs.DIRS; dir++) {
int tile1 = tn.getNeibIndex(nTile, dir);
if ((tile1 >=0) && defined[tile1]){
double w = dir_weights[dir]; // use strength?
sw += w;
swd += w * ref_disparity_in[tile1];
num_neibs++;
}
}
if (num_neibs >= min_neibs_fill) {
ref_disparity[nTile] = swd/sw;
new_defined[nTile] = true;
afilled.getAndIncrement();
} else {
acounter.getAndIncrement(); // left unfilled
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (afilled.get() > 0) {
System.arraycopy(ref_disparity, 0, ref_disparity_in, 0, ref_disparity.length);
System.arraycopy(new_defined, 0, defined, 0, ref_disparity.length);
if (acounter.get() == 0) {
break; // this run filled all remaining
}
} else {
break; // for (int nfill = 0; nfill < max_try_fill; nfill++)
}
}
}
// return acounter.get();
return defined;
}
public static void averageNeighborsDisparity(
final double [] ref_disparity,
final int [] corr_mode,
final int tilesX,
final int tilesY
) {
double [] nwo = {0.7, 0.5};
final double [] dir_weights = new double[] {nwo[0],nwo[1],nwo[0],nwo[1],nwo[0],nwo[1],nwo[0],nwo[1]};
final TileNeibs tn = new TileNeibs(tilesX,tilesY);
final double [] ref_disparity_in = ref_disparity.clone();
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < corr_mode.length; nTile = ai.getAndIncrement())
if (corr_mode[nTile] == MODE_NEIB){ // only neighbors
double sw = 1, swd = ref_disparity_in[nTile];
for (int dir = 0; dir < TileNeibs.DIRS; dir++) {
int tile1 = tn.getNeibIndex(nTile, dir);
if ((tile1 >=0) && (corr_mode[tile1] == MODE_NEIB)){
double w = dir_weights[dir]; // use strength?
sw += w;
swd += w * ref_disparity_in[tile1];
}
}
ref_disparity[nTile] = swd/sw;
}
}
};
}
ImageDtt.startAndJoin(threads);
}
/** /**
* Calculate SfM disparity correction from a set of scene pairs with approximately * Calculate SfM disparity correction from a set of scene pairs with approximately
...@@ -1276,16 +1643,23 @@ public class StructureFromMotion { ...@@ -1276,16 +1643,23 @@ public class StructureFromMotion {
final double fade_sigma, final double fade_sigma,
final SfmCorr [] sfmCorr, final SfmCorr [] sfmCorr,
final int tilesX) { final int tilesX) {
final int extra = sfm_shrink + (int)Math.ceil(fade_sigma);
final int tilesY = sfmCorr.length / tilesX; final int tilesY = sfmCorr.length / tilesX;
final TileNeibs tn = new TileNeibs(tilesX,tilesY);
final boolean [] sfm_defined = new boolean [sfmCorr.length]; final int tilesX_extra = tilesX+2*extra;
final int tilesY_extra = tilesY+2*extra;
final boolean [] sfm_defined_extra = new boolean [tilesX_extra*tilesY_extra];
final TileNeibs tn = new TileNeibs(tilesX_extra,tilesY_extra);
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
for (int nTile = ai.getAndIncrement(); nTile < sfmCorr.length; nTile = ai.getAndIncrement()) if (sfmCorr[nTile] != null){ for (int nTile = ai.getAndIncrement(); nTile < sfmCorr.length; nTile = ai.getAndIncrement()) if (sfmCorr[nTile] != null){
sfm_defined[nTile] = sfmCorr[nTile].sfm_gain > 0; int tileX = nTile % tilesX + extra;
int tileY = nTile / tilesX + extra;
int nTile_extra=tileX + tileY * tilesX_extra;
sfm_defined_extra[nTile_extra] = sfmCorr[nTile].sfm_gain > 0;
} }
} }
}; };
...@@ -1293,17 +1667,17 @@ public class StructureFromMotion { ...@@ -1293,17 +1667,17 @@ public class StructureFromMotion {
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
if (sfm_shrink > 0) { if (sfm_shrink > 0) {
tn.shrinkSelection( tn.shrinkSelection(
sfm_shrink, // final int shrink, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more sfm_shrink, // final int shrink, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
sfm_defined, // final boolean [] tiles, sfm_defined_extra, // final boolean [] tiles,
null); // final boolean [] prohibit) null); // final boolean [] prohibit)
} }
if (fade_sigma > 0) { if (fade_sigma > 0) {
final double [] gain_scale = new double [sfm_defined.length]; final double [] gain_scale = new double [sfm_defined_extra.length];
ai.set(0); ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
for (int nTile = ai.getAndIncrement(); nTile < sfmCorr.length; nTile = ai.getAndIncrement()) if (sfm_defined[nTile]){ for (int nTile = ai.getAndIncrement(); nTile < sfm_defined_extra.length; nTile = ai.getAndIncrement()) if (sfm_defined_extra[nTile]){
gain_scale[nTile] = 2.0; gain_scale[nTile] = 2.0;
} }
} }
...@@ -1311,16 +1685,18 @@ public class StructureFromMotion { ...@@ -1311,16 +1685,18 @@ public class StructureFromMotion {
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
DoubleGaussianBlur gb = new DoubleGaussianBlur(); DoubleGaussianBlur gb = new DoubleGaussianBlur();
gb.blurDouble(gain_scale, tilesX, tilesY, fade_sigma, fade_sigma, 0.01); gb.blurDouble(gain_scale, tilesX_extra, tilesY_extra, fade_sigma, fade_sigma, 0.01);
ai.set(0); ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
for (int nTile = ai.getAndIncrement(); nTile < sfmCorr.length; nTile = ai.getAndIncrement()) if (sfmCorr[nTile] != null){ for (int nTile = ai.getAndIncrement(); nTile < sfmCorr.length; nTile = ai.getAndIncrement()) if (sfmCorr[nTile] != null){
if (sfm_defined[nTile]) { int tileX = nTile % tilesX + extra;
double g = gain_scale[nTile]-1; int tileY = nTile / tilesX + extra;
sfmCorr[nTile].sfm_gain *= g * g; int nTile_extra=tileX + tileY * tilesX_extra;
if (sfm_defined_extra[nTile_extra]) {
double g = gain_scale[nTile_extra]-1;
sfmCorr[nTile].sfm_gain *= g * g;
} else { } else {
sfmCorr[nTile].sfm_gain = 0.0; // null; // or use sfmCorr[nTile] = null? sfmCorr[nTile].sfm_gain = 0.0; // null; // or use sfmCorr[nTile] = null?
} }
......
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