Commit 83946ca3 authored by Andrey Filippov's avatar Andrey Filippov

added preliminary inter-camera correlation, but it is not working yet

parent b6b0e4d8
......@@ -78,6 +78,7 @@ public class BiQuadParameters {
public boolean ml_keep_aux = true; // include auxiliary camera data in the ML output
public boolean ml_keep_inter = true; // include inter-camera correlation data in the ML output
public boolean ml_keep_hor_vert = true; // include combined horizontal and vertical pairs data in the ML output
public boolean ml_keep_tbrl = true; // include individual top, bottom, right, left pairs
public boolean ml_keep_debug= true; // include debug layer(s) data in the ML output
public boolean ml_8bit= true; // output in 8-bit format (default - 32-bit TIFF
public double ml_limit_extrim = 0.00001; // ignore lowest and highest values when converting to 8 bpp
......@@ -180,8 +181,11 @@ public class BiQuadParameters {
"ML output will have the second set of the layers for the auxiliary camera. Disparity values should be scaled for the camera baseline");
gd.addCheckbox ("Keep inter-camera correlation data", this.ml_keep_inter,
"Inter-camera correlation data has only one layer (and one correlation pair). It is used to generate ground truth data. Usable disparity range (measured in the main camera pixels) is ~1/5 of teh main camera");
gd.addCheckbox ("Keep combine horizonta/vertical pairs", this.ml_keep_hor_vert,
gd.addCheckbox ("Keep individual top, bottom, right, and left pairs", this.ml_keep_tbrl,
"Each of these two layers per camera are calculated from a pair of top/bottom and left/right pairs. Can possibly be used instead of originals to reduce amount of input data");
gd.addCheckbox ("Keep combined horizonta/vertical pairs", this.ml_keep_hor_vert,
"Individual horizontal and vertical pairs (4 total). Can be replaced by two combined (horizontal+vertical) ones");
gd.addCheckbox ("Keep debug layer(s)", this.ml_keep_debug,
"Keep additional (debug) layers that may change for different file versions");
gd.addCheckbox ("Use 8 bpp TIFF (default - 32 bpp)", this.ml_8bit,
......@@ -241,6 +245,7 @@ public class BiQuadParameters {
this.ml_sweep_steps= (int) gd.getNextNumber();
this.ml_keep_aux= gd.getNextBoolean();
this.ml_keep_inter= gd.getNextBoolean();
this.ml_keep_tbrl= gd.getNextBoolean();
this.ml_keep_hor_vert= gd.getNextBoolean();
this.ml_keep_debug= gd.getNextBoolean();
this.ml_8bit= gd.getNextBoolean();
......@@ -299,6 +304,7 @@ public class BiQuadParameters {
properties.setProperty(prefix+"ml_sweep_steps", this.ml_sweep_steps+"");
properties.setProperty(prefix+"ml_keep_aux", this.ml_keep_aux+"");
properties.setProperty(prefix+"ml_keep_inter", this.ml_keep_inter+"");
properties.setProperty(prefix+"ml_keep_tbrl", this.ml_keep_tbrl+"");
properties.setProperty(prefix+"ml_keep_hor_vert", this.ml_keep_hor_vert+"");
properties.setProperty(prefix+"ml_keep_debug", this.ml_keep_debug+"");
properties.setProperty(prefix+"ml_8bit", this.ml_8bit+"");
......@@ -355,6 +361,7 @@ public class BiQuadParameters {
if (properties.getProperty(prefix+"ml_sweep_steps")!=null) this.ml_sweep_steps=Integer.parseInt(properties.getProperty(prefix+"ml_sweep_steps"));
if (properties.getProperty(prefix+"ml_keep_aux")!=null) this.ml_keep_aux=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_aux"));
if (properties.getProperty(prefix+"ml_keep_inter")!=null) this.ml_keep_inter=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_inter"));
if (properties.getProperty(prefix+"ml_keep_tbrl")!=null) this.ml_keep_tbrl=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_tbrl"));
if (properties.getProperty(prefix+"ml_keep_hor_vert")!=null) this.ml_keep_hor_vert=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_hor_vert"));
if (properties.getProperty(prefix+"ml_keep_debug")!=null) this.ml_keep_debug=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_debug"));
if (properties.getProperty(prefix+"ml_8bit")!=null) this.ml_8bit=Boolean.parseBoolean(properties.getProperty(prefix+"ml_8bit"));
......@@ -411,6 +418,7 @@ public class BiQuadParameters {
bqp.ml_sweep_steps= this.ml_sweep_steps;
bqp.ml_keep_aux= this.ml_keep_aux;
bqp.ml_keep_inter= this.ml_keep_inter;
bqp.ml_keep_tbrl= this.ml_keep_tbrl;
bqp.ml_keep_hor_vert= this.ml_keep_hor_vert;
bqp.ml_keep_debug= this.ml_keep_debug;
bqp.ml_8bit= this.ml_8bit;
......
......@@ -476,12 +476,14 @@ public class EyesisCorrections {
}
if (correctionsParameters.isJP4()) imp=JP4_INSTANCE.demuxImage(imp_composite, subChannel);
if (imp==null) imp=imp_composite; // not a composite image
int [] widthHeight={imp.getWidth(),imp.getHeight()};
this.channelWidthHeight[srcChannel]=widthHeight;
// int [] widthHeight={imp.getWidth(),imp.getHeight()};
// this.channelWidthHeight[srcChannel]=widthHeight;
this.channelVignettingCorrection[srcChannel]=this.pixelMapping.getBayerFlatFieldFloat(
srcChannel,
this.channelWidthHeight[srcChannel][0],
this.channelWidthHeight[srcChannel][1],
// this.channelWidthHeight[srcChannel][0],
// this.channelWidthHeight[srcChannel][1],
bayer);
if (this.debugLevel>0){
System.out.println("Created vignetting info for channel "+srcChannel+
......
......@@ -85,6 +85,11 @@ public class GeometryCorrection {
public RigOffset rigOffset = null;
public int [] getSensorWH() {
int [] wh = {this.pixelCorrectionWidth, this.pixelCorrectionHeight};
return wh;
}
public GeometryCorrection(double [] extrinsic_corr)
{
this.extrinsic_corr = new CorrVector(extrinsic_corr);
......@@ -98,6 +103,11 @@ public class GeometryCorrection {
return (use_rig && (rigOffset != null)) ? rigOffset.rXY_aux: rXY ;
}
// public double [] getAuxOffset(boolean use_rig){
// double [] main_offset = {0.0,0.0};
// return (use_rig && (rigOffset != null)) ? rigOffset.getAuxOffset(): main_offset ;
// }
public Matrix getRotMatrix(boolean use_rig){
return (use_rig && (rigOffset != null)) ? rigOffset.getRotMatrix(): null ;
}
......@@ -656,6 +666,10 @@ public class GeometryCorrection {
return vector;
}
// public double [] getAuxOffset() {
// double [] aux_offset= {baseline * Math.cos(aux_angle)/getDisparityRadius(), baseline * Math.sin(aux_angle)/getDisparityRadius()};
// return aux_offset;
// }
public void recalcRXY() {
if (rXY != null) {
// rXY_aux = rXY; // FIXME: put real stuff !!!
......@@ -695,10 +709,6 @@ public class GeometryCorrection {
{ xc_pix, yc_pix},
{dxc_dangle, dyc_dangle},
{dxc_baseline, dyc_baseline}};
/* double [][] rslt = {
{ -xc_pix, -yc_pix},
{-dxc_dangle, -dyc_dangle},
{-dxc_baseline, -dyc_baseline}}; */
return rslt;
}
......@@ -2236,8 +2246,13 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
double ri_scale = 0.001 * gc_main.pixelSize / gc_main.distortionRadius;
// non-distorted XY relative to the auxiliary camera center if it was parallel to the main one
double pXci0 = pXc - disparity * aux_offset_derivs[0][0]; // in pixels
double pYci0 = pYc - disparity * aux_offset_derivs[0][1]; // in pixels
// Allow aux_offset_derivs null only if disparity == 0.0;
double pXci0 = pXc; // - disparity * aux_offset_derivs[0][0]; // in pixels
double pYci0 = pYc; // - disparity * aux_offset_derivs[0][1]; // in pixels
if (disparity != 0.0) { // aux_offset_derivs != null)
pXci0 -= disparity * aux_offset_derivs[0][0]; // in pixels
pYci0 -= disparity * aux_offset_derivs[0][1]; // in pixels
}
// rectilinear here
// Convert a 2-d non-distorted vector to 3d at fl_pix distance in z direction
......@@ -2246,7 +2261,7 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
// Apply port-individual combined rotation/zoom matrix
Matrix rvi = aux_rot.times(vi);
Matrix rvi = (aux_rot == null) ? vi: aux_rot.times(vi);
// get back to the projection plane by normalizing vector
......@@ -2480,6 +2495,51 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
return pXY;
}
/*
public double [] getAuxCoordinatesRigIdeal( // used in macro mode
GeometryCorrection gc_main,
Matrix rots,
double px,
double py,
double disparity)
{
// reverse getPortsCoordinates
double c_roll = 1.0; // Math.cos(( - this.common_roll) * Math.PI/180.0);
double s_roll = 0.0; // Math.sin(( - this.common_roll) * Math.PI/180.0);
double pXcd0 = px - 0.5 * this.pixelCorrectionWidth;
double pYcd0 = py - 0.5 * this.pixelCorrectionWidth;
double pXcd = c_roll * pXcd0 - s_roll* pYcd0;
double pYcd = s_roll * pXcd0 + c_roll* pYcd0;
double rD = Math.sqrt(pXcd*pXcd + pYcd*pYcd)*0.001*this.pixelSize; // distorted radius in a virtual center camera
double rND2R=getRByRDist(rD/this.distortionRadius, (debugLevel > -1));
double pXc = pXcd * rND2R; // non-distorted coordinates relative to the (0.5 * this.pixelCorrectionWidth, 0.5 * this.pixelCorrectionHeight)
double pYc = pYcd * rND2R; // in pixels
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
double [] pXY = new double[2];
// calculate for aux (this) camera
double [][] aux_offset = getAuxOffsetAndDerivatives(gc_main);
// non-distorted XY of the shifted location of the individual sensor
double pXci = pXc - disparity * aux_offset[0][0]; // in pixels
double pYci = pYc - disparity * aux_offset[0][1];
// calculate back to distorted
double rNDi = Math.sqrt(pXci*pXci + pYci*pYci); // in pixels
// Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A8-A7-A6-A5-A-B-C)");
double ri = rNDi* 0.001 * this.pixelSize / this.distortionRadius; // relative to distortion radius
// double rD2rND = (1.0 - distortionA8 - distortionA7 - distortionA6 - distortionA5 - distortionA - distortionB - distortionC);
double rD2rND = 1.0;
double rri = 1.0;
for (int j = 0; j < a.length; j++){
rri *= ri;
rD2rND += a[j]*(rri - 1.0);
}
double pXid = pXci * rD2rND;
double pYid = pYci * rD2rND;
pXY[i][0] = c_roll * pXid + s_roll* pYid + 0.5 * this.pixelCorrectionWidth; // this.pXY0[i][0];
pXY[i][1] = -s_roll * pXid + c_roll* pYid + 0.5 * this.pixelCorrectionWidth; // this.pXY0[i][1];
return pXY;
}
*/
public double [][] getPortsCoordinatesIdeal(
......@@ -2500,6 +2560,30 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
return coords;
}
public double [] getRigAuxCoordinatesIdeal(
int macro_scale, // 1 for pixels, 8 - for tiles when correlating tiles instead of the pixels
GeometryCorrection gc_main,
Matrix aux_rot,
double px,
double py,
double disparity)
{
double [] xy = getRigAuxCoordinatesAndDerivatives(
gc_main, // GeometryCorrection gc_main,
aux_rot, // Matrix aux_rot,
null, // Matrix [] aux_rot_derivs,
null, // double [][] aux_offset_derivs,
null, // double [][] pXYderiv, // if not null, should be double[6][]
px * macro_scale, // double px,
py * macro_scale, // double py,
disparity); // double disparity);
double [] coords = {xy[0]/macro_scale,xy[1]/macro_scale};
return coords;
}
// Copied from PixelMapping
/**
......
......@@ -1777,6 +1777,8 @@ public class ImageDtt {
centerY = tileY * transform_size + transform_size/2 - shiftY;
// TODO: move port coordinates out of color channel loop
double [][] centersXY;
if (macro_mode){
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction
System.out.println("\nUsing MACRO mode, centerX="+centerX+", centerY="+centerY);
......@@ -1979,16 +1981,12 @@ public class ImageDtt {
chn,
centersXY[i][0], // centerX, // center of aberration-corrected (common model) tile, X
centersXY[i][1], // centerY, //
// ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)),
(!FPGA_COMPARE_DATA && (globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2) && (i==0)) ? (globalDebugLevel + 0) : 0, // external tile compare
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2), // external tile compare
no_deconvolution,
false, // ); // transpose);
((saturation_imp != null) ? saturation_imp[i] : null), //final boolean [][] saturation_imp, // (near) saturated pixels or null
((saturation_imp != null) ? overexp_all: null)); // final double [] overexposed)
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println();
......@@ -7713,9 +7711,8 @@ public class ImageDtt {
final double [][] ml_data, // data for ML - 18 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
final double [][][][] texture_tiles_main, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
final double [][][][] texture_tiles_aux, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
final int width,
final int width, // may be not multiple of 8, same for the height
final double min_corr, // 0.02; // minimal correlation value to consider valid
final GeometryCorrection geometryCorrection_main,
final GeometryCorrection geometryCorrection_aux,
final double [][][][][][] clt_kernels_main, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......@@ -8336,7 +8333,318 @@ public class ImageDtt {
}
public void clt_bi_macro(
final EyesisCorrectionParameters.CLTParameters clt_parameters,
final int macro_scale,
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final double [][][] image_rig_data, // [2][1][pixels] (single color channel)
final double [][] disparity_bimap, // [23][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
final int width,
final GeometryCorrection geometryCorrection_main,
final GeometryCorrection geometryCorrection_aux, // it has rig offset)
final double corr_magic_scale, // still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
final int threadsMax, // maximal number of threads to launch
final int debugLevel)
{
final int globalDebugLevel = clt_parameters.rig.rig_mode_debug?debugLevel:-2;
final int debug_tileX = clt_parameters.tileX;
final int debug_tileY = clt_parameters.tileY;
final int height= image_rig_data[0][0].length/width;
final int tilesX=width/clt_parameters.transform_size;
final int tilesY=height/clt_parameters.transform_size;
final int nTilesInChn=tilesX*tilesY;
// clt_data does not need to be for the whole image (no, it is used for textures)
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int corr_size = clt_parameters.transform_size * 2 -1;
final int [][] transpose_indices = new int [corr_size*(corr_size-1)/2][2];
int indx = 0;
for (int i =0; i < corr_size-1; i++){
for (int j = i+1; j < corr_size; j++){
transpose_indices[indx ][0] = i * corr_size + j;
transpose_indices[indx++][1] = j * corr_size + i;
}
}
// Create window to select center correlation strip using
// ortho_height - full width of non-zero elements
// ortho_eff_height - effective height (ration of the weighted column sum to the center value)
int wcenter = clt_parameters.transform_size - 1;
final double [] ortho_weights = new double [corr_size]; // [15]
for (int i = 0; i < corr_size; i++){
if ((i >= wcenter - clt_parameters.img_dtt.ortho_height/2) && (i <= wcenter + clt_parameters.img_dtt.ortho_height/2)) {
double dx = 1.0*(i-wcenter)/(clt_parameters.img_dtt.ortho_height/2 + 1);
ortho_weights[i] = 0.5*(1.0+Math.cos(Math.PI*dx))/clt_parameters.img_dtt.ortho_eff_height;
}
}
if (globalDebugLevel > 0){
System.out.println("ortho_height="+ clt_parameters.img_dtt.ortho_height+" ortho_eff_height="+ clt_parameters.img_dtt.ortho_eff_height);
for (int i = 0; i < corr_size; i++){
System.out.println(" ortho_weights["+i+"]="+ ortho_weights[i]);
}
}
if (globalDebugLevel > 0) {
System.out.println("clt_aberrations_quad_corr(): width="+width+" height="+height+" transform_size="+clt_parameters.transform_size+
" debug_tileX="+debug_tileX+" debug_tileY="+debug_tileY+" globalDebugLevel="+globalDebugLevel);
}
final int transform_len = clt_parameters.transform_size * clt_parameters.transform_size;
final double [] filter_direct= new double[transform_len];
if (clt_parameters.corr_sigma == 0) {
filter_direct[0] = 1.0;
for (int i= 1; i<filter_direct.length;i++) filter_direct[i] =0;
} else {
for (int i = 0; i < clt_parameters.transform_size; i++){
for (int j = 0; j < clt_parameters.transform_size; j++){
filter_direct[i * clt_parameters.transform_size+j] = Math.exp(-(i*i+j*j)/(2*clt_parameters.corr_sigma)); // FIXME: should be sigma*sigma !
}
}
}
// normalize
double sum = 0;
for (int i = 0; i < clt_parameters.transform_size; i++){
for (int j = 0; j < clt_parameters.transform_size; j++){
double d = filter_direct[i*clt_parameters.transform_size+j];
d*=Math.cos(Math.PI*i/(2*clt_parameters.transform_size))*Math.cos(Math.PI*j/(2*clt_parameters.transform_size));
if (i > 0) d*= 2.0;
if (j > 0) d*= 2.0;
sum +=d;
}
}
for (int i = 0; i<filter_direct.length; i++){
filter_direct[i] /= sum;
}
DttRad2 dtt = new DttRad2(clt_parameters.transform_size);
final double [] filter= dtt.dttt_iiie(filter_direct);
for (int i=0; i < filter.length;i++) filter[i] *= 2*clt_parameters.transform_size;
// prepare disparity maps and weights
final int max_search_radius = (int) Math.abs(clt_parameters.max_corr_radius); // use negative max_corr_radius for squares instead of circles?
final int max_search_radius_poly = 1;
if (globalDebugLevel > 0){
System.out.println("max_corr_radius= "+clt_parameters.max_corr_radius);
System.out.println("max_search_radius= "+max_search_radius);
System.out.println("max_search_radius_poly="+max_search_radius_poly);
System.out.println("corr_fat_zero= "+clt_parameters.fat_zero);
System.out.println("disparity_array[0][0]= "+disparity_array[0][0]);
}
// add optional initialization of debug layers here
// FIXME: init only relevant, leave others null?
if (disparity_bimap != null){
for (int i = 0; i < disparity_bimap.length;i++){
disparity_bimap[i] = new double [tilesY*tilesX];
}
}
// final double [] corr_max_weights_poly =(((clt_parameters.max_corr_sigma > 0) && (disparity_bimap != null))?
// setMaxXYWeights(clt_parameters.max_corr_sigma,max_search_radius_poly): null); // here use square anyway
dtt.set_window(clt_parameters.clt_window);
final double [] lt_window = dtt.getWin2d(); // [256]
final double [] lt_window2 = new double [lt_window.length]; // squared
for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i];
if (globalDebugLevel > 1) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(lt_window, 2*clt_parameters.transform_size, 2*clt_parameters.transform_size, "lt_window");
}
//FIXME: no rotation matrices, no rig disparity - it is all included in source data in macro mode. Distortion?
// final Matrix rigMatrix = geometryCorrection_aux.getRotMatrix(true);
final int nChn = image_rig_data[0].length; // 1; ==1
final double [] col_weights= {1.0};
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DttRad2 dtt = new DttRad2(clt_parameters.transform_size);
dtt.set_window(clt_parameters.clt_window);
int tileY,tileX,tIndex; // , chn;
// showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double centerX; // center of aberration-corrected (common model) tile, X
double centerY; //
double [] fract_shiftsXY_main = null; //new double[quad_main][];
double [] fract_shiftsXY_aux = null; // new double[quad_aux][];
double [][][][] clt_data_main = new double[1][nChn][][]; // single channel
double [][][][] clt_data_aux = new double[1][nChn][][];
Correlation2d corr2d = new Correlation2d(
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
(globalDebugLevel > -1)); // boolean debug)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
tileY = nTile /tilesX;
tileX = nTile % tilesX;
tIndex = tileY * tilesX + tileX;
if (tile_op[tileY][tileX] == 0) {
if (disparity_bimap != null){
disparity_bimap[BI_TARGET_INDEX][tIndex] = Double.NaN;
}
continue; // nothing to do for this tile
}
// Moved from inside chn loop
centerX = tileX * clt_parameters.transform_size + clt_parameters.transform_size/2; // - shiftX;
centerY = tileY * clt_parameters.transform_size + clt_parameters.transform_size/2; // - shiftY;
// TODO: move port coordinates out of color channel loop
double disparity = disparity_array[tileY][tileX];
if (disparity_bimap != null){
disparity_bimap[BI_TARGET_INDEX][tIndex] = disparity;
}
// here it needs disparity_aux, as the aux camera knows nothing about the main
double [] centersXY_main = {centerX, centerY};
double [] centersXY_aux = geometryCorrection_aux.getRigAuxCoordinatesIdeal(
macro_scale, // int macro_scale, // 1 for pixels, 8 - for tiles when correlating tiles instead of the pixels
geometryCorrection_main, // GeometryCorrection gc_main,
null, // rigMatrix, // Matrix aux_rot,
centerX, // double px,
centerY, // double py,
disparity*macro_scale); // double disparity)
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction
System.out.println(disparity_array[tileY][tileX]+"\t"+
centersXY_main[0]+"\t"+centersXY_main[1]+"\t"+
centersXY_aux[0]+" \t"+centersXY_aux[1]);
}
for (int chn = 0; chn < nChn; chn++) { // now single color channel in each (
clt_data_main[0][chn] = new double [4][];
fract_shiftsXY_main = extract_correct_tile( // return a pair of residual offsets
image_rig_data[0],
width, // image width
null, // [color][tileY][tileX][band][pixel]
clt_data_main[0][chn], //double [][] clt_tile, // should be double [4][];
clt_parameters.kernel_step,
clt_parameters.transform_size,
dtt,
chn,
centersXY_main[0], // centerX, // center of aberration-corrected (common model) tile, X
centersXY_main[1], // centerY, //
0, // external tile compare
true,// no_deconvolution,
false, // ); // transpose);
null, //final boolean [][] saturation_imp, // (near) saturated pixels or null
null); // final double [] overexposed)
clt_data_aux[0][chn] = new double [4][];
fract_shiftsXY_aux = extract_correct_tile( // return a pair of residual offsets
image_rig_data[1],
width, // image width
null, // [color][tileY][tileX][band][pixel]
clt_data_aux[0][chn], //double [][] clt_tile, // should be double [4][];
clt_parameters.kernel_step,
clt_parameters.transform_size,
dtt,
chn,
centersXY_aux[0], // centerX, // center of aberration-corrected (common model) tile, X
centersXY_aux[1], // centerY, //
0, // external tile compare
true,// no_deconvolution,
false, // ); // transpose);
null, //final boolean [][] saturation_imp, // (near) saturated pixels or null
null); // final double [] overexposed)
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println();
}
if ((globalDebugLevel > 0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)) {
System.out.println("clt_bi_quad(): color="+chn+", tileX="+tileX+", tileY="+tileY+
" fract_shiftsXY_main[0]="+fract_shiftsXY_main[0]+" fract_shiftsXY_main[1]="+fract_shiftsXY_main[1]);
System.out.println("clt_bi_quad(): color="+chn+", tileX="+tileX+", tileY="+tileY+
" fract_shiftsXY_aux[0]="+fract_shiftsXY_aux[0]+" fract_shiftsXY_aux[1]="+fract_shiftsXY_aux[1]);
}
// apply residual shift
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
clt_data_main[0][chn], // double [][] clt_tile,
clt_parameters.transform_size,
fract_shiftsXY_main[0], // double shiftX,
fract_shiftsXY_main[1], // double shiftY,
((globalDebugLevel > 1) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
clt_data_aux[0][chn], // double [][] clt_tile,
clt_parameters.transform_size,
fract_shiftsXY_aux[0], // double shiftX,
fract_shiftsXY_aux[1], // double shiftY,
((globalDebugLevel > 1) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
if ((globalDebugLevel > 100) && (debug_tileX == tileX) && (debug_tileY == tileY)) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"CC0","SC0","CS0","SS0"};
double [][] dbg_tile = new double [4][];
for (int i = 0; i < 4; i++) dbg_tile[i]=clt_data_main[0][chn][i & 3];
sdfa_instance.showArrays(dbg_tile, clt_parameters.transform_size, clt_parameters.transform_size, true, "MAIN_shifted_x"+tileX+"_y"+tileY+"-z", titles);
double [][] dbg_tile_aux = new double [16][];
for (int i = 0; i < 4; i++) dbg_tile[i]=clt_data_aux[0][chn][i & 3];
sdfa_instance.showArrays(dbg_tile_aux, clt_parameters.transform_size, clt_parameters.transform_size, true, "AUX_shifted_x"+tileX+"_y"+tileY+"-z", titles);
}
}
int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? clt_parameters.img_dtt.lma_debug_level : -1;
if (disparity_bimap != null){ // not null - calculate correlations
// * @param clt_data_tile_main aberration-corrected FD CLT data for one tile of the main quad camera [sub-camera][color][quadrant][index]
double [] inter_corrs_dxy = tileInterCamCorrs(
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
corr2d, // final Correlation2d corr2d,
clt_data_main, // double [][][][] clt_data_tile_main,
clt_data_aux, // double [][][][] clt_data_tile_aux,
filter, // final double [] filter,
col_weights, // final double [] col_weights,
0, // ml_hwidth, // final int ml_hwidth,
null, // ml_data_inter, // final double [] ml_center_corr,
null, // tcorr_combo, // double [][] tcorr_combo,
tileX, // final int tileX, // only used in debug output
tileY, // final int tileY,
tile_lma_debug_level); // final int debugLevel)
if (inter_corrs_dxy != null) {
disparity_bimap[BI_DISP_CROSS_INDEX][nTile] = inter_corrs_dxy[INDEX_DISP];
disparity_bimap[BI_STR_CROSS_INDEX][nTile] = inter_corrs_dxy[INDEX_STRENGTH];
disparity_bimap[BI_DISP_CROSS_DX_INDEX][nTile] = inter_corrs_dxy[INDEX_DX];
disparity_bimap[BI_DISP_CROSS_DY_INDEX][nTile] = inter_corrs_dxy[INDEX_DY];
// TODO: Use strength for the same residual disparity
disparity_bimap[BI_STR_ALL_INDEX][nTile] =
Math.pow(inter_corrs_dxy[INDEX_STRENGTH]*
disparity_bimap[BI_STR_FULL_INDEX][nTile]*
disparity_bimap[BI_ASTR_FULL_INDEX][nTile], 1.0/3);
}
} // if (disparity_map != null){ // not null - calculate correlations
}
}
};
}
startAndJoin(threads);
}
}
......@@ -201,25 +201,26 @@ public class PixelMapping {
public float [] getBayerFlatFieldFloat(
int channel,
int width,
int height,
// int width,
// int height,
int [][] bayer){ //{{1,0},{2,1}} GR/BG
if ((this.sensors == null) || (channel<0) && (channel>=this.sensors.length))return null;
// width = this.sensors[channel]
return this.sensors[channel].getBayerFlatFieldFloat(
width,
height,
// width,
// height,
bayer);
}
public double [] getBayerFlatField(
int channel,
int width,
int height,
// int width,
// int height,
int [][] bayer){ //{{1,0},{2,1}} GR/BG
if ((this.sensors == null) || (channel<0) && (channel>=this.sensors.length))return null;
return this.sensors[channel].getBayerFlatField(
width,
height,
// width,
// height,
bayer);
}
......@@ -15645,8 +15646,8 @@ public class PixelMapping {
public double [][] pixelCorrection= null; // x,y, alpha, add flat, color, etc.
// public double [] sensorMask= null;
public int pixelCorrectionDecimation= 1;
public int pixelCorrectionWidth= 2592;
public int pixelCorrectionHeight= 1936;
public int pixelCorrectionWidth= -1; // 2592;
public int pixelCorrectionHeight= -1; // 1936;
public double entrancePupilForward= 0.0;
......@@ -15673,6 +15674,11 @@ public class PixelMapping {
public double [][] r_xyod=null; //{x0,y0,ortho, diagonal}
public int [] getSensorWH() {
int [] wh = {this.pixelCorrectionWidth, this.pixelCorrectionHeight};
return wh;
}
public SensorData (String channelPath , boolean ok ){
createEquirectangularMap(channelPath);
......@@ -15880,9 +15886,11 @@ public class PixelMapping {
}
public double [] getBayerFlatField(
int width,
int height,
// int width,
// int height,
int [][] bayer){ //{{1,0},{2,1}} GR/BG
int width = this.pixelCorrectionWidth; // width,
int height= this.pixelCorrectionHeight; // int height,
double [] corrScale = new double [width*height];
for (int y=0;y<height;y++) for (int x=0;x<width;x++){
......@@ -15908,6 +15916,13 @@ public class PixelMapping {
return corrScale;
}
public float [] getBayerFlatFieldFloat(
int [][] bayer){ //{{1,0},{2,1}} GR/BG
return _getBayerFlatFieldFloat(
this.pixelCorrectionWidth, // width,
this.pixelCorrectionHeight, // int height,
bayer);
}
private float [] _getBayerFlatFieldFloat(
int width,
int height,
int [][] bayer){ //{{1,0},{2,1}} GR/BG
......
......@@ -26,6 +26,7 @@
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -38,6 +39,7 @@ import ij.WindowManager;
//import ij.gui.Overlay;
import ij.io.FileSaver;
import ij.process.ColorProcessor;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
......@@ -2629,6 +2631,10 @@ public class QuadCLT {
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
imp_srcs[srcChannel] = padBayerToFullSize(
imp_srcs[srcChannel], // ImagePlus imp_src,
eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(),
true); // boolean replicate);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
......@@ -3189,6 +3195,81 @@ public class QuadCLT {
return nf;
}
/**
* Pad acquired Bayer image to the full sensor width/height. Used when optical center pixel coordinates do not match for channels
* and WOI is adjusted during image capture to avoid ERS mismatch between horizontal pairs
* @param imp_src source image with WOI specified as properties (sizes and offsets should be even)
* @param wh {sesnor_width, sensor_height} in pixels
* @param replicate fill gaps by replicating existing pixels
* @return full size image
*/
ImagePlus padBayerToFullSize(
ImagePlus imp_src,
int [] wh,
boolean replicate) {
int woi_top = Integer.parseInt((String) imp_src.getProperty("WOI_TOP")); // enforce even
int woi_left = Integer.parseInt((String) imp_src.getProperty("WOI_LEFT"));
int woi_width = imp_src.getWidth(); // Integer.parseInt((String) imp_src.getProperty("WOI_WIDTH"));
int woi_height = imp_src.getHeight(); // Integer.parseInt((String) imp_src.getProperty("WOI_HEIGHT"));
Properties properties = imp_src.getProperties();
if ((woi_top == 0) && (woi_left == 0) && (woi_width == wh[0]) && (woi_height == wh[1])){
return imp_src; // good as is
}
float [] full_pixels = new float [wh[0]*wh[1]];
float [] pixels=(float []) imp_src.getProcessor().getPixels();
int dst_col = woi_left;
int copy_width = woi_width;
if ((dst_col + copy_width) > wh[0]) {
copy_width = wh[0] - dst_col;
}
for (int src_row = 0; src_row < woi_height; src_row++) {
int dst_row = src_row + woi_top;
if (dst_row < wh[1]) {
System.arraycopy( pixels, src_row * woi_width, full_pixels, dst_row * wh[0] + dst_col, copy_width);
}
}
if (replicate) {
// replicate top
for (int dst_row = 0; dst_row < woi_top; dst_row++) {
int src_row = woi_top + (dst_row & 1);
System.arraycopy( full_pixels, src_row * wh[0] + dst_col, full_pixels, dst_row * wh[0] + dst_col, copy_width);
}
// replicate bottom
for (int dst_row = woi_top + woi_height; dst_row < wh[1]; dst_row++) {
int src_row = woi_top + woi_height - 2 + (dst_row & 1);
System.arraycopy( full_pixels, src_row * wh[0] + dst_col, full_pixels, dst_row * wh[0] + dst_col, copy_width);
}
// right and left are not likely, as there is no need to use them - horizontal mismatch does not influence ERS
for (int col = 0; col < woi_left; col++) {
for (int row = 0; row < wh[1]; row++) {
full_pixels[row*wh[0] + col] = full_pixels[row*wh[0] + woi_left + (col & 1)];
}
}
for (int col = woi_left + woi_width; col < wh[0]; col++) {
for (int row = 0; row < wh[1]; row++) {
full_pixels[row*wh[0] + col] = full_pixels[row*wh[0] + woi_left + woi_width - 2 +(col & 1)];
}
}
}
ImageProcessor ip = new FloatProcessor(wh[0],wh[1]);
ip.setPixels(full_pixels);
ip.resetMinAndMax(); // is it needed here?
ImagePlus imp = new ImagePlus(imp_src.getTitle(),ip); // OK to have the same name?
for (Map.Entry<?, ?> entry: properties.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
imp.setProperty(key, value);
}
imp.setProperty("WOI_WIDTH", wh[0]+"");
imp.setProperty("WOI_HEIGHTH", wh[1]+"");
imp.setProperty("WOI_TOP", "0");
imp.setProperty("WOI_LEFT", "0");
return imp;
}
/**
* Conditions images for a single image set
......@@ -3215,6 +3296,7 @@ public class QuadCLT {
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
// double [] scaleExposures = new double[channelFiles.length]; //
double [][] dbg_dpixels = new double [channelFiles.length][];
// int [] fullWindowWH = geometryCorrection.getSensorWH();
for (int srcChannel=0; srcChannel < channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel]; // channelFiles[srcChannel];
......@@ -3246,7 +3328,12 @@ public class QuadCLT {
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
// imp_srcs[srcChannel].show(); // REMOVE ME!
imp_srcs[srcChannel] = padBayerToFullSize(
imp_srcs[srcChannel], // ImagePlus imp_src,
eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(),
true); // boolean replicate);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
......@@ -4736,6 +4823,10 @@ public class QuadCLT {
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
imp_srcs[srcChannel] = padBayerToFullSize(
imp_srcs[srcChannel], // ImagePlus imp_src,
eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(),
true); // boolean replicate);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
......@@ -8373,7 +8464,7 @@ public class QuadCLT {
}
public ImagePlus [] conditionImageSet(
public ImagePlus [] conditionImageSetBatch( // used in batchCLT3d
final int nSet, // index of the 4-image set
final EyesisCorrectionParameters.CLTParameters clt_parameters,
final int [][] fileIndices, // =new int [numImagesToProcess][2]; // file index, channel number
......@@ -8431,7 +8522,10 @@ public class QuadCLT {
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
imp_srcs[srcChannel] = padBayerToFullSize(
imp_srcs[srcChannel], // ImagePlus imp_src,
eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(),
true); // boolean replicate);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
......@@ -8712,7 +8806,7 @@ public class QuadCLT {
this.startSetTime = System.nanoTime();
boolean [][] saturation_imp = (clt_parameters.sat_level > 0.0)? new boolean[QUAD][] : null;
double [] scaleExposures = new double[QUAD]; //
ImagePlus [] imp_srcs = conditionImageSet(
ImagePlus [] imp_srcs = conditionImageSetBatch(
nSet, // final int nSet, // index of the 4-image set
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
fileIndices, // final int [][] fileIndices, // =new int [numImagesToProcess][2]; // file index, channel number
......
......@@ -271,7 +271,7 @@ public class TwoQuadCLT {
boolean infinity_corr = false;
double [][] scaleExposures= {scaleExposures_main, scaleExposures_aux};
boolean toRGB= quadCLT_main.correctionsParameters.toRGB;
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging? - TODO - move whete it belongs
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging? - TODO - move where it belongs
// may use this.StartTime to report intermediate steps execution times
String name=quadCLT_main.correctionsParameters.getModelName((String) imp_quad_main[0].getProperty("name"));
String path= (String) imp_quad_main[0].getProperty("path"); // Only for debug output
......@@ -333,8 +333,6 @@ public class TwoQuadCLT {
double [][] disparity_bimap = new double [ImageDtt.BIDISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging) last 4 - max pixel differences
double min_corr_selected = clt_parameters.min_corr;
ImageDtt image_dtt = new ImageDtt();
double [][] ml_data = null;
......@@ -357,8 +355,6 @@ public class TwoQuadCLT {
texture_tiles_main, // final double [][][][] texture_tiles_main, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
texture_tiles_aux, // final double [][][][] texture_tiles_aux, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
imp_quad_main[0].getWidth(), // final int width,
min_corr_selected, // final double min_corr, // 0.02; // minimal correlation value to consider valid
quadCLT_main.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_main,
quadCLT_aux.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_aux,
quadCLT_main.getCLTKernels(), // final double [][][][][][] clt_kernels_main, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......@@ -852,7 +848,112 @@ public class TwoQuadCLT {
}
// use macro mode (strengths with limited disparity) to align at infinity if it is way off.
public boolean prealignInfinityRig(
QuadCLT quadCLT_main,
QuadCLT quadCLT_aux,
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
double [][] disparity_bimap = measureNewRigDisparity(
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
quadCLT_aux, // QuadCLT quadCLT_aux,
null, // double [][] src_bimap, // current state of measurements (or null for new measurement)
0.0, // double disparity,
null, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of teh list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
// create two arrays of main and aux strengths and small disparity
// public double inf_max_disp_main = 0.15;
// public double inf_max_disp_aux = 0.15;
final int tilesX = quadCLT_main.tp.getTilesX();
final int tilesY = quadCLT_main.tp.getTilesY();
final int tile_op_all = clt_parameters.tile_task_op; //FIXME Use some constant?
double max_main_disparity = 3* clt_parameters.rig.inf_max_disp_main;
double max_aux_disparity = 3* clt_parameters.rig.inf_max_disp_aux;
double min_strength_main =0.2;
double min_strength_aux =0.2;
int numTiles = disparity_bimap[ImageDtt.BI_STR_FULL_INDEX].length;
double [][][] macro_pair = new double[2][1][numTiles]; // second index for compatibility with multiple colors
for (int nTile = 0; nTile < numTiles; nTile++) {
double d_main= disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX ][nTile];
double d_aux= disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile];
double s_main= disparity_bimap[ImageDtt.BI_STR_FULL_INDEX ][nTile];
double s_aux= disparity_bimap[ImageDtt.BI_ASTR_FULL_INDEX][nTile];
if ((Math.abs(d_main) <= max_main_disparity) && (s_main > min_strength_main)) macro_pair[0][0][nTile] = s_main-min_strength_main;
if ((Math.abs(d_aux) <= max_aux_disparity) && (s_aux > min_strength_aux)) macro_pair[1][0][nTile] = s_aux- min_strength_aux;
// macro_pair[0][0][nTile] = s_main;
// macro_pair[1][0][nTile] = s_aux;
}
if (debugLevel >-2) {
double [][] dbg_macro = {macro_pair[0][0],macro_pair[1][0]};
(new showDoubleFloatArrays()).showArrays(
dbg_macro,
tilesX,
tilesY,
true,
"MACRO-INPUT");
}
int macro_scale = clt_parameters.transform_size;
int mTilesX = tilesX/macro_scale;
int mTilesY = tilesY/macro_scale;
int [][] mtile_op = new int [mTilesY][mTilesX];
for (int mTileY=0; mTileY < mTilesY; mTileY++) {
for (int mTileX=0; mTileX < mTilesX; mTileX++) {
mtile_op[mTileY][mTileX] = tile_op_all;
}
}
double [][] mdisparity_array = new double [mTilesY][mTilesX]; // keep all zeros
double [][] mdisparity_bimap = new double [ImageDtt.BIDISPARITY_TITLES.length][];
ImageDtt image_dtt = new ImageDtt();
image_dtt.clt_bi_macro(
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
macro_scale, // final int macro_scale,
mtile_op, // final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
mdisparity_array, // final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
macro_pair, // final double [][][] image_rig_data, // [2][1][pixels] (single color channel)
mdisparity_bimap, // final double [][] disparity_bimap, // [23][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
tilesX, // final int width,
quadCLT_main.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_main,
quadCLT_aux.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_aux,
clt_parameters.corr_magic_scale, // final double corr_magic_scale, // still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
threadsMax, // final int threadsMax, // maximal number of threads to launch
debugLevel + 1); // final int debugLevel);
// Display macro correlation results (later convert to a full size disparity_bimap for compatibility with infinity alignment
if (debugLevel > -2) {
(new showDoubleFloatArrays()).showArrays(
mdisparity_bimap,
mTilesX,
mTilesY,
true,
"MACRO-DISP_MAP",
ImageDtt.BIDISPARITY_TITLES);
}
/*
* ImageDtt.BIDISPARITY_TITLES.length
public void clt_bi_macro(
final EyesisCorrectionParameters.CLTParameters clt_parameters,
final int macro_scale,
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final double [][][] image_rig_data, // [2][1][pixels] (single color channel)
final double [][] disparity_bimap, // [23][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
final int width,
final GeometryCorrection geometryCorrection_main,
final GeometryCorrection geometryCorrection_aux, // it has rig offset)
final double corr_magic_scale, // still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
final int threadsMax, // maximal number of threads to launch
final int debugLevel)
*/
return true;
}
public boolean processInfinityRig(
......@@ -881,9 +982,17 @@ public class TwoQuadCLT {
quadCLT_main.tp.resetCLTPasses();
quadCLT_aux.tp.resetCLTPasses();
/*
FIXME - make it work
prealignInfinityRig(
quadCLT_main, // QuadCLT quadCLT_main,
quadCLT_aux, // QuadCLT quadCLT_aux,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
if (debugLevel > -100) return true; // temporarily !
*/
final int tilesX = quadCLT_main.tp.getTilesX();
// perform full re-measure cycles
......@@ -892,7 +1001,7 @@ public class TwoQuadCLT {
for (int num_full_cycle = 0; num_full_cycle < clt_parameters.rig.rig_adjust_full_cycles;num_full_cycle++) {
disparity_bimap = null;
ArrayList<Integer> tile_list = new ArrayList<Integer>();
// measuere and refine
// measure and refine
for (int disp_step = 0; disp_step < clt_parameters.rig.rig_num_disp_steps; disp_step++) {
double disparity = 0.0;
if (clt_parameters.rig.rig_num_disp_steps > 1) {
......@@ -903,7 +1012,7 @@ public class TwoQuadCLT {
quadCLT_aux, // QuadCLT quadCLT_aux,
disparity_bimap, // double [][] src_bimap, // current state of measurements (or null for new measurement)
disparity, // double disparity,
tile_list, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of teh list
tile_list, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
......@@ -1082,12 +1191,6 @@ public class TwoQuadCLT {
final boolean updateStatus,
final int debugLevel) throws Exception
{
// int min_new = 100; // make a parameter
// int num_inf_refine = 20;
// int num_near_refine = 20;
// double min_trusted_strength = 0.1; // 14;
// double trusted_tolerance = 1.0;
System.out.println("enhanceByRig()");
System.out.println("enhanceByRig()");
if ((quadCLT_main == null) || (quadCLT_aux == null)) {
System.out.println("QuadCLT instances are not initilaized");
......@@ -1422,7 +1525,7 @@ public class TwoQuadCLT {
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
saveMlFile(
quadCLT_main.image_name+"-ML_DATA-OFFS_", // String ml_title,
quadCLT_main.image_name+"-ML_DATA-", // String ml_title,
ml_directory, // String ml_directory,
disparity_offset, // double disp_offset,
quadCLT_main, // QuadCLT quadCLT_main,
......@@ -1433,6 +1536,7 @@ public class TwoQuadCLT {
clt_parameters.rig.ml_keep_aux, // boolean keep_aux,
clt_parameters.rig.ml_keep_inter, // boolean keep_inter,
clt_parameters.rig.ml_keep_hor_vert, // boolean keep_hor_vert,
clt_parameters.rig.ml_keep_tbrl, // boolean ml_keep_tbrl,
clt_parameters.rig.ml_keep_debug, // boolean keep_debug,
clt_parameters.rig.ml_hwidth, // int ml_hwidth,
ml_data, // double [][] ml_data,
......@@ -1455,6 +1559,7 @@ public class TwoQuadCLT {
boolean keep_aux,
boolean keep_inter,
boolean keep_hor_vert,
boolean ml_keep_tbrl,
boolean keep_debug,
int ml_hwidth,
double [][] ml_data,
......@@ -1466,7 +1571,8 @@ public class TwoQuadCLT {
int ml_width = 2 * ml_hwidth + 1;
int width = tilesX * ml_width;
int height = tilesY * ml_width;
String title = ml_title+(keep_aux?"A":"")+(keep_inter?"I":"")+(keep_hor_vert?"O":"")+(keep_debug?"D":"")+disp_offset;
String title = ml_title+ (use8bpp?"08":"32")+"B-"+(keep_aux?"A":"")+(keep_inter?"I":"")+(keep_hor_vert?"O":"")+(ml_keep_tbrl?"T":"")+
(keep_debug?"D":"")+"-OFFS"+disp_offset;
int [] aux_indices = {
ImageDtt.ML_TOP_AUX_INDEX, // 8 - top pair 2d correlation center area (auxiliary camera)
ImageDtt.ML_BOTTOM_AUX_INDEX, // 9 - bottom pair 2d correlation center area (auxiliary camera)
......@@ -1486,6 +1592,17 @@ public class TwoQuadCLT {
ImageDtt.ML_HOR_AUX_INDEX, //14 - horizontal pairs combined 2d correlation center area (auxiliary camera)
ImageDtt.ML_VERT_AUX_INDEX //15 - vertical pairs combined 2d correlation center area (auxiliary camera)
};
int [] tbrl_indices = {
ImageDtt.ML_TOP_INDEX, // 0 - top pair 2d correlation center area
ImageDtt.ML_BOTTOM_INDEX, // 1 - bottom pair 2d correlation center area
ImageDtt.ML_LEFT_INDEX, // 2 - left pair 2d correlation center area
ImageDtt.ML_RIGHT_INDEX, // 3 - right pair 2d correlation center area
ImageDtt.ML_TOP_AUX_INDEX, // 8 - top pair 2d correlation center area (auxiliary camera)
ImageDtt.ML_BOTTOM_AUX_INDEX, // 9 - bottom pair 2d correlation center area (auxiliary camera)
ImageDtt.ML_LEFT_AUX_INDEX, //10 - left pair 2d correlation center area (auxiliary camera)
ImageDtt.ML_RIGHT_AUX_INDEX //11 - right pair 2d correlation center area (auxiliary camera)
};
int [] dbg_indices = {
ImageDtt.ML_DBG1_INDEX //18 - just debug data (first - auto phase correlation)
};
......@@ -1498,6 +1615,8 @@ public class TwoQuadCLT {
if (!keep_aux) for (int nl:aux_indices) skip_layers[nl] = true;
if (!keep_inter) for (int nl:inter_indices) skip_layers[nl] = true;
if (!keep_hor_vert) for (int nl:hor_vert_indices) skip_layers[nl] = true;
if (!ml_keep_tbrl) for (int nl:tbrl_indices) skip_layers[nl] = true;
if (!keep_debug) for (int nl:dbg_indices) skip_layers[nl] = true;
ImageStack array_stack=new ImageStack(width,height);
......@@ -1936,7 +2055,7 @@ public class TwoQuadCLT {
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
if (debugLevel > 0) {
if ((debugLevel > 0) && (tile_list != null)) {
System.out.println("measureNewRigDisparity(), disparity = "+disparity+", tile_list.size()="+tile_list.size());
}
int tile_op_all = clt_parameters.tile_task_op; //FIXME Use some constant?
......@@ -2116,7 +2235,6 @@ public class TwoQuadCLT {
double [][] disparity_bimap = new double [ImageDtt.BIDISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging) last 4 - max pixel differences
double min_corr_selected = clt_parameters.min_corr;
image_dtt.clt_bi_quad (
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
tile_op, // final int [][] tile_op_main, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
......@@ -2134,7 +2252,6 @@ public class TwoQuadCLT {
null, // final double [][][][] texture_tiles_aux, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
quadCLT_main.tp.getTilesX()*clt_parameters.transform_size, // final int width,
min_corr_selected, // final double min_corr, // 0.02; // minimal correlation value to consider valid
quadCLT_main.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_main,
quadCLT_aux.getGeometryCorrection(), // final GeometryCorrection geometryCorrection_aux,
quadCLT_main.getCLTKernels(), // final double [][][][][][] clt_kernels_main, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......
import java.awt.Rectangle;
import ij.*;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.gui.GenericDialog;
import ij.gui.Roi;
import ij.process.*;
import ij.process.ColorProcessor;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
public class showDoubleFloatArrays {
// defaults for color conversion
......@@ -14,7 +18,7 @@ import ij.process.*;
public double Kr=0.299; // 0.299;
public double Kb=0.114; // 0.114;
public double brightness=0.5;
/* For square arrays */
......@@ -75,7 +79,7 @@ import ij.process.*;
for (j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
array_stack.addSlice("chn-"+i, fpixels);
if (pixels[i].length!=(width*height)){
}
}
ImagePlus imp_stack = new ImagePlus(title, array_stack);
......@@ -92,14 +96,18 @@ import ij.process.*;
if (asStack) {
float [] fpixels;
ImageStack array_stack=new ImageStack(width,height);
boolean not_empty = false;
for (i=0;i<pixels.length;i++) if (pixels[i]!=null) {
fpixels=new float[pixels[i].length];
for (j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
array_stack.addSlice(titles[i], fpixels);
not_empty = true;
fpixels=new float[pixels[i].length];
for (j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
array_stack.addSlice(titles[i], fpixels);
}
if (not_empty) {
ImagePlus imp_stack = new ImagePlus(title, array_stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.show();
}
ImagePlus imp_stack = new ImagePlus(title, array_stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.show();
return;
} else showArrays(pixels, width, height, titles);
}
......@@ -111,7 +119,7 @@ import ij.process.*;
ImageStack array_stack=new ImageStack(width,height);
for (i=0;i<pixels.length;i++) if (pixels[i]!=null) {
fpixels=new float[pixels[i].length];
for (j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
for (j=0;j<fpixels.length;j++) fpixels[j]=pixels[i][j];
array_stack.addSlice(titles[i], fpixels);
}
ImagePlus imp_stack = new ImagePlus(title, array_stack);
......@@ -242,7 +250,7 @@ import ij.process.*;
ImagePlus[] imp=new ImagePlus[pixels.length];
for (i=0;i<pixels.length;i++) if (pixels[i]!=null) {
fpixels=new float[pixels[i].length];
for (j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
for (j=0;j<fpixels.length;j++) fpixels[j]=pixels[i][j];
ip[i]=new FloatProcessor(width,height);
ip[i].setPixels(fpixels);
ip[i].resetMinAndMax();
......@@ -299,7 +307,7 @@ import ij.process.*;
float [] fpixels;
if (pixels!=null) {
fpixels=new float[pixels.length];
for (j=0;j<pixels.length;j++) fpixels[j]=(float)pixels[j];
for (j=0;j<pixels.length;j++) fpixels[j]=pixels[j];
ImageProcessor ip=new FloatProcessor(width,height);
ip.setPixels(fpixels);
ip.resetMinAndMax();
......@@ -323,14 +331,14 @@ import ij.process.*;
}
return null;
}
public ImagePlus makeArrays(float[] pixels, int width, int height, String title) {
int j;
float [] fpixels;
if (pixels!=null) {
fpixels=new float[pixels.length];
for (j=0;j<pixels.length;j++) fpixels[j]=(float)pixels[j];
for (j=0;j<pixels.length;j++) fpixels[j]=pixels[j];
ImageProcessor ip=new FloatProcessor(width,height);
ip.setPixels(fpixels);
ip.resetMinAndMax();
......@@ -394,7 +402,7 @@ import ij.process.*;
ImagePlus imp_stack = new ImagePlus(title, stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.show();
return imp_stack;
return imp_stack;
}
public void showImageStackThree(ImageStack stack, String title) {
if (stack==null) return;
......@@ -410,7 +418,7 @@ import ij.process.*;
imp_stack.getProcessor().resetMinAndMax();
imp_stack.show();
}
// additional methods to show 2-d "flows" in color
/*
public int sliceRminusG=1;
......@@ -436,7 +444,7 @@ import ij.process.*;
gd.addNumericField("Color conversion coefficient Kr (default =0.299) ", this.Kr, 3);
gd.addNumericField("Color conversion coefficient Kb (default =0.114) ", this.Kb, 3);
gd.addNumericField("Brightness (0..1.0)", this.brightness, 3);
gd.showDialog();
if (gd.wasCanceled()) return null;
this.sliceRminusG= (int) gd.getNextNumber();
......@@ -457,7 +465,7 @@ import ij.process.*;
this.Kb);
}
/**
*
*
* @param imp image containing at least 2 slices, rectangular selection will be used to find min/max
* @param sliceRminusG slice number to be interpreted as R-G
* @param sliceBminusG slice number to be interpreted as B-G
......@@ -477,7 +485,7 @@ import ij.process.*;
sliceBminusG,
colorSpan,
brightnessModulate,0.5,0.299,0.114);
}
public ImagePlus showFlowFromSlices(
ImagePlus imp,
......@@ -519,7 +527,7 @@ import ij.process.*;
if (maxB<Math.abs(pixels[1][index])) maxB=Math.abs(pixels[1][index]);
double a=Math.sqrt(pixels[0][index]*pixels[0][index]+pixels[1][index]*pixels[1][index]);
if (maxA<a) maxA=a;
}
double maxRB=Math.max(maxR,maxB);
double Kg=1.0-Kr-Kb;
......@@ -572,7 +580,7 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
return imp_color;
}
}
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