Commit ab19db78 authored by Andrey Filippov's avatar Andrey Filippov

cluster texture output

parent 2717c448
...@@ -47,7 +47,7 @@ public class CorrectionColorProc { ...@@ -47,7 +47,7 @@ public class CorrectionColorProc {
void setDebug(int debugLevel){this.debugLevel=debugLevel;} void setDebug(int debugLevel){this.debugLevel=debugLevel;}
public void processColorsWeights(ImageStack stack, public void processColorsWeights(ImageStack stack, // does not like NaN (in GaussianBlur
double scale, // initial maximal pixel value (16)) double scale, // initial maximal pixel value (16))
EyesisCorrectionParameters.ColorProcParameters colorProcParameters, EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters, CorrectionColorProc.ColorGainsParameters channelGainParameters,
...@@ -107,7 +107,7 @@ public class CorrectionColorProc { ...@@ -107,7 +107,7 @@ public class CorrectionColorProc {
for (i=0;i<length;i++) { for (i=0;i<length;i++) {
double Y=Ar*fpixels_r[i]+Ag*fpixels_g[i]+Ab*fpixels_b[i]; double Y=Ar*fpixels_r[i]+Ag*fpixels_g[i]+Ab*fpixels_b[i];
Y=linGamma(colorProcParameters.gamma, gamma_a, gamma_linK, colorProcParameters.minLin, Y)/Y; Y= (Y !=0.0) ? (linGamma(colorProcParameters.gamma, gamma_a, gamma_linK, colorProcParameters.minLin, Y)/Y): 0.0;
fpixels_r[i]*=Y*gain_red; fpixels_r[i]*=Y*gain_red;
fpixels_g[i]*=Y*gain_green; fpixels_g[i]*=Y*gain_green;
fpixels_b[i]*=Y*gain_blue; fpixels_b[i]*=Y*gain_blue;
...@@ -151,7 +151,7 @@ public class CorrectionColorProc { ...@@ -151,7 +151,7 @@ public class CorrectionColorProc {
double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue; double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue;
double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed; double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed;
double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue; double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue;
if (debugLevel>1) { if (debugLevel> 1) {
System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue); System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue);
System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK); System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK);
System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb); System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb);
...@@ -221,7 +221,7 @@ public class CorrectionColorProc { ...@@ -221,7 +221,7 @@ public class CorrectionColorProc {
gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01); gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pr_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01); gb.blurDouble(dpixels_pr_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
gb.blurDouble(dpixels_pb_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01); gb.blurDouble(dpixels_pb_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
if (debugLevel>2) { if (debugLevel> 2) {
SDFA_INSTANCE.showArrays(dmask, width, height,"dmask"); SDFA_INSTANCE.showArrays(dmask, width, height,"dmask");
SDFA_INSTANCE.showArrays(dpixels_pr, width, height,"dpixels_pr"); SDFA_INSTANCE.showArrays(dpixels_pr, width, height,"dpixels_pr");
SDFA_INSTANCE.showArrays(dpixels_pb, width, height,"dpixels_pb"); SDFA_INSTANCE.showArrays(dpixels_pb, width, height,"dpixels_pb");
...@@ -340,7 +340,7 @@ public class CorrectionColorProc { ...@@ -340,7 +340,7 @@ public class CorrectionColorProc {
double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue; double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue;
double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed; double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed;
double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue; double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue;
if (debugLevel>1) { if (debugLevel > 1) {
System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue); System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue);
System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK); System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK);
System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb); System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb);
......
...@@ -2022,6 +2022,8 @@ public class EyesisCorrectionParameters { ...@@ -2022,6 +2022,8 @@ public class EyesisCorrectionParameters {
public double bgnd_maybe = 0.1; // maximal strength to ignore as non-background public double bgnd_maybe = 0.1; // maximal strength to ignore as non-background
// public double bgnd_2diff = 0.005; // maximal strength to ignore as non-background // public double bgnd_2diff = 0.005; // maximal strength to ignore as non-background
public int min_clstr_seed = 2; // number of tiles in a cluster to seed (just background?) public int min_clstr_seed = 2; // number of tiles in a cluster to seed (just background?)
public int min_clstr_lone = 4; // number of tiles in a cluster not close to other clusters (more than 2 tiles apart)
public int fill_gaps = 4; // same as in grow - 1: 4 directions by 1 step, 2: 8 directions by 1 step. +2*n - alternating hor/vert
public int min_clstr_block = 3; // number of tiles in a cluster to block (just non-background?) public int min_clstr_block = 3; // number of tiles in a cluster to block (just non-background?)
public int bgnd_grow = 2; // number of tiles to grow (1 - hor/vert, 2 - hor/vert/diagonal) public int bgnd_grow = 2; // number of tiles to grow (1 - hor/vert, 2 - hor/vert/diagonal)
...@@ -2143,6 +2145,8 @@ public class EyesisCorrectionParameters { ...@@ -2143,6 +2145,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"bgnd_sure", this.bgnd_sure +""); properties.setProperty(prefix+"bgnd_sure", this.bgnd_sure +"");
properties.setProperty(prefix+"bgnd_maybe", this.bgnd_maybe +""); properties.setProperty(prefix+"bgnd_maybe", this.bgnd_maybe +"");
properties.setProperty(prefix+"min_clstr_seed", this.min_clstr_seed+""); properties.setProperty(prefix+"min_clstr_seed", this.min_clstr_seed+"");
properties.setProperty(prefix+"min_clstr_lone", this.min_clstr_lone+"");
properties.setProperty(prefix+"fill_gaps", this.fill_gaps+"");
properties.setProperty(prefix+"min_clstr_block", this.min_clstr_block+""); properties.setProperty(prefix+"min_clstr_block", this.min_clstr_block+"");
properties.setProperty(prefix+"bgnd_grow", this.bgnd_grow+""); properties.setProperty(prefix+"bgnd_grow", this.bgnd_grow+"");
properties.setProperty(prefix+"ortho_min_hor", this.ortho_min_hor +""); properties.setProperty(prefix+"ortho_min_hor", this.ortho_min_hor +"");
...@@ -2255,6 +2259,8 @@ public class EyesisCorrectionParameters { ...@@ -2255,6 +2259,8 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"bgnd_sure")!=null) this.bgnd_sure=Double.parseDouble(properties.getProperty(prefix+"bgnd_sure")); if (properties.getProperty(prefix+"bgnd_sure")!=null) this.bgnd_sure=Double.parseDouble(properties.getProperty(prefix+"bgnd_sure"));
if (properties.getProperty(prefix+"bgnd_maybe")!=null) this.bgnd_maybe=Double.parseDouble(properties.getProperty(prefix+"bgnd_maybe")); if (properties.getProperty(prefix+"bgnd_maybe")!=null) this.bgnd_maybe=Double.parseDouble(properties.getProperty(prefix+"bgnd_maybe"));
if (properties.getProperty(prefix+"min_clstr_seed")!=null) this.min_clstr_seed=Integer.parseInt(properties.getProperty(prefix+"min_clstr_seed")); if (properties.getProperty(prefix+"min_clstr_seed")!=null) this.min_clstr_seed=Integer.parseInt(properties.getProperty(prefix+"min_clstr_seed"));
if (properties.getProperty(prefix+"min_clstr_lone")!=null) this.min_clstr_lone=Integer.parseInt(properties.getProperty(prefix+"min_clstr_lone"));
if (properties.getProperty(prefix+"fill_gaps")!=null) this.fill_gaps=Integer.parseInt(properties.getProperty(prefix+"fill_gaps"));
if (properties.getProperty(prefix+"min_clstr_block")!=null) this.min_clstr_block=Integer.parseInt(properties.getProperty(prefix+"min_clstr_block")); if (properties.getProperty(prefix+"min_clstr_block")!=null) this.min_clstr_block=Integer.parseInt(properties.getProperty(prefix+"min_clstr_block"));
if (properties.getProperty(prefix+"bgnd_grow")!=null) this.bgnd_grow=Integer.parseInt(properties.getProperty(prefix+"bgnd_grow")); if (properties.getProperty(prefix+"bgnd_grow")!=null) this.bgnd_grow=Integer.parseInt(properties.getProperty(prefix+"bgnd_grow"));
if (properties.getProperty(prefix+"ortho_min_hor")!=null) this.ortho_min_hor=Double.parseDouble(properties.getProperty(prefix+"ortho_min_hor")); if (properties.getProperty(prefix+"ortho_min_hor")!=null) this.ortho_min_hor=Double.parseDouble(properties.getProperty(prefix+"ortho_min_hor"));
...@@ -2382,6 +2388,8 @@ public class EyesisCorrectionParameters { ...@@ -2382,6 +2388,8 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Maximal strength to ignore as non-background", this.bgnd_maybe, 3); gd.addNumericField("Maximal strength to ignore as non-background", this.bgnd_maybe, 3);
gd.addNumericField("Number of tiles in a cluster to seed (just background?)", this.min_clstr_seed, 0); gd.addNumericField("Number of tiles in a cluster to seed (just background?)", this.min_clstr_seed, 0);
gd.addNumericField("Number of tiles in a cluster not close to other clusters (more than 2 tiles apart)", this.min_clstr_lone, 0);
gd.addNumericField("Fill gaps betsween clusters, see comments for 'grow'", this.fill_gaps, 0);
gd.addNumericField("Number of tiles in a cluster to block (just non-background?)", this.min_clstr_block, 0); gd.addNumericField("Number of tiles in a cluster to block (just non-background?)", this.min_clstr_block, 0);
gd.addNumericField("Number of tiles to grow tile selection (1 - hor/vert, 2 - hor/vert/diagonal)", this.bgnd_grow, 0); gd.addNumericField("Number of tiles to grow tile selection (1 - hor/vert, 2 - hor/vert/diagonal)", this.bgnd_grow, 0);
...@@ -2503,6 +2511,8 @@ public class EyesisCorrectionParameters { ...@@ -2503,6 +2511,8 @@ public class EyesisCorrectionParameters {
this.bgnd_sure= gd.getNextNumber(); this.bgnd_sure= gd.getNextNumber();
this.bgnd_maybe= gd.getNextNumber(); this.bgnd_maybe= gd.getNextNumber();
this.min_clstr_seed= (int) gd.getNextNumber(); this.min_clstr_seed= (int) gd.getNextNumber();
this.min_clstr_lone= (int) gd.getNextNumber();
this.fill_gaps= (int) gd.getNextNumber();
this.min_clstr_block= (int) gd.getNextNumber(); this.min_clstr_block= (int) gd.getNextNumber();
this.bgnd_grow= (int) gd.getNextNumber(); this.bgnd_grow= (int) gd.getNextNumber();
this.ortho_min_hor= gd.getNextNumber(); this.ortho_min_hor= gd.getNextNumber();
......
...@@ -1398,7 +1398,7 @@ public class EyesisCorrections { ...@@ -1398,7 +1398,7 @@ public class EyesisCorrections {
break; break;
} }
} }
if (debugLevel>2) { if (debugLevel > 2) {
System.out.println ( "Input file color slice numbers:"); System.out.println ( "Input file color slice numbers:");
System.out.println ( " Red - slice "+((rgbNumbers[0]>0)?rgbNumbers[0]:"missing")); System.out.println ( " Red - slice "+((rgbNumbers[0]>0)?rgbNumbers[0]:"missing"));
System.out.println ( " Green - slice "+((rgbNumbers[1]>0)?rgbNumbers[1]:"missing")); System.out.println ( " Green - slice "+((rgbNumbers[1]>0)?rgbNumbers[1]:"missing"));
......
...@@ -70,7 +70,7 @@ public class EyesisTiff { ...@@ -70,7 +70,7 @@ public class EyesisTiff {
int width = imp.getWidth(); int width = imp.getWidth();
int height = imp.getHeight(); int height = imp.getHeight();
int [] pixels = (int []) imp.getProcessor().getPixels(); int [] pixels = (int []) imp.getProcessor().getPixels();
System.out.println("width="+width+", height="+height+" length="+pixels.length); System.out.println("savePNG_ARGB32("+path+"): width="+width+", height="+height+" length="+pixels.length);
DataBufferInt buffer = new DataBufferInt(pixels, pixels.length); DataBufferInt buffer = new DataBufferInt(pixels, pixels.length);
......
...@@ -1044,7 +1044,7 @@ public class ImageDtt { ...@@ -1044,7 +1044,7 @@ public class ImageDtt {
if (i == (transform_size-1)) enh_ortho_scale[i] = 0.0 ; // hardwired 0 in the center if (i == (transform_size-1)) enh_ortho_scale[i] = 0.0 ; // hardwired 0 in the center
enh_ortho_scale[i] *= Math.sin(Math.PI*(i+1.0)/(2*transform_size)); enh_ortho_scale[i] *= Math.sin(Math.PI*(i+1.0)/(2*transform_size));
} }
if (globalDebugLevel > -1){ if (globalDebugLevel > 0){
System.out.println("enhortho_width="+ enhortho_width+" enhortho_scale="+ enhortho_scale); System.out.println("enhortho_width="+ enhortho_width+" enhortho_scale="+ enhortho_scale);
for (int i = 0; i < corr_size; i++){ for (int i = 0; i < corr_size; i++){
System.out.println(" enh_ortho_scale["+i+"]="+ enh_ortho_scale[i]); System.out.println(" enh_ortho_scale["+i+"]="+ enh_ortho_scale[i]);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
*/ */
import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -3352,8 +3353,8 @@ public class QuadCLT { ...@@ -3352,8 +3353,8 @@ public class QuadCLT {
true, // boolean saveShowIntermediate, // save/show if set globally true, // boolean saveShowIntermediate, // save/show if set globally
true, // boolean saveShowFinal, // save/show result (color image?) true, // boolean saveShowFinal, // save/show result (color image?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb), ((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tp.tilesX, tp.tilesX * clt_parameters.transform_size,
tp.tilesY, tp.tilesY * clt_parameters.transform_size,
1.0, // double scaleExposure, // is it needed? 1.0, // double scaleExposure, // is it needed?
debugLevel ); debugLevel );
} }
...@@ -3521,8 +3522,8 @@ public class QuadCLT { ...@@ -3521,8 +3522,8 @@ public class QuadCLT {
true, // boolean saveShowIntermediate, // save/show if set globally true, // boolean saveShowIntermediate, // save/show if set globally
false, // boolean saveShowFinal, // save/show result (color image?) false, // boolean saveShowFinal, // save/show result (color image?)
iclt_data, iclt_data,
tp.tilesX, tp.tilesX * clt_parameters.transform_size,
tp.tilesY, tp.tilesY * clt_parameters.transform_size,
scaleExposures[iQuad], // double scaleExposure, // is it needed? scaleExposures[iQuad], // double scaleExposure, // is it needed?
debugLevel ); debugLevel );
...@@ -3551,6 +3552,39 @@ public class QuadCLT { ...@@ -3551,6 +3552,39 @@ public class QuadCLT {
return results; return results;
} }
double [][] resizeGridTexture(
double [][] imgData,
int tileSize,
int tilesX,
int tilesY,
Rectangle bounds){
int width = tileSize*bounds.width + 1;
int height = tileSize*bounds.height + 1;
// Adding row/column of all 0, assuming java zeroes arrays
int numSlices = imgData.length;
double [][] rslt = new double [numSlices][width*height];
int offset = (tileSize*bounds.y)*tileSize*tilesX + (tileSize*bounds.x);
// System.out.println("bounds = {.x:"+bounds.x + ", .y=" + bounds.y + ", .width=" + bounds.width + ", .height=" + bounds.height+ ", numSlices="+numSlices);
// System.out.println("offset = " + offset+ " tileSize = "+tileSize);
for (int y = 0; y < (height - 1); y ++){
for (int x = 0; x < width-1; x ++){
int indx = width * y + x;
int indx_in = indx + offset;
for (int i = 0; i < numSlices; i++) {
rslt[i][indx] = Double.isNaN(imgData[i][indx_in])? 0.0:imgData[i][indx_in];
// if ((imgData[i][indx_in] !=0.0) && (i ==3))
// {
// int a = 0;
// int b = a;
// }
}
}
offset += tilesX * tileSize - width;
}
return rslt;
}
public ImagePlus linearStackToColor( public ImagePlus linearStackToColor(
EyesisCorrectionParameters.CLTParameters clt_parameters, EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters, EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
...@@ -3562,8 +3596,8 @@ public class QuadCLT { ...@@ -3562,8 +3596,8 @@ public class QuadCLT {
boolean saveShowIntermediate, // save/show if set globally boolean saveShowIntermediate, // save/show if set globally
boolean saveShowFinal, // save/show result (color image?) boolean saveShowFinal, // save/show result (color image?)
double [][] iclt_data, double [][] iclt_data,
int tilesX, int width, // int tilesX,
int tilesY, int height, // int tilesY,
double scaleExposure, double scaleExposure,
int debugLevel int debugLevel
) )
...@@ -3576,14 +3610,15 @@ public class QuadCLT { ...@@ -3576,14 +3610,15 @@ public class QuadCLT {
if (iclt_data.length > 3) alpha = iclt_data[3]; if (iclt_data.length > 3) alpha = iclt_data[3];
ImageStack stack = sdfa_instance.makeStack( ImageStack stack = sdfa_instance.makeStack(
rgb_in, // iclt_data, rgb_in, // iclt_data,
(tilesX + 0) * clt_parameters.transform_size, width, // (tilesX + 0) * clt_parameters.transform_size,
(tilesY + 0) * clt_parameters.transform_size, height, // (tilesY + 0) * clt_parameters.transform_size,
sliceNames); // or use null to get chn-nn slice names sliceNames, // or use null to get chn-nn slice names
if (debugLevel > -1){ true); // replace NaN with 0.0
if (debugLevel > 0){
double [] chn_avg = {0.0,0.0,0.0}; double [] chn_avg = {0.0,0.0,0.0};
float [] pixels; float [] pixels;
int width = stack.getWidth(); // int width = stack.getWidth();
int height = stack.getHeight(); // int height = stack.getHeight();
for (int c = 0; c <3; c++){ for (int c = 0; c <3; c++){
pixels = (float[]) stack.getPixels(c+1); pixels = (float[]) stack.getPixels(c+1);
...@@ -4704,6 +4739,57 @@ public class QuadCLT { ...@@ -4704,6 +4739,57 @@ public class QuadCLT {
path+=Prefs.getFileSeparator()+name+".x3d"; path+=Prefs.getFileSeparator()+name+".x3d";
x3dOutput.generateX3D(path); x3dOutput.generateX3D(path);
} }
// testing 2-nd pass
tp.secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
clt_parameters,
// disparity range - differences from
clt_parameters.bgnd_range, // double disparity_far,
clt_parameters.other_range, //double disparity_near, //
clt_parameters.bgnd_sure, // double this_sure, // minimal strength to be considered definitely background
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background
clt_parameters.sure_smth, // sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
ImageDtt.DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
// get images for predefined regions and dispariteies. First - with just fixed scans 1 .. list.size()
for (int scanIndex = 1; scanIndex < tp.clt_3d_passes.size(); scanIndex++){
if (debugLevel > 0){
System.out.println("FPGA processing scan #"+scanIndex);
}
TileProcessor.CLTPass3d scan = CLTMeasure( // perform single pass according to prepared tiles operations and disparity
image_data, // first index - number of image in a quad
clt_parameters,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
}
int scan_limit = 10;
for (int scanIndex = 1; (scanIndex < tp.clt_3d_passes.size()) && (scanIndex < scan_limit); scanIndex++){ // just temporary limiting
if (debugLevel > -1){
System.out.println("Generating cluster images, hardwired limit of "+scan_limit+" largest, scan #"+scanIndex);
}
ImagePlus cluster_image = getPassImage( // get image form a single pass
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-img"+scanIndex,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
}
// now generate and save texture files (start with full, later use bounding rectangle?)
return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name"); return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
} }
...@@ -4738,11 +4824,14 @@ public class QuadCLT { ...@@ -4738,11 +4824,14 @@ public class QuadCLT {
boolean [] bgnd_strict = bgnd_tiles.clone(); // only these have non 0 alpha boolean [] bgnd_strict = bgnd_tiles.clone(); // only these have non 0 alpha
tp.growTiles( tp.growTiles(
clt_parameters.bgnd_grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more clt_parameters.bgnd_grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
bgnd_tiles); bgnd_tiles,
null); // prohibit
boolean [] bgnd_tiles_grown = bgnd_tiles.clone(); // only these have non 0 alpha boolean [] bgnd_tiles_grown = bgnd_tiles.clone(); // only these have non 0 alpha
tp.growTiles( tp.growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more 2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
bgnd_tiles); bgnd_tiles,
null); // prohibit
bgnd_data.selected = bgnd_tiles_grown; // selected for background w/o extra transparent layer bgnd_data.selected = bgnd_tiles_grown; // selected for background w/o extra transparent layer
if (sdfa_instance!=null){ if (sdfa_instance!=null){
...@@ -4813,8 +4902,8 @@ public class QuadCLT { ...@@ -4813,8 +4902,8 @@ public class QuadCLT {
true, // boolean saveShowIntermediate, // save/show if set globally true, // boolean saveShowIntermediate, // save/show if set globally
false, //true, // boolean saveShowFinal, // save/show result (color image?) false, //true, // boolean saveShowFinal, // save/show result (color image?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb), ((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tp.tilesX, tp.tilesX * clt_parameters.transform_size,
tp.tilesY, tp.tilesY * clt_parameters.transform_size,
1.0, // double scaleExposure, // is it needed? 1.0, // double scaleExposure, // is it needed?
debugLevel); debugLevel);
// resize for backdrop here! // resize for backdrop here!
...@@ -4842,28 +4931,124 @@ public class QuadCLT { ...@@ -4842,28 +4931,124 @@ public class QuadCLT {
correctionsParameters.png, correctionsParameters.png,
clt_parameters.show_textures, clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG -1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
return imp_texture_bgnd_ext;
}
// testing 2-nd pass
tp.secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad public ImagePlus getPassImage( // get image form a single pass
clt_parameters, EyesisCorrectionParameters.CLTParameters clt_parameters,
// disparity range - differences from EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
clt_parameters.bgnd_range, // double disparity_far, EyesisCorrectionParameters.RGBParameters rgbParameters,
clt_parameters.other_range, //double disparity_near, // String name,
clt_parameters.bgnd_sure, // double this_sure, // minimal strength to be considered definitely background int scanIndex,
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background int threadsMax, // maximal number of threads to launch
clt_parameters.sure_smth, // sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd boolean updateStatus,
disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4) int debugLevel)
{
// showDoubleFloatArrays sdfa_instance = null;
// if (clt_parameters.debug_filters && (debugLevel > -1)) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
boolean [] borderTiles = scan.border_tiles;
double [][][][] texture_tiles = scan.texture_tiles;
// boolean [] selected = scan.getAllSelected(); // all selected, including border
scan.updateSelection(); // update .selected field (all selected, including border) and Rectangle bounds
// scan.selected = selected; // selected for background w/o extra transparent layer
double [][][][] texture_tiles_cluster = new double[tp.tilesY][tp.tilesX][][];
double [] alpha_zero = new double [4*clt_parameters.transform_size*clt_parameters.transform_size];
int alpha_index = 3;
for (int i = 0; i < alpha_zero.length; i++) alpha_zero[i]=0.0;
for (int tileY = 0; tileY < tp.tilesY; tileY++){
for (int tileX = 0; tileX < tp.tilesX; tileX++){
texture_tiles_cluster[tileY][tileX]= null;
if (texture_tiles[tileY][tileX] != null) {
if (borderTiles[tileY * tp.tilesX + tileX]) {
texture_tiles_cluster[tileY][tileX]= texture_tiles[tileY][tileX].clone();
texture_tiles_cluster[tileY][tileX][alpha_index] = alpha_zero;
}else{
texture_tiles_cluster[tileY][tileX]= texture_tiles[tileY][tileX];
}
}
}
}
ImageDtt image_dtt = new ImageDtt();
double [][] texture_overlap = image_dtt.combineRGBATiles(
texture_tiles_cluster, // texture_tiles, // array [tp.tilesY][tp.tilesX][4][4*transform_size] or [tp.tilesY][tp.tilesX]{null}
clt_parameters.transform_size,
true, // when false - output each tile as 16x16, true - overlap to make 8x8
clt_parameters.sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
threadsMax, // maximal number of threads to launch threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel); debugLevel);
if (clt_parameters.alpha1 > 0){ // negative or 0 - keep alpha as it was
double scale = (clt_parameters.alpha1 > clt_parameters.alpha0) ? (1.0/(clt_parameters.alpha1 - clt_parameters.alpha0)) : 0.0;
for (int i = 0; i < texture_overlap[alpha_index].length; i++){
double d = texture_overlap[alpha_index][i];
if (d >=clt_parameters.alpha1) d = 1.0;
else if (d <=clt_parameters.alpha0) d = 0.0;
else d = scale * (d- clt_parameters.alpha0);
texture_overlap[alpha_index][i] = d;
}
}
// for now - use just RGB. Later add oprion for RGBA
double [][] texture_rgb = {texture_overlap[0],texture_overlap[1],texture_overlap[2]};
double [][] texture_rgba = {texture_overlap[0],texture_overlap[1],texture_overlap[2],texture_overlap[3]};
double [][] texture_rgbx = ((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb);
// sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// sdfa_instance.showArrays(texture_rgbx, clt_parameters.transform_size * tp.tilesX, clt_parameters.transform_size * tp.tilesY, true, "texture_rgbx_full");
boolean resize = true;
if (resize) {
texture_rgbx = resizeGridTexture(
texture_rgbx,
clt_parameters.transform_size,
tp.tilesX,
tp.tilesY,
scan.bounds);
}
return imp_texture_bgnd_ext;
int width = resize ? (clt_parameters.transform_size * scan.bounds.width + 1): (clt_parameters.transform_size * tp.tilesX);
int height = resize ? (clt_parameters.transform_size * scan.bounds.height + 1): (clt_parameters.transform_size * tp.tilesY);
// sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// sdfa_instance.showArrays(texture_rgbx, width, height, true, "texture_rgbx");
ImagePlus imp_texture_cluster = linearStackToColor(
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-texture", // String name,
"", //String suffix, // such as disparity=...
true, // toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
true, // boolean saveShowIntermediate, // save/show if set globally
false, //true, // boolean saveShowFinal, // save/show result (color image?)
texture_rgbx,
width, //tp.tilesX * clt_parameters.transform_size,
height, //tp.tilesY * clt_parameters.transform_size,
1.0, // double scaleExposure, // is it needed?
debugLevel);
String path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
// only show/save original size if debug or debug_filters)
eyesisCorrections.saveAndShow(
imp_texture_cluster,
path,
correctionsParameters.png,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
return imp_texture_cluster;
} }
public ImagePlus resizeForBackdrop(ImagePlus imp, int debugLevel){ public ImagePlus resizeForBackdrop(ImagePlus imp, int debugLevel){
double backdropPixels = 2.0/geometryCorrection.getFOVPix(); double backdropPixels = 2.0/geometryCorrection.getFOVPix();
if (debugLevel > -1) { if (debugLevel > -1) {
...@@ -4987,4 +5172,90 @@ public class QuadCLT { ...@@ -4987,4 +5172,90 @@ public class QuadCLT {
return scan_rslt; return scan_rslt;
} }
public TileProcessor.CLTPass3d CLTMeasure( // perform single pass according to prepared tiles operations and disparity
final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int scanIndex,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
int [][] tile_op = scan.tile_op;
double [][] disparity_array = scan.disparity;
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][tp.tilesY][tp.tilesX][]; // will only be used inside?
double min_corr_selected = clt_parameters.min_corr;
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
double [][][][] texture_tiles = new double [tp.tilesY][tp.tilesX][][]; // ["RGBA".length()][];
ImageDtt image_dtt = new ImageDtt();
image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
image_data, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tp.tilesY][tp.tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_map, // [12][tp.tilesY * tp.tilesX]
texture_tiles, // [tp.tilesY][tp.tilesX]["RGBA".length()][];
tp.tilesX * clt_parameters.transform_size, // imp_quad[0].getWidth(), // final int width,
clt_parameters.fat_zero, // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
clt_parameters.corr_sym,
clt_parameters.corr_offset,
clt_parameters.corr_red,
clt_parameters.corr_blue,
clt_parameters.corr_sigma,
clt_parameters.corr_normalize, // normalize correlation results by rms
min_corr_selected, // 0.0001; // minimal correlation value to consider valid
clt_parameters.max_corr_sigma,// 1.5; // weights of points around global max to find fractional
clt_parameters.max_corr_radius,
clt_parameters.enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
clt_parameters.enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
clt_parameters.max_corr_double, // Double pass when masking center of mass to reduce preference for integer values
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
(clt_parameters.fcorr_ignore? null: this.fine_corr),
clt_parameters.corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
(clt_parameters.dbg_mode & 64) != 0, // no fract shift
(clt_parameters.dbg_mode & 128) != 0, // no convolve
// (clt_parameters.dbg_mode & 256) != 0, // transpose convolve
threadsMax,
debugLevel);
scan.disparity_map = disparity_map;
scan.texture_tiles = texture_tiles;
return scan;
}
} }
import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
/** /**
** **
...@@ -39,9 +41,27 @@ public class TileProcessor { ...@@ -39,9 +41,27 @@ public class TileProcessor {
public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX] public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX]
public int [][] tile_op; // what was done in the current pass public int [][] tile_op; // what was done in the current pass
public double [][] disparity_map; // add 4 layers - worst difference for the port public double [][] disparity_map; // add 4 layers - worst difference for the port
public boolean [] border_tiles; // these are border tiles, zero out alpha
public boolean [] selected; // which tiles are selected for this layer public boolean [] selected; // which tiles are selected for this layer
public double [][][][] texture_tiles; public double [][][][] texture_tiles;
public String texture = null; // relative (to x3d) path public String texture = null; // relative (to x3d) path
public Rectangle bounds;
public void updateSelection(){ // add updating border tiles?
selected = new boolean[tilesY*tilesX];
int minX = tilesX, minY = tilesY, maxX = -1, maxY = -1;
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
if (texture_tiles[ty][tx] != null) {
selected[ty * tilesX + tx] = true;
if (maxX < tx) maxX = tx;
if (minX > tx) minX = tx;
if (maxY < ty) maxY = ty;
if (minY > ty) minY = ty;
} else {
selected[ty * tilesX + tx] = false; // may be omitted
}
}
bounds = new Rectangle(minX, minY, maxX - minX +1, maxY - minY +1 );
}
} }
public void resetCLTPasses(){ public void resetCLTPasses(){
...@@ -187,9 +207,327 @@ public class TileProcessor { ...@@ -187,9 +207,327 @@ public class TileProcessor {
return bgnd_tiles; return bgnd_tiles;
} }
public int createTileTasks(
int maxClusters,
int minClusterArea,
double [] disparity_in,
double [] strength_in,
double minStrength,
int [] clusters_in,
double minDisparity,
double maxDisparity,
int debugLevel)
{
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// adding 1-tile frame around to avoid checking for the borders
int tilesX4 = tilesX + 4;
int tilesY4 = tilesY + 4;
int tlen4 = tilesX4*tilesY4;
double [] disparity0 = new double [tlen4];
double [] strength0 = new double [tlen4];
int [] clusters = new int [tlen4];
for (int i = 0; i < tlen4; i++) {
clusters[i] = 0;
strength0[i] = 0.0;
}
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
clusters[(i + 2) * tilesX4 + j + 2] = clusters_in[i * tilesX + j];
strength0[(i + 2) * tilesX4 + j + 2] = strength_in[i * tilesX + j];
disparity0[(i + 2) * tilesX4 + j + 2] = disparity_in[i * tilesX + j];
}
}
int [] dirs8 = {-tilesX4, -tilesX4 + 1, 1, tilesX4 +1, tilesX4, tilesX4 - 1, -1, -tilesX4 - 1};
int [] dirs = dirs8;
int op = ImageDtt.setImgMask(0, 0xf);
op = ImageDtt.setPairMask(op,0xf);
op = ImageDtt.setForcedDisparity(op,true);
int tlen = clusters.length;
int numClusters = 0;
for (int ncl = 0; (maxClusters == 0) || (ncl < maxClusters); ncl++){ // need to break;
double [] strength = strength0.clone();
double [] disparity = disparity0.clone();
boolean [] bcluster = new boolean [tlen];
int clusterSize = 0;
int cindx = ncl + 1;
for (int i = 0; i < tlen; i++) if (clusters[i] == cindx) {
clusterSize++;
bcluster[i] = true;
}
if (debugLevel > 1) {
System.out.println("createTileTasks(), cluster #"+ncl+", cluster size = "+clusterSize);
}
if ((clusterSize < minClusterArea) || (clusterSize == 0)) break;
boolean [] grown_clusters = bcluster.clone();
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown_clusters,
null,
tilesX4,
tilesY4);
// fill missing disparities by a simple method - actually should be done before
int numFailures = 0;
int numSuccesses = 0;
if ( (ncl ==0) && (debugLevel > 0)) {
String [] titles = {"strength","disparity","clusters","grown"};
double [][] dbg_img = new double [titles.length][tilesX4*tilesY4];
for (int i = 0; i < clusters.length; i++){
dbg_img[2][i] = clusters[i];
dbg_img[3][i] = grown_clusters[i]?1:0;
}
dbg_img[0] = strength0;
dbg_img[1] = disparity0;
sdfa_instance.showArrays(dbg_img, tilesX4, tilesY4,true, "createTileTasks",titles);
}
while (true){
numFailures = 0;
numSuccesses = 0;
for (int i = 0; i < tlen ; i++){
if (bcluster[i] && (Double.isNaN(disparity[i]) || (strength[i] < minStrength) || (disparity[i] < minDisparity) || (disparity[i] > maxDisparity))){
double sw =0.0, sd = 0.0;
int n = 0;
for (int d = 0; d < dirs.length; d++){
int indx = i + dirs[d];
if (bcluster[indx] && !Double.isNaN(disparity[indx]) && (strength[indx] > minStrength)){
sw += strength[indx];
sd += strength[indx] * disparity[indx];
n++;
}
}
if (sw >0){
numSuccesses++;
disparity[i] = sd/sw;
strength[i] = sw/n;
} else {
numFailures++;
}
}
}
if (debugLevel > 0) {
System.out.println("createTileTasks(), numFailures="+numFailures+", numSuccesses = "+numSuccesses);
}
if ((numFailures == 0) || (numSuccesses == 0)) break;
}
if (numFailures > 0){
System.out.println("**** Could not fill some missing tiles for cluster # " + cindx + ", numFailures = "+numFailures+" ****");
continue; // with next cluster
}
// now fill border pixels disparity disregarding known for that tile
for (int i = 0; i < tlen ; i++){
if (!bcluster[i] && grown_clusters[i]){ // only border
double sw =0.0, sd = 0.0;
int n = 0;
for (int d = 0; d < dirs.length; d++){
int indx = i + dirs[d];
if (bcluster[indx]){
sw += strength[indx];
sd += strength[indx] * disparity[indx];
n++;
}
}
if (sw >0){
disparity[i] = sd/sw;
strength[i] = sw/n; // will not actually be used
} else {
System.out.println("**** Program BUG, should not happen ****");
disparity[i] = 0.0;
strength[i] = 0.0;
}
}
}
// return to original dimensions
double [][] disparityTask = new double [tilesY][tilesX];
int [][] tile_op = new int [tilesY][tilesX];
boolean [] borderTiles = new boolean[tilesY*tilesX]; // to zero alpha in the images
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx <tilesX; tx++){
int indx = tilesX * ty + tx;
int indx4 = tilesX4 * (ty+2) + (tx + 2);
if (grown_clusters[indx4]){
disparityTask[ty][tx] = disparity[indx4];
tile_op[ty][tx] = op;
borderTiles[indx] = !bcluster[indx4];
} else {
disparityTask[ty][tx] = 0.0;
tile_op[ty][tx] = 0;
borderTiles[indx] = false;
}
}
// Create FPGA task for tis cluster
CLTPass3d scan_next = new CLTPass3d();
scan_next.disparity = disparityTask;
scan_next.tile_op = tile_op;
scan_next.border_tiles = borderTiles;
clt_3d_passes.add(scan_next);
numClusters++;
}
return numClusters;
}
/*
public void growTiles( public void growTiles(
int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
boolean [] tiles) boolean [] tiles,
boolean [] prohibit)
*/
// temporary - simple separation until continuous tile areas are split along disparity steps
public int [] enumerateClusters(
boolean diag_en,
boolean [] tiles_src)
{
// adding 1-tile frame around to avoid checking for the borders
int tilesX2 = tilesX + 2;
int tilesY2 = tilesY + 2;
boolean [] tiles = new boolean [tilesX2*tilesY2];
int [] enum_clust2 = new int[tiles.length];
for (int i = 0; i < enum_clust2.length; i++) enum_clust2[i] = 0;
int numClust = 0;
for (int i = 0; i < tilesY2; i++) {
tiles[tilesX2 * 0 + i] = false;
tiles[tilesX2*(tilesY2-1) + i] = false;
tiles[tilesX2* i + 0] = false;
tiles[tilesX2* i + tilesX2 -1] = false;
}
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
tiles[(i+1)*tilesX2 + j + 1]= tiles_src[i * tilesX + j];
}
}
int [] dirs4 = {-tilesX2, 1, tilesX2,-1};
int [] dirs8 = {-tilesX2, -tilesX2 + 1, 1, tilesX2 +1, tilesX2, tilesX2 - 1, -1, -tilesX2 - 1};
int [] dirs = diag_en? dirs8 : dirs4;
int [] waves = new int [tiles.length];
for (int i = 0; i < tiles.length; i++) waves[i] = tiles[i] ? 0: -1;
ArrayList<Integer> front = new ArrayList<Integer>();
for (int start_indx = 0; start_indx < tiles.length; start_indx++) if (waves[start_indx] == 0){ // found first pixel of a new cluster
numClust ++;
Integer ipx = start_indx;
Integer ipx1;
front.clear();
int area = 1;
waves[ipx] = area;
enum_clust2[ipx] = numClust;
front.add(ipx);
while (!front.isEmpty()) {
ipx = front.remove(0);// get oldest element
for (int d = 0; d < dirs.length; d++){
ipx1 = ipx + dirs[d];
if (waves[ipx1] == 0) {
area++;
waves[ipx1] = area;
enum_clust2[ipx1] = numClust;
front.add(ipx1);
}
}
}
}
// return to original dimensions
int [] enum_clust = new int[tiles_src.length];
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
enum_clust[i * tilesX + j] =enum_clust2[(i+1)*tilesX2 + j + 1];
}
}
// count cluster
int []clustSizes = new int [numClust];
for (int i = 0; i < clustSizes.length; i++) clustSizes[i] = 0;
for (int i = 0; i < enum_clust.length; i++) if (enum_clust[i] > 0) clustSizes[enum_clust[i]-1]++;
class Pair implements Comparable<Pair> {
public final int index;
public final int value;
public Pair(int index, int value) {
this.index = index;
this.value = value;
}
@Override
public int compareTo(Pair other) {
return Integer.valueOf(this.value).compareTo(other.value);
}
}
Pair[] pairs = new Pair[numClust];
for (int i = 0; i < clustSizes.length; i++) pairs [i] = new Pair (i, clustSizes[i]);
Arrays.sort(pairs);
int [] revIndex = new int [numClust];
for (int i = 0; i < revIndex.length; i++) revIndex [pairs[i].index] = (numClust - i); // array was in accending order
int [] enum_clust_ordered = new int[tiles_src.length];
for (int i=0; i < enum_clust_ordered.length; i++){
enum_clust_ordered[i] = (enum_clust[i] > 0) ? revIndex[enum_clust[i] - 1] : 0;
}
return enum_clust_ordered;
}
public void fillGaps( // grows, then shrinks
int depth, // same as grow - odd - 4 directions, even - 8
boolean [] tiles,
boolean [] prohibit){
boolean [] orig_tiles = tiles.clone();
growTiles(
depth, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
tiles,
prohibit);
// invert selection, so "grow" will be "shrink"
for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i];
growTiles(
depth, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
tiles,
prohibit);
// invert selection again (restore)
for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i];
// for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i] || orig_tiles[i]; // and or with original (why result does not have some of original - only with prohibit?
if (prohibit != null) { // second pass w/o prohoibit, then end results
growTiles(
depth, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
orig_tiles,
null);
// invert selection, so "grow" will be "shrink"
for (int i =0; i< tiles.length; i++) orig_tiles[i] = !orig_tiles[i];
growTiles(
depth, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
orig_tiles,
null);
// invert selection again (restore)
for (int i =0; i< tiles.length; i++) tiles[i] &= !orig_tiles[i];
}
}
public void growTiles(
int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
boolean [] tiles,
boolean [] prohibit)
{
growTiles(
grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
tiles,
prohibit,
this.tilesX,
this.tilesY);
}
public void growTiles(
int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
boolean [] tiles,
boolean [] prohibit,
int tilesX,
int tilesY)
{ {
boolean [] src_tiles = tiles.clone(); // just in case boolean [] src_tiles = tiles.clone(); // just in case
// grow // grow
...@@ -201,29 +539,72 @@ public class TileProcessor { ...@@ -201,29 +539,72 @@ public class TileProcessor {
for (int tileY = 0; tileY < tilesY; tileY++){ for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < (tilesX - 1); tileX++){ for (int tileX = 0; tileX < (tilesX - 1); tileX++){
int tindx = tileY * tilesX + tileX; int tindx = tileY * tilesX + tileX;
if ((prohibit == null) || (!prohibit[tindx] && !prohibit[tindx + 1])) {
tiles[tindx + 1] |= src_tiles[tindx]; tiles[tindx + 1] |= src_tiles[tindx];
}
} }
for (int tileX = 1; tileX < tilesX; tileX++){ for (int tileX = 1; tileX < tilesX; tileX++){
int tindx = tileY * tilesX + tileX; int tindx = tileY * tilesX + tileX;
if ((prohibit == null) || (!prohibit[tindx] && !prohibit[tindx - 1])) {
tiles[tindx - 1] |= src_tiles[tindx]; tiles[tindx - 1] |= src_tiles[tindx];
} }
} }
} }
}
if (!hor || single){ // do vertically, but from previous state if (!hor || single){ // do vertically, but from previous state
for (int tileX = 0; tileX < tilesX; tileX++){ for (int tileX = 0; tileX < tilesX; tileX++){
for (int tileY = 0; tileY < (tilesY - 1); tileY++){ for (int tileY = 0; tileY < (tilesY - 1); tileY++){
int tindx = tileY * tilesX + tileX; int tindx = tileY * tilesX + tileX;
if ((prohibit == null) || (!prohibit[tindx] && !prohibit[tindx + tilesX])) {
tiles[tindx + tilesX] |= src_tiles[tindx]; tiles[tindx + tilesX] |= src_tiles[tindx];
}
} }
for (int tileY = 1; tileY < tilesY; tileY++){ for (int tileY = 1; tileY < tilesY; tileY++){
int tindx = tileY * tilesX + tileX; int tindx = tileY * tilesX + tileX;
if ((prohibit == null) || (!prohibit[tindx] && !prohibit[tindx - tilesX])) {
tiles[tindx - tilesX] |= src_tiles[tindx]; tiles[tindx - tilesX] |= src_tiles[tindx];
} }
} }
} }
} }
hor = !hor;
}
}
public void removeLoneClusters(
boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
boolean [] tiles, // selected tiles, will modified
double [] weights_src, // or null
int min_area, // minimal number of pixels
double min_weight // minimal total weight of the cluster (expanded!
){
boolean [] grown_by_1 = tiles.clone();
growTiles(2, // 1, // 2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown_by_1,
null);
int grown_min = (int) (min_area + 4 * Math.sqrt(min_area) + 4); // would be for compact cluster (floor - forgiving)
removeSmallClusters(
diag_en, // enable diagonal directions, false only up, dowm, right,left
grown_by_1, // selected tiles, will modified
weights_src, // or null
grown_min, // minimal number of pixels
min_weight); // minimal total weight of the cluster
/*** showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"orig","grown","combined"};
double [][] dbg_img = new double [titles.length][tiles.length];
for (int i = 0; i<tiles.length; i++){
dbg_img[0][i] = tiles[i]? 1:-1;
dbg_img[1][i] = grown_by_1[i]? 1:-1;
}
for (int i = 0; i< tiles.length; i++) tiles[i] &= grown_by_1[i];
for (int i = 0; i<tiles.length; i++){
dbg_img[2][i] = tiles[i]? 1:-1;
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
***/
for (int i = 0; i< tiles.length; i++) tiles[i] &= grown_by_1[i];
} }
public void removeSmallClusters( public void removeSmallClusters(
...@@ -564,7 +945,8 @@ public class TileProcessor { ...@@ -564,7 +945,8 @@ public class TileProcessor {
} }
block_propagate[i] = (these_diffs[imax2][i] > sure_smth); block_propagate[i] = (these_diffs[imax2][i] > sure_smth);
} }
boolean[] prohibit = null; // TBD
boolean[] dbg_before_gaps = null;
if (clt_parameters.min_clstr_seed > 1){ if (clt_parameters.min_clstr_seed > 1){
removeSmallClusters( removeSmallClusters(
false, //true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left false, //true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
...@@ -578,35 +960,44 @@ public class TileProcessor { ...@@ -578,35 +960,44 @@ public class TileProcessor {
null, // double [] weights_src, // or null null, // double [] weights_src, // or null
clt_parameters.min_clstr_seed, // int min_area, // minimal number of pixels clt_parameters.min_clstr_seed, // int min_area, // minimal number of pixels
0.0); // double min_weight // minimal total weight of the cluster 0.0); // double min_weight // minimal total weight of the cluster
removeSmallClusters( // only remove far outstanding clusters
removeSmallClusters( // remove single-tile clusters - anywhere
false, // true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left false, // true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
these_tiles, // boolean [] tiles_src, // selected tiles, will modified these_tiles, // boolean [] tiles_src, // selected tiles, will modified
null, // double [] weights_src, // or null null, // double [] weights_src, // or null
clt_parameters.min_clstr_seed, // int min_area, // minimal number of pixels clt_parameters.min_clstr_seed, // 2, // int min_area, // minimal number of pixels
0.0); // double min_weight // minimal total weight of the cluster
removeLoneClusters(
false, // true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
these_tiles, // boolean [] tiles_src, // selected tiles, will modified
null, // double [] weights_src, // or null
clt_parameters.min_clstr_lone, // int min_area, // minimal number of pixels
0.0); // double min_weight // minimal total weight of the cluster 0.0); // double min_weight // minimal total weight of the cluster
dbg_before_gaps = these_tiles.clone();
prohibit = far_tiles; // do not fill gaps over known background/far tiles
if (clt_parameters.fill_gaps > 0) {
fillGaps( // grows, then shrinks
clt_parameters.fill_gaps, // int depth, // same as grow - odd - 4 directions, even - 8
these_tiles, // boolean [] tiles,
prohibit);
}
} }
double [] this_disparity_masked = this_disparity.clone(); double [] this_disparity_masked = this_disparity.clone();
for (int i = 0; i < this_disparity.length; i++){ for (int i = 0; i < this_disparity.length; i++){
if (!these_tiles[i])this_disparity_masked[i] = Double.NaN; if (!these_tiles[i])this_disparity_masked[i] = Double.NaN;
} }
/*
double [] hor_strength_conv = detectOrtho( int [] enum_clusters = enumerateClusters(
hor_strength, // double [] tiles, true, // boolean diag_en,
false, // boolean vert, // true for vertical correlation and _horizontal features these_tiles); // boolean [] tiles_src)
clt_parameters.ortho_half_length, // int radius, // one dimension - [-radius, +radius], other dimension -1,0, 1
debugLevel);
double [] vert_strength_conv = detectOrtho(
vert_strength, // double [] tiles,
true, // boolean vert, // true for vertical correlation and _horizontal features
clt_parameters.ortho_half_length, // int radius, // one dimension - [-radius, +radius], other dimension -1,0, 1
debugLevel);
*/
if (sdfa_instance!=null){ if (sdfa_instance!=null){
String [] titles = {"masked","map","orig_map","hor_map","vert_map","bg_sel","far","these","near","block", String [] titles = {"masked","map","orig_map","hor_map","vert_map","bg_sel","far","these_gaps","these","near","block",
"strength","hor-strength","hor-conv-strength","vert-strength","vert-conv-strength", "strength","hor-strength","hor-conv-strength","vert-strength","vert-conv-strength",
"hor","hor-bridged","vert","vert-bridged","diff0","diff1","diff2","diff3"}; "hor","hor-bridged","vert","vert-bridged","diff0","diff1","diff2","diff3", "enum_clusters"};
double [][] dbg_img = new double[titles.length][tilesY * tilesX]; double [][] dbg_img = new double[titles.length][tilesY * tilesX];
for (int i = 0; i<dbg_img[0].length;i++){ for (int i = 0; i<dbg_img[0].length;i++){
dbg_img[ 0][i] = this_disparity_masked[i]; dbg_img[ 0][i] = this_disparity_masked[i];
...@@ -616,26 +1007,54 @@ public class TileProcessor { ...@@ -616,26 +1007,54 @@ public class TileProcessor {
dbg_img[ 4][i] = this_vert_disparity[i]; dbg_img[ 4][i] = this_vert_disparity[i];
dbg_img[ 5][i] = bg_tiles [i] ? 1 : -1; dbg_img[ 5][i] = bg_tiles [i] ? 1 : -1;
dbg_img[ 6][i] = far_tiles [i] ? 1 : -1; dbg_img[ 6][i] = far_tiles [i] ? 1 : -1;
dbg_img[ 7][i] = these_tiles [i] ? 1 : -1; dbg_img[ 7][i] = dbg_before_gaps [i] ? 1 : -1;
dbg_img[ 8][i] = near_tiles [i] ? 1 : -1; dbg_img[ 8][i] = these_tiles [i] ? 1 : -1;
dbg_img[ 9][i] = block_propagate[i] ? 1 : -1; dbg_img[ 9][i] = near_tiles [i] ? 1 : -1;
dbg_img[10][i] = this_strength[i]; dbg_img[10][i] = block_propagate[i] ? 1 : -1;
dbg_img[11][i] = hor_strength[i]; dbg_img[11][i] = this_strength[i];
dbg_img[12][i] = hor_strength_conv[i]; dbg_img[12][i] = hor_strength[i];
dbg_img[13][i] = vert_strength[i]; dbg_img[13][i] = hor_strength_conv[i];
dbg_img[14][i] = vert_strength_conv[i]; dbg_img[14][i] = vert_strength[i];
dbg_img[15][i] = dbg_used_hor[i]? 1 : -1; dbg_img[15][i] = vert_strength_conv[i];
dbg_img[16][i] = used_hor[i]? 1 : -1; dbg_img[16][i] = dbg_used_hor[i]? 1 : -1;
dbg_img[17][i] = dbg_used_vert[i]? 1 : -1; dbg_img[17][i] = used_hor[i]? 1 : -1;
dbg_img[18][i] = used_vert[i]? 1 : -1; dbg_img[18][i] = dbg_used_vert[i]? 1 : -1;
dbg_img[19][i] = used_vert[i]? 1 : -1;
dbg_img[19][i] = these_diffs[0][i];
dbg_img[20][i] = these_diffs[1][i]; dbg_img[20][i] = these_diffs[0][i];
dbg_img[21][i] = these_diffs[2][i]; dbg_img[21][i] = these_diffs[1][i];
dbg_img[22][i] = these_diffs[3][i]; dbg_img[22][i] = these_diffs[2][i];
dbg_img[23][i] = these_diffs[3][i];
dbg_img[24][i] = enum_clusters[i];
} }
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles); sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
} }
int numScans = createTileTasks(
50, // int maxClusters,
0, // int minClusterArea,
this_disparity, // [] disparity_in, masked ok too
this_strength, // double [] strength_in,
0.0, // double minStrength,
enum_clusters, // int [] clusters_in,
disparity_far,
disparity_near,
debugLevel);
if (debugLevel > -1){
System.out.println("secondPassSetup(): created "+ numScans+ " FPGA passes.");
}
if (debugLevel > 0){
String [] titles = new String [clt_3d_passes.size()];
double [][] disparities = new double [titles.length][tilesX*tilesY];
for (int i = 0; i < titles.length; i++) {
titles[i] = i+"_scan";
double [][] disparityTiles = clt_3d_passes.get(i).disparity;
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
disparities[i][ty*tilesX+tx] = disparityTiles[ty][tx];
}
}
sdfa_instance.showArrays(disparities, tilesX, tilesY, true, "disparities_scans",titles);
}
return scan_next; return scan_next;
} }
......
...@@ -137,3 +137,24 @@ public class X3dOutput { ...@@ -137,3 +137,24 @@ public class X3dOutput {
return bbox; return bbox;
} }
} }
/*
An IndexedFaceSet geometry node creates geometry out of faces
texCoord and texCoordIndex - specify texture pieces
Shape {
appearance Appearance { . . . }
geometry IndexedFaceSet {
coord Coordinate { . . . }
coordIndex [ . . . ]
texCoord TextureCoordinate { . . . }
texCoordIndex [ . . . ]
}
}
<IndexedFaceSet coordIndex="0 1 2 -1 0 2 3 -1 ..." texCoordIndex="0 1 2 -1 0 2 3 -1 ...">
<Coordinate point="-37.500000 4.000000 -46.450000 .../>
<TextureCoordinate point="-37.500000 4.000000 -46.450000 .../>
</IndexedFaceSet>
*/
*/
\ No newline at end of file
...@@ -180,6 +180,9 @@ import ij.process.*; ...@@ -180,6 +180,9 @@ import ij.process.*;
} }
public ImageStack makeStack(double[][] pixels, int width, int height, String [] titles) { public ImageStack makeStack(double[][] pixels, int width, int height, String [] titles) {
return makeStack( pixels, width, height, titles, false);
}
public ImageStack makeStack(double[][] pixels, int width, int height, String [] titles, boolean noNaN) {
float [] fpixels; float [] fpixels;
ImageStack array_stack=new ImageStack(width,height); ImageStack array_stack=new ImageStack(width,height);
for (int i=0;i<pixels.length;i++) if (pixels[i]!=null) { for (int i=0;i<pixels.length;i++) if (pixels[i]!=null) {
...@@ -188,7 +191,11 @@ import ij.process.*; ...@@ -188,7 +191,11 @@ import ij.process.*;
return null; return null;
} }
fpixels=new float[pixels[i].length]; fpixels=new float[pixels[i].length];
if (noNaN){
for (int j=0;j<fpixels.length;j++) fpixels[j]= Double.isNaN(pixels[i][j])? 0.0F: ((float)pixels[i][j]);
} else {
for (int j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j]; for (int j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
}
if (titles!=null){ if (titles!=null){
array_stack.addSlice(titles[i], fpixels); array_stack.addSlice(titles[i], fpixels);
} else { } else {
......
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