Commit 2eae496d authored by Andrey Filippov's avatar Andrey Filippov

trying group phase correlation, preparing to convert to GPU

parent a149cadd
......@@ -32,7 +32,7 @@ public class CLTParameters {
public int ishift_y = 0; // debug feature - shift source image by this pixels down
private double fat_zero = 0.05; // modify phase correlation to prevent division by very small numbers
private double fat_zero_mono = 0.1; // modify phase correlation to prevent division by very small numbers
private double fat_zero_mono = 0.03; // modify phase correlation to prevent division by very small numbers
private double corr_sigma = 0.8; // LPF correlation sigma
private double corr_sigma_mono = 0.1; // LPF correlation sigma for monochrome images
private double scale_strength_main = 1.0; // leave as is
......@@ -766,9 +766,10 @@ public class CLTParameters {
public boolean taEnMismatch = false; // Enable cost of a measurement layer not having same layer in the same location or near
// gpu processing parameters
public double gpu_corr_scale = 0.75; // reduce GPU-generated correlation values
public int gpu_corr_rad = 7; // size of the correlation to save - initially only 15x15
public double gpu_weight_r = 0.25;
public double gpu_weight_b = 0.25; // weight g = 1.0 - gpu_weight_r - gpu_weight_b
public double gpu_weight_r = 0.5; // 25;
public double gpu_weight_b = 0.2; // 0.25; // weight g = 1.0 - gpu_weight_r - gpu_weight_b
public double gpu_sigma_r = 0.9; // 1.1;
public double gpu_sigma_b = 0.9; // 1.1;
public double gpu_sigma_g = 0.6; // 0.7;
......@@ -1567,6 +1568,7 @@ public class CLTParameters {
properties.setProperty(prefix+"taEnMismatch", this.taEnMismatch +"");
properties.setProperty(prefix+"gpu_corr_scale", this.gpu_corr_scale +"");
properties.setProperty(prefix+"gpu_corr_rad", this.gpu_corr_rad +"");
properties.setProperty(prefix+"gpu_weight_r", this.gpu_weight_r +"");
properties.setProperty(prefix+"gpu_weight_b", this.gpu_weight_b +"");
......@@ -2352,6 +2354,7 @@ public class CLTParameters {
if (properties.getProperty(prefix+"taEnFlaps")!=null) this.taEnFlaps=Boolean.parseBoolean(properties.getProperty(prefix+"taEnFlaps"));
if (properties.getProperty(prefix+"taEnMismatch")!=null) this.taEnMismatch=Boolean.parseBoolean(properties.getProperty(prefix+"taEnMismatch"));
if (properties.getProperty(prefix+"gpu_corr_scale")!=null) this.gpu_corr_scale=Double.parseDouble(properties.getProperty(prefix+"gpu_corr_scale"));
if (properties.getProperty(prefix+"gpu_corr_rad")!=null) this.gpu_corr_rad=Integer.parseInt(properties.getProperty(prefix+"gpu_corr_rad"));
if (properties.getProperty(prefix+"gpu_weight_r")!=null) this.gpu_weight_r=Double.parseDouble(properties.getProperty(prefix+"gpu_weight_r"));
if (properties.getProperty(prefix+"gpu_weight_b")!=null) this.gpu_weight_b=Double.parseDouble(properties.getProperty(prefix+"gpu_weight_b"));
......@@ -3279,6 +3282,8 @@ public class CLTParameters {
gd.addTab ("GPU", "Parameters for GPU development");
gd.addMessage ("--- GPU processing parameters ---");
gd.addNumericField("GPU 2D correlation scale", this.gpu_corr_scale, 4, 6,"",
"Reduce GPU-generated correlation values to approximately match CPU-generated ones");
gd.addNumericField("Correlation radius", this.gpu_corr_rad, 0, 6,"pix",
"Size of the 2D correlation - maximal radius = 7 corresponds to full 15x15 pixel tile");
gd.addNumericField("Correlation weight R", this.gpu_weight_r, 4, 6,"",
......@@ -4057,6 +4062,7 @@ public class CLTParameters {
this.taEnFlaps= gd.getNextBoolean();
this.taEnMismatch= gd.getNextBoolean();
this.gpu_corr_scale = gd.getNextNumber();
this.gpu_corr_rad = (int) gd.getNextNumber();
this.gpu_weight_r = gd.getNextNumber();
this.gpu_weight_b = gd.getNextNumber();
......
......@@ -803,7 +803,7 @@ public class GPUTileProcessor {
/**
* Copy array of CPU-prepared tasks to the GPU memory
* @param tile_tasks array of TpTask prepared by the CPU (before geometry correction is appllied)
* @param tile_tasks array of TpTask prepared by the CPU (before geometry correction is applied)
* @param use_aux Use second (aux) camera
*/
public void setTasks(TpTask [] tile_tasks, boolean use_aux) // while is it in class member? - just to be able to free
......@@ -2078,6 +2078,16 @@ public class GPUTileProcessor {
if (debug) System.out.println("constantMemorySize: " + constantMemorySize);
cuMemcpyHtoD(constantMemoryPointer, Pointer.to(lpf_flat), constantMemorySize);
if (debug) System.out.println();
/*
if (debug) {
for (int i = 0; i < lpf_flat.length; i++) {
System.out.print(String.format("%8.5f", lpf_flat[i]));
if (((i+1) % 16) == 0) {
System.out.println();
}
}
}
*/
}
public void setLpfCorr(
......@@ -2094,6 +2104,16 @@ public class GPUTileProcessor {
if (debug) System.out.println("constantMemorySize: " + constantMemorySize);
cuMemcpyHtoD(constantMemoryPointer, Pointer.to(lpf_flat), constantMemorySize);
if (debug) System.out.println();
/*
if (debug) {
for (int i = 0; i < lpf_flat.length; i++) {
System.out.print(String.format("%8.5f", lpf_flat[i]));
if (((i+1) % 16) == 0) {
System.out.println();
}
}
}
*/
}
public float [] floatSetCltLpfFd(
......
......@@ -399,6 +399,7 @@ public class Correlation2d {
return tcorr;
}
/**
* Calculate color channels FD phase correlations, mix results with weights, apply optional low-pass filter
* and convert to the pixel domain as [(2*transform_size-1) * (2*transform_size-1)] tiles (15x15)
......@@ -482,12 +483,270 @@ public class Correlation2d {
double [] corr_pd = dtt.corr_unfold_tile(tcorr[first_col], transform_size);
return corr_pd;
}
/**
* Calculate all required image pairs phase correlation
* Combine compatible correlations in TD (for 6 pairs requires 2 calls): vertical will be transposed,
* (all quadrants transposed, quadrants 1 and 2 - swapped), "diagonal other" (#5) will be flipped
* vertically (quadrants 2 and 3 - negated)
* @param corr_combo_td per-pair array of the TD representation of correlation pairs, mixed color components
* @param pairs_mask bitmask of the pairs to combinde
* @return TD representation of the combined 2D correlation
*/
public double [][] combineCorrelationsTD(
double [][][] corr_combo_td, // vertical will be transposed, other diagonal flipped vertically (should be separate)
int pairs_mask // vertical
) {
if (corr_combo_td != null) {
double [][]tcorr = new double [4][transform_len];
int num_combined = 0;
for (int npair = 0; npair < corr_combo_td.length; npair++) if ((((pairs_mask >> npair) & 1) != 0 ) && (corr_combo_td[npair] !=null)) {
if (isHorizontalPair(npair) || isDiagonalMainPair(npair)) {
for (int q = 0; q < 4; q++) {
for (int i = 0; i < transform_len; i++) {
tcorr[q][i] += corr_combo_td[npair][q][i];
}
}
num_combined++;
} else if (isVerticalPair(npair)) {
for (int q = 0; q < 4; q++) {
int qr = ((q & 1) << 1) | ((q >> 1) & 1);
int i = 0;
for (int iy = 0; iy < transform_size; iy++ ) {
for (int ix = 0; ix < transform_size; ix++ ) {
int ir = ix*transform_size + iy;
tcorr[qr][ir] += corr_combo_td[npair][q][i];
i++;
}
}
}
num_combined++;
} else if (isDiagonalOtherPair(npair)) {
for (int q = 0; q < 2; q++) {
for (int i = 0; i < transform_len; i++) {
tcorr[q][i] += corr_combo_td[npair][q][i];
}
}
for (int q = 2; q < 4; q++) {
for (int i = 0; i < transform_len; i++) {
tcorr[q][i] -= corr_combo_td[npair][q][i];
}
}
num_combined++;
}
}
if (num_combined > 0) {
for (int q = 0; q < 4; q++) {
for (int i = 0; i < transform_len; i++) {
tcorr[q][i] /= num_combined;
}
}
return tcorr;
}
}
return null;
}
/**
* Normalize TD tile (before converting to pixel domain as a phase correlation result and optionally LOF
* @param td 4-quadrant TD tile, will be normalized in-place
* @param lpf optional low-pass filter (or null)
* @param fat_zero relative fat zero to apply during normalization
*/
public void normalize_TD(
double [][] td,
double [] lpf, // or null
double fat_zero) {
if (td == null) return;
double [] a2 = new double[transform_len];
double sa2 = 0.0;
for (int i = 0; i < transform_len; i++) {
double s1 = 0.0;
for (int n = 0; n< 4; n++){
s1+=td[n][i] * td[n][i];
}
a2[i] = Math.sqrt(s1);
sa2 += a2[i];
}
double fz2 = sa2/transform_len * fat_zero * fat_zero; // fat_zero squared to match units
for (int i = 0; i < transform_len; i++) {
double scale = 1.0 / (a2[i] + fz2);
for (int n = 0; n<4; n++){
td[n][i] *= scale;
}
}
if (lpf != null) {
for (int n = 0; n<4; n++) {
for (int i = 0; i < transform_len; i++) {
td[n][i] *= lpf[i];
}
}
}
}
/**
* Convert 2D correlation tile from the TD to pixel domain
* @param td 4-quadrant TD representation of the tile
* @return normally a 15x15 pixel 2D correlation
*/
public double [] convertCorrToPD(
double [][] td) {
if (td == null) return null;
for (int quadrant = 0; quadrant < 4; quadrant++){
int mode = ((quadrant << 1) & 2) | ((quadrant >> 1) & 1); // transpose
td[quadrant] = dtt.dttt_iie(td[quadrant], mode, transform_size);
}
// convert from 4 quadrants to 15x15 centered tiles (only composite)
double [] corr_pd = dtt.corr_unfold_tile(td, transform_size);
return corr_pd;
}
/**
* Calculate all required image pairs phase correlation, stay in Transform Domain
* @param clt_data aberration-corrected FD CLT data [camera][color][tileY][tileX][quadrant][index]
* @param tileX tile to extract X index
* @param tileY tile to extract Y index
* @param pairs_mask bimask of required pairs
* @param lpf_rb optional low-pass filter - extra LPF for red and blue
* @param scale_value scale correlation results to compensate for lpf changes and other factors
* @param col_weights RBG color weights
* @return [pair][quadrant][index]
*/
public double [][][] correlateCompositeTD(
double [][][][][][] clt_data,
int tileX,
int tileY,
int pairs_mask,
double [] lpf_rb, // extra lpf for red and blue (unused for mono) or null
double scale_value, // scale correlation value
double [] col_weights) {
double [][][][] clt_data_tile = new double[clt_data.length][][][]; // [camera][color][quadrant][index]
for (int ncam = 0; ncam < clt_data.length; ncam++) if (clt_data[ncam] != null){
clt_data_tile[ncam] = new double[clt_data[ncam].length][][];
for (int ncol = 0; ncol < clt_data[ncam].length; ncol++) if ((clt_data[ncam][ncol] != null) && (clt_data[ncam][ncol][tileY] != null)){
clt_data_tile[ncam][ncol] = clt_data[ncam][ncol][tileY][tileX];
}
}
return correlateCompositeTD(
clt_data_tile,
pairs_mask, // already decoded so bit 0 - pair 0
lpf_rb,
scale_value,
col_weights);
}
/**
* Calculate all required image pairs phase correlation, stay in Transform Domain
* @param clt_data_tile aberration-corrected FD CLT data for one tile [camera][color][quadrant][index]
* @param pairs_mask bimask of required pairs
* @param lpf optional final low-pass filter
* @param lpf_rb optional low-pass filter (extra) for R,B components
* @param scale_value scale correlation results to compensate for lpf changes and other factors
* @param col_weights RBG color weights
* @return [pair][quadrant][index]
*/
public double [][][] correlateCompositeTD(
double [][][][] clt_data_tile,
int pairs_mask, // already decoded so bit 0 - pair 0
double [] lpf_rb, // extra lpf for red and blue (unused for mono) or null
double scale_value, // scale correlation value
double [] col_weights) {
if (clt_data_tile == null) return null;
double [][][] pairs_corr = new double [PAIRS.length][][];
for (int npair = 0; npair < pairs_corr.length; npair++) if (((pairs_mask >> npair) & 1) != 0 ) {
int ncam1 = PAIRS[npair][0];
int ncam2 = PAIRS[npair][1];
if ((ncam1 < clt_data_tile.length) && (clt_data_tile[ncam1] != null) && (ncam2 < clt_data_tile.length) && (clt_data_tile[ncam2] != null)) {
pairs_corr[npair] = correlateCompositeTD(
clt_data_tile[ncam1], // double [][][] clt_data1,
clt_data_tile[ncam2], // double [][][] clt_data2,
lpf_rb, // double [] lpf_rb,
scale_value,
col_weights); // double [] col_weights,
}
}
return pairs_corr;
}
/**
* Calculate color channels FD phase correlations, mix results with weights, apply optional low-pass filter
* No transposing or rotation
* @param clt_data1 [3][4][transform_len] first operand data. First index - RBG color
* @param clt_data2 [3][4][transform_len] first operand data. First index - RBG color
* @param lpf optional final low-pass filter applied to mixed colors
* @param lpf_rb optional low-pass filter (extra) for R,B components only
* @param scale_value scale correlation results to compensate for lpf changes and other factors
* @param col_weights [3] - color weights {R, B, G} - green is last, normalized to sum =1.0
* @return correlation result (Transform Domain) [quadrant][index]
*/
public double[][] correlateCompositeTD(
double [][][] clt_data1,
double [][][] clt_data2,
double [] lpf_rb, // extra lpf for red and blue (unused for mono) or null
double scale_value, // scale correlation value
double [] col_weights_in){ // should have the same dimension as clt_data1 and clt_data2
double [] col_weights = col_weights_in.clone();
double s = 0.0;
for (int i = 0; i < col_weights.length; i++) {
if ((clt_data1[i] == null) || (clt_data2[i] == null)) {
col_weights[i]= 0.0;
}
s+=col_weights[i];
}
for (int i = 0; i < col_weights.length; i++) {
if (col_weights[i] != 0.0) col_weights[i] *= scale_value;
}
if (clt_data1.length == 1) { // monochrome // not used in lwir
col_weights = new double[1];
col_weights[0] = 1.0;
}
for (int i = 0; i < col_weights.length; i++) {
if (col_weights[i] != 0.0) col_weights[i]/=s; // will have 1.0 for the single color
}
double [][][]tcorr = new double [clt_data1.length][4][transform_len];
int first_col = -1;
for (int col = 0; col < tcorr.length; col++) if (col_weights[col] > 0.0 ) {
correlateSingleColorFD( // no amplitude normalization
clt_data1[col],
clt_data2[col],
tcorr[col]);
if (first_col < 0) {// accumulate all channels in first non-null color ( 0 for color, 2 for mono?)
first_col = col; // first non-empty color (2, green) or 0 for color images
for (int n = 0; n < 4; n++) {
for (int i = 0; i < transform_len; i++) {
tcorr[first_col][n][i] *= col_weights[col];
}
}
} else {
for (int n = 0; n < 4; n++) {
for (int i = 0; i < transform_len; i++) {
tcorr[first_col][n][i] += tcorr[col][n][i] * col_weights[col];
}
}
if (col == 1) { // after blue, before red
if (lpf_rb != null) {
for (int n = 0; n<4; n++) {
for (int i = 0; i < transform_len; i++) {
tcorr[first_col][n][i] *= lpf_rb[i];
}
}
}
}
}
}
return tcorr[first_col];
}
/**
* Calculate all required image pairs phase correlation
* @param clt_data aberration-corrected FD CLT data [camera][color][tileY][tileX][quadrant][index]
* @param tileX tile to extract X index
* @param tileY tile to extract Y index
* @param lpf optional low-pass filter
* @param scale_value scale correlation results to compensate for lpf changes and other factors
* @param col_weights RBG color weights
......
......@@ -72,6 +72,7 @@ public class ImageDtt extends ImageDttCPU {
final float [][][] iclt_fimg, // will return quad images or null to skip, use quadCLT.linearStackToColor
//// final int width,
// new parameters, will replace some other?
final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0
final double gpu_sigma_r, // 0.9, 1.1
final double gpu_sigma_b, // 0.9, 1.1
......@@ -163,6 +164,7 @@ public class ImageDtt extends ImageDttCPU {
}
*/
// keep for now for mono, find out what do they mean for macro mode
if (macro_mode) { // all the same as they now mean different
//compensating Bayer correction
col_weights[0] = 0.25; // 1.0/3;
......@@ -179,7 +181,7 @@ public class ImageDtt extends ImageDttCPU {
col_weights[1] = corr_blue * col_weights[2];
}
}
/*
double [] scales = isMonochrome() ?
(new double [] {1.0}) :
(macro_mode?
......@@ -189,13 +191,14 @@ public class ImageDtt extends ImageDttCPU {
corr_blue, // 0.25
1.0 - corr_red - corr_blue})); // 0.5
*/
final int corr_size = transform_size * 2 - 1;
final int [][] transpose_indices = new int [corr_size*(corr_size-1)/2][2];
// final int [][] transpose_indices = new int [corr_size*(corr_size-1)/2][2];
if ((globalDebugLevel > -10) && (disparity_corr != 0.0)){
System.out.println(String.format("Using manual infinity disparity correction of %8.5f pixels",disparity_corr));
}
/*
{ int indx = 0;
for (int i =0; i < corr_size-1; i++){
for (int j = i+1; j < corr_size; j++){
......@@ -204,7 +207,7 @@ public class ImageDtt extends ImageDttCPU {
}
}
}
*/
//// final int first_color = isMonochrome()? MONO_CHN : 0; // color that is non-zero
......@@ -316,8 +319,8 @@ public class ImageDtt extends ImageDttCPU {
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
final double [] lt_window = dtt.getWin2d(); // [256]
final double [] lt_window2 = new double [lt_window.length]; // squared
final double [] lt_window = dtt.getWin2d(); // [256] - never used
final double [] lt_window2 = new double [lt_window.length]; // squared - never used
for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i];
......@@ -356,20 +359,20 @@ public class ImageDtt extends ImageDttCPU {
};
gpuQuad.setLpfRbg( // constants memory - same for all cameras
lpf_rgb,
false); // !batch_mode);
globalDebugLevel > -1);
final float [] lpf_flat = floatGetCltLpfFd(gpu_sigma_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_corr", // String const_name, // "lpf_corr"
lpf_flat,
false); // !batch_mode);
globalDebugLevel > -1);
final float [] lpf_rb_flat = floatGetCltLpfFd(gpu_sigma_rb_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_rb_corr", // String const_name, // "lpf_corr"
lpf_rb_flat,
false); // !batch_mode);
globalDebugLevel > -1);
gpuQuad.setTasks( // copy tp_tasks to the GPU memory
tp_tasks, // TpTask [] tile_tasks,
......@@ -382,7 +385,7 @@ public class ImageDtt extends ImageDttCPU {
for (int ncam = 0; ncam < iclt_fimg.length; ncam++) {
iclt_fimg[ncam] = gpuQuad.getRBG(ncam); // retrieve data from GPU
}
}
} else {gpuQuad.execImcltRbgAll(isMonochrome());} // just for testing
// does it need texture tiles to be output?
if (texture_img != null) {
Rectangle woi = new Rectangle(); // will be filled out to match actual available image
......@@ -443,7 +446,7 @@ public class ImageDtt extends ImageDttCPU {
if (fneed_corr) {
//Generate 2D phase correlations from the CLT representation
gpuQuad.execCorr2D(
scales,// double [] scales,
col_weights, // scales,// double [] scales,
gpu_fat_zero, // double fat_zero);
gpu_corr_rad); // int corr_radius
//Show 2D correlations
......@@ -452,6 +455,24 @@ public class ImageDtt extends ImageDttCPU {
final float [][] fcorr2D = gpuQuad.getCorr2D(
gpu_corr_rad); // int corr_rad);
if (corr_indices.length > 0) {
if (true) {
int [] wh = new int[2];
double [][] dbg_corr = GPUTileProcessor.getCorr2DView(
tilesX,
tilesY,
corr_indices,
fcorr2D,
wh);
(new ShowDoubleFloatArrays()).showArrays(
dbg_corr,
wh[0],
wh[1],
true,
"dbg-corr2D", // name+"-CORR2D-D"+clt_parameters.disparity,
GPUTileProcessor.getCorrTitles());
}
final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size
// assuming that the correlation pairs sets are the same for each tile that has correlations
// find this number
......@@ -464,62 +485,13 @@ public class ImageDtt extends ImageDttCPU {
final int num_tiles = corr_indices.length / num_tile_corr;
/*
// convert to 6-layer image using tasks
double [][] dbg_corr = GPUTileProcessor.getCorr2DView(
tilesX,
tilesY,
corr_indices,
corr2D,
wh);
(new ShowDoubleFloatArrays()).showArrays(
dbg_corr,
wh[0],
wh[1],
true,
name+"-CORR2D-D"+clt_parameters.disparity,
GPUTileProcessor.getCorrTitles());
*/
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
// int tileY,tileX,tIndex;
double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS][corr_length]; // 225-long (15x15)
// double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS][corr_length]; // 225-long (15x15)
/*
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
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 = new double[quad][];
double [][] tcorr_combo = null; // [15*15] pixel space
double [][][] tcorr_partial = null; // [quad][numcol+1][15*15]
double [][][][] tcorr_tpartial = null; // [quad][numcol+1][4][8*8]
double [] ports_rgb = null;
double [][] rXY;
if (use_main) {
rXY = geometryCorrection.getRXY(true); // boolean use_rig_offsets,
} else {
rXY = geometryCorrection.getRXY(false); // boolean use_rig_offsets,
}
Correlation2d corr2d = new Correlation2d(
imgdtt_params, // ImageDttParameters imgdtt_params,
transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(globalDebugLevel > -1)); // boolean debug)
corr2d.createOrtoNotch(
imgdtt_params.getEnhOrthoWidth(isAux()), // double getEnhOrthoWidth(isAux()),
imgdtt_params.getEnhOrthoScale(isAux()), //double getEnhOrthoScale(isAux()),
(imgdtt_params.lma_debug_level > 1)); // boolean debug);
*/
Correlation2d corr2d = new Correlation2d(
imgdtt_params, // ImageDttParameters imgdtt_params,
transform_size, // int transform_size,
......@@ -532,6 +504,7 @@ public class ImageDtt extends ImageDttCPU {
(imgdtt_params.lma_debug_level > 1)); // boolean debug);
for (int indx_tile = ai.getAndIncrement(); indx_tile < num_tiles; indx_tile = ai.getAndIncrement()) {
double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS][corr_length]; // 225-long (15x15)
int indx_corr = indx_tile * num_tile_corr;
int nt = (corr_indices[indx_corr] >> GPUTileProcessor.CORR_NTILE_SHIFT);
int tileX = nt % tilesX;
......@@ -543,7 +516,7 @@ public class ImageDtt extends ImageDttCPU {
assert pair < GPUTileProcessor.NUM_PAIRS : "invalid correllation pair";
pair_mask |= (1 << pair);
for (int i = 0; i < corr_length; i++) {
corrs[pair][i] = fcorr2D[indx_corr][i]; // from float do double
corrs[pair][i] = gpu_corr_scale * fcorr2D[indx_corr][i]; // from float to double
}
indx_corr++;
}
......@@ -934,6 +907,14 @@ public class ImageDtt extends ImageDttCPU {
}
}
}
} else { // if (lma != null)
if (imgdtt_params.corr_poly_only) { // discard tile if LMA failed
disp_str[0] = Double.NaN;
disp_str[1] = 0.0;
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
disparity_map[DISPARITY_STRENGTH_INDEX] [tIndex] = disp_str[1];
}
}
}
} // end of if (corr_stat != null)
......
......@@ -2439,7 +2439,9 @@ public class ImageDttCPU {
for (int i = 0; i < debug_offsets.length; i++) for (int j = 0; j < debug_offsets[i].length; j++) {
debug_offsets[i][j] = imgdtt_params.lma_dbg_offset[i][j]*imgdtt_params.lma_dbg_scale;
}
final double [] dbg_corr_shift =((imgdtt_params.pcorr_dbg_offsx != 0.0) || (imgdtt_params.pcorr_dbg_offsy != 0.0))?
(new double [] {imgdtt_params.pcorr_dbg_offsx,imgdtt_params.pcorr_dbg_offsy}):null;
final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data
final int quad = 4; // number of subcameras
......@@ -2566,7 +2568,11 @@ public class ImageDttCPU {
{ 0.5, 0.5}};
final int transform_len = transform_size * transform_size;
final double [] filter = doubleGetCltLpfFd(corr_sigma);
final double [] filter = doubleGetCltLpfFd(corr_sigma);
final double [] filter_rb = doubleGetCltLpfFd(imgdtt_params.pcorr_sigma_rb);
final double [] filter_common = doubleGetCltLpfFd(imgdtt_params.getCorrSigma(isMonochrome()));
final double pcorr_fat_zero = imgdtt_params.getFatZero(isMonochrome());
// prepare disparity maps and weights
final int max_search_radius = (int) Math.abs(max_corr_radius); // use negative max_corr_radius for squares instead of circles?
......@@ -2672,7 +2678,7 @@ public class ImageDttCPU {
}
}
boolean debugTile =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -1);
boolean debugTile0 =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -3);
final int [] overexp_all = (saturation_imp != null) ? ( new int [2]): null;
// Moved from inside chn loop
......@@ -3054,7 +3060,60 @@ public class ImageDttCPU {
// Debug feature - only calculated if requested
// if ((clt_corr_partial != null) && imgdtt_params.corr_mode_debug) {
if ((clt_corr_partial != null) && (imgdtt_params.corr_mode_debug || imgdtt_params.gpu_mode_debug)) {
if ((clt_corr_partial != null) && (imgdtt_params.corr_mode_debug || imgdtt_params.gpu_mode_debug)) {
if (debugTile0) {
System.out.println("Debugging tileY = "+tileY+" tileX = " + tileX);
System.out.println("Debugging tileY = "+tileY+" tileX = " + tileX);
System.out.println("Debugging tileY = "+tileY+" tileX = " + tileX);
}
double [][][] corr_pairs_td = corr2d.correlateCompositeTD(
clt_data, // double [][][][][][] clt_data,
tileX, // int tileX,
tileY, // int tileY,
0x3f, // int pairs_mask,
filter_rb, // double [] lpf_rb, // extra lpf for red and blue (unused for mono) or null
getScaleStrengths(), // double scale_value, // scale correlation value
col_weights); // double [] col_weights);
double [][] corrs_ortho_td = corr2d.combineCorrelationsTD(
corr_pairs_td, // double [][][] corr_combo_td, // vertical will be transposed, other diagonal flipped vertically (should be separate)
0x0f); // int pairs_mask); // vertical
if (dbg_corr_shift!= null) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations // USED in lwir
corrs_ortho_td, // double [][] clt_tile,
dbg_corr_shift[0], // double shiftX,
dbg_corr_shift[1], // double shiftY,
false); // boolean bdebug);
}
corr2d.normalize_TD(
corrs_ortho_td, // double [][] td,
filter_common, // double [] lpf, // or null
pcorr_fat_zero); // double fat_zero);
double [] corrs_ortho = corr2d.convertCorrToPD(
corrs_ortho_td); // double [][] td);
double [][] corrs_cross_td = corr2d.combineCorrelationsTD(
corr_pairs_td, // double [][][] corr_combo_td, // vertical will be transposed, other diagonal flipped vertically (should be separate)
0x30); // int pairs_mask); // vertical
if (dbg_corr_shift!= null) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations // USED in lwir
corrs_cross_td, // double [][] clt_tile,
dbg_corr_shift[0], // double shiftX,
dbg_corr_shift[1], // double shiftY,
false); // boolean bdebug);
}
corr2d.normalize_TD(
corrs_cross_td, // double [][] td,
filter_common, // double [] lpf, // or null
pcorr_fat_zero); // double fat_zero);
double [] corrs_cross = corr2d.convertCorrToPD(
corrs_cross_td); // double [][] td);
double [] strip_ortho = corr2d.combineInterpolatedCorrelations(
strips, // double [][] strips,
0x0f, // int pairs_mask,
......@@ -3093,8 +3152,10 @@ public class ImageDttCPU {
clt_corr_partial[tileY][tileX][0][3] = corrs[3]; // 4
clt_corr_partial[tileY][tileX][1][0] = corrs[4]; // 5
clt_corr_partial[tileY][tileX][1][1] = corrs[5]; // 6
clt_corr_partial[tileY][tileX][1][2] = corr2d.debugStrip(strip_hor); // 7
clt_corr_partial[tileY][tileX][1][3] = corr2d.debugStrip(strip_vert); // 8
clt_corr_partial[tileY][tileX][1][2] = corrs_ortho; // 7
clt_corr_partial[tileY][tileX][1][3] = corrs_cross; // 8
// clt_corr_partial[tileY][tileX][1][2] = corr2d.debugStrip(strip_hor); // 7
// clt_corr_partial[tileY][tileX][1][3] = corr2d.debugStrip(strip_vert); // 8
clt_corr_partial[tileY][tileX][2][0] = corr2d.debugStrip(strips[4]); // 9
clt_corr_partial[tileY][tileX][2][1] = corr2d.debugStrip(strips[5]); // 10
clt_corr_partial[tileY][tileX][2][2] = corr2d.debugStrip2(strip_hor); // 11
......
......@@ -31,6 +31,7 @@ public class ImageDttParameters {
public boolean gpu_mode_debug = true;
public boolean corr_mode_debug = true;
public boolean mix_corr_poly = true;
public boolean corr_poly_only = false; // if LMA fails, discard tile
public double min_poly_strength = 0.2; /// 0.1
public double max_poly_hwidth = 2.5; // Maximal polynomial approximation half-width (in both directions)
public double poly_corr_scale = 2.0; /// 0.0 // Shift value if correlation maximum is wide in X than in Y to detect near objects (negative - far ones)
......@@ -98,6 +99,14 @@ public class ImageDttParameters {
public int corr_wndx_size = 9; // half number of columns to calculate CM disparity (each row has only odd/even columns, so disparity range is smaller
public double corr_wndx_hwidth = 6.0; // 50% window cutoff width
public double corr_wndx_blur = 5.0; // 100% to 0 % vertical transition range
public double pcorr_sigma_mono = 0.15; // correlation sigma for monochrome images (after normalization)
public double pcorr_sigma = 0.8; // correlation sigma for Bayder images (after normalization)
public double pcorr_sigma_rb = 0.5; // correlation sigma extra for R and B (before normalization)
public double pcorr_fat_zero = 0.05; // correlation relative fat zero for Bayer images
public double pcorr_fat_zero_mono = 0.03; // correlation relative fat zero for monochrome images
public double pcorr_dbg_offsx = 0.0; // X-offset correlation in TD
public double pcorr_dbg_offsy = 0.0; // Y-offset correlation in TD
// LMA parameters
public double lma_disp_range = 5.0; // disparity range to combine in one cluster (to mitigate ERS
......@@ -174,6 +183,13 @@ public class ImageDttParameters {
public double lma_dbg_scale = 0.0; // scale lma_dbg_offset
public double [][] lma_dbg_offset = {{ 1.0, 0.0},{ -1.0, 0.0},{-1.0, 0.0},{ 1.0, 0.0}}; // new double [4][2];
public double getCorrSigma(boolean monochrome) {
return monochrome ? pcorr_sigma_mono : pcorr_sigma;
}
public double getFatZero(boolean monochrome) {
return monochrome ? pcorr_fat_zero_mono : pcorr_fat_zero;
}
public int getEnhOrthoWidth(boolean aux) {
return aux ? enhortho_width_aux : enhortho_width;
}
......@@ -198,6 +214,7 @@ public class ImageDttParameters {
gd.addCheckbox ("Enable ImageDtt correlation debug layers", this.corr_mode_debug,
"false - return (old) per-coord correlations, true - replace them with more pairs correlation (new)");
gd.addCheckbox ("Replace CM layer with mixed/new poly one", this.mix_corr_poly);
gd.addCheckbox ("If LMA fails, discard tile", this.corr_poly_only);
gd.addNumericField("Use poly mode if strength is greater than", this.min_poly_strength, 3,6,"", "AND condition");
gd.addNumericField("Maximal polynomial approximation half-width", this.max_poly_hwidth, 3,6,"pix", "Maximal polynomial approximation half-width (in both directions), Most now are ~2.0");
gd.addNumericField("Polynomial argmax correction (positive - near, negative - far)", this.poly_corr_scale, 3,6,"×", "Shift value if correlation maximum is wide in X than in Y to detect near objects (negative - far ones)");
......@@ -316,12 +333,26 @@ public class ImageDttParameters {
gd.addNumericField("100% to 0 % correlation horizontal window transition range", this.corr_wndx_blur, 3, 6, "",
"Transition range, shifted sine is used");
gd.addTab("Corr Intra","Parameters Group 2D Phase correlation");
gd.addNumericField("Correlation sigma for monochrome images", this.pcorr_sigma_mono, 3, 6, "pix",
"after normalization");
gd.addNumericField("Correlation sigma for Bayer images", this.pcorr_sigma, 3, 6, "pix",
"after normalization");
gd.addNumericField("Extra correlation sigma for red and blue", this.pcorr_sigma_rb, 3, 6, "pix",
"before normalization");
gd.addNumericField("Correlation relative fat zero for Bayer images", this.pcorr_fat_zero, 3, 6, "",
"Normalized to average correlation absolute value");
gd.addNumericField("Correlation relative fat zero for monochrome images", this.pcorr_fat_zero_mono, 3, 6, "",
"Normalized to average correlation absolute value");
gd.addNumericField("Debug feature - shift correlation result X", this.pcorr_dbg_offsx, 3, 6, "",
"Rotate in Transform Domain");
gd.addNumericField("Debug feature - shift correlation result Y", this.pcorr_dbg_offsy, 3, 6, "",
"Rotate in Transform Domain");
gd.addTab("Corr LMA","Parameters for LMA fitting of the correlation maximum parameters");
gd.addMessage("Single-tile (no lazy eye) only parameters (some are common");
gd.addNumericField("Cluster disparity range", this.lma_disp_range, 3, 6, "pix",
"Disparity range to combine in one cluster (to mitigate ERS");
gd.addMessage("Single-tile (no lazy eye) only parameters (some are common");
gd.addCheckbox ("Correlation maximum as gaussian", this.lmas_gaussian,
"Model correlation maximum as a Gaussian exp(-r^2) (false - as a parabola - 1-r^2)");
gd.addCheckbox ("Fit correlation defined half-width", this.lmas_adjust_wm,
......@@ -474,6 +505,7 @@ public class ImageDttParameters {
this.gpu_mode_debug = gd.getNextBoolean();
this.corr_mode_debug= gd.getNextBoolean();
this.mix_corr_poly= gd.getNextBoolean();
this.corr_poly_only= gd.getNextBoolean();
this.min_poly_strength= gd.getNextNumber();
this.max_poly_hwidth= gd.getNextNumber();
this.poly_corr_scale= gd.getNextNumber();
......@@ -541,6 +573,13 @@ public class ImageDttParameters {
this.corr_wndx_hwidth = gd.getNextNumber();
this.corr_wndx_blur = gd.getNextNumber();
this.pcorr_sigma_mono = gd.getNextNumber();
this.pcorr_sigma = gd.getNextNumber();
this.pcorr_sigma_rb = gd.getNextNumber();
this.pcorr_fat_zero = gd.getNextNumber();
this.pcorr_fat_zero_mono = gd.getNextNumber();
this.pcorr_dbg_offsx = gd.getNextNumber();
this.pcorr_dbg_offsy = gd.getNextNumber();
//LMA tab
this.lma_disp_range = gd.getNextNumber();
this.lmas_gaussian= gd.getNextBoolean();
......@@ -616,6 +655,7 @@ public class ImageDttParameters {
properties.setProperty(prefix+"gpu_mode_debug", this.gpu_mode_debug+"");
properties.setProperty(prefix+"corr_mode_debug", this.corr_mode_debug+"");
properties.setProperty(prefix+"mix_corr_poly", this.mix_corr_poly+"");
properties.setProperty(prefix+"corr_poly_only", this.corr_poly_only+"");
properties.setProperty(prefix+"min_poly_strength", this.min_poly_strength+"");
properties.setProperty(prefix+"max_poly_hwidth", this.max_poly_hwidth+"");
properties.setProperty(prefix+"poly_corr_scale", this.poly_corr_scale+"");
......@@ -680,6 +720,13 @@ public class ImageDttParameters {
properties.setProperty(prefix+"corr_wndx_hwidth", this.corr_wndx_hwidth +"");
properties.setProperty(prefix+"corr_wndx_blur", this.corr_wndx_blur +"");
properties.setProperty(prefix+"pcorr_sigma_mono", this.pcorr_sigma_mono +"");
properties.setProperty(prefix+"pcorr_sigma", this.pcorr_sigma +"");
properties.setProperty(prefix+"pcorr_sigma_rb", this.pcorr_sigma_rb +"");
properties.setProperty(prefix+"pcorr_fat_zero", this.pcorr_fat_zero +"");
properties.setProperty(prefix+"pcorr_fat_zero_mono", this.pcorr_fat_zero_mono +"");
properties.setProperty(prefix+"pcorr_dbg_offsx", this.pcorr_dbg_offsx +"");
properties.setProperty(prefix+"pcorr_dbg_offsy", this.pcorr_dbg_offsy +"");
properties.setProperty(prefix+"lma_disp_range", this.lma_disp_range +"");
properties.setProperty(prefix+"lmas_gaussian", this.lmas_gaussian +"");
......@@ -758,6 +805,7 @@ public class ImageDttParameters {
if (properties.getProperty(prefix+"gpu_mode_debug")!=null) this.gpu_mode_debug=Boolean.parseBoolean(properties.getProperty(prefix+"gpu_mode_debug"));
if (properties.getProperty(prefix+"corr_mode_debug")!=null) this.corr_mode_debug=Boolean.parseBoolean(properties.getProperty(prefix+"corr_mode_debug"));
if (properties.getProperty(prefix+"mix_corr_poly")!=null) this.mix_corr_poly=Boolean.parseBoolean(properties.getProperty(prefix+"mix_corr_poly"));
if (properties.getProperty(prefix+"corr_poly_only")!=null) this.corr_poly_only=Boolean.parseBoolean(properties.getProperty(prefix+"corr_poly_only"));
if (properties.getProperty(prefix+"min_poly_strength")!=null) this.min_poly_strength=Double.parseDouble(properties.getProperty(prefix+"min_poly_strength"));
if (properties.getProperty(prefix+"max_poly_hwidth")!=null) this.max_poly_hwidth=Double.parseDouble(properties.getProperty(prefix+"max_poly_hwidth"));
if (properties.getProperty(prefix+"poly_corr_scale")!=null) this.poly_corr_scale=Double.parseDouble(properties.getProperty(prefix+"poly_corr_scale"));
......@@ -825,6 +873,13 @@ public class ImageDttParameters {
if (properties.getProperty(prefix+"corr_wndx_hwidth")!=null) this.corr_wndx_hwidth=Double.parseDouble(properties.getProperty(prefix+"corr_wndx_hwidth"));
if (properties.getProperty(prefix+"corr_wndx_blur")!=null) this.corr_wndx_blur=Double.parseDouble(properties.getProperty(prefix+"corr_wndx_blur"));
if (properties.getProperty(prefix+"pcorr_sigma_mono")!=null) this.pcorr_sigma_mono=Double.parseDouble(properties.getProperty(prefix+"pcorr_sigma_mono"));
if (properties.getProperty(prefix+"pcorr_sigma")!=null) this.pcorr_sigma=Double.parseDouble(properties.getProperty(prefix+"pcorr_sigma"));
if (properties.getProperty(prefix+"pcorr_sigma_rb")!=null) this.pcorr_sigma_rb=Double.parseDouble(properties.getProperty(prefix+"pcorr_sigma_rb"));
if (properties.getProperty(prefix+"pcorr_fat_zero")!=null) this.pcorr_fat_zero=Double.parseDouble(properties.getProperty(prefix+"pcorr_fat_zero"));
if (properties.getProperty(prefix+"pcorr_fat_zero_mono")!=null) this.pcorr_fat_zero_mono=Double.parseDouble(properties.getProperty(prefix+"pcorr_fat_zero_mono"));
if (properties.getProperty(prefix+"pcorr_dbg_offsx")!=null) this.pcorr_dbg_offsx=Double.parseDouble(properties.getProperty(prefix+"pcorr_dbg_offsx"));
if (properties.getProperty(prefix+"pcorr_dbg_offsy")!=null) this.pcorr_dbg_offsy=Double.parseDouble(properties.getProperty(prefix+"pcorr_dbg_offsy"));
if (properties.getProperty(prefix+"lma_disp_range")!=null) this.lma_disp_range=Double.parseDouble(properties.getProperty(prefix+"lma_disp_range"));
if (properties.getProperty(prefix+"lmas_gaussian")!=null) this.lmas_gaussian=Boolean.parseBoolean(properties.getProperty(prefix+"lmas_gaussian"));
......@@ -900,6 +955,7 @@ public class ImageDttParameters {
idp.gpu_mode_debug = this.gpu_mode_debug;
idp.corr_mode_debug = this.corr_mode_debug;
idp.mix_corr_poly = this.mix_corr_poly;
idp.corr_poly_only = this.corr_poly_only;
idp.min_poly_strength = this.min_poly_strength;
idp.max_poly_hwidth = this.max_poly_hwidth;
idp.poly_corr_scale = this.poly_corr_scale;
......@@ -965,6 +1021,14 @@ public class ImageDttParameters {
idp.corr_wndx_hwidth = this.corr_wndx_hwidth;
idp.corr_wndx_blur = this.corr_wndx_blur;
idp.pcorr_sigma_mono = this.pcorr_sigma_mono;
idp.pcorr_sigma = this.pcorr_sigma;
idp.pcorr_sigma_rb = this.pcorr_sigma_rb;
idp.pcorr_fat_zero = this.pcorr_fat_zero;
idp.pcorr_fat_zero_mono = this.pcorr_fat_zero_mono;
idp.pcorr_dbg_offsx = this.pcorr_dbg_offsx;
idp.pcorr_dbg_offsy = this.pcorr_dbg_offsy;
idp.lma_disp_range= this.lma_disp_range;
idp.lmas_gaussian = this.lmas_gaussian;
idp.lmas_adjust_wm = this.lmas_adjust_wm;
......
......@@ -277,7 +277,7 @@ public class QuadCLT extends QuadCLTCPU {
};
gpuQuad.setLpfRbg( // constants memory - same for all cameras
lpf_rgb,
!batch_mode);
true); // !batch_mode);
float [] lpf_flat = image_dtt.floatGetCltLpfFd(clt_parameters.getGpuCorrSigma(is_mono));
......@@ -499,10 +499,20 @@ public class QuadCLT extends QuadCLTCPU {
boolean is_lwir = quadCLT_main.isLwir();
double fat_zero = clt_parameters.getGpuFatZero(is_mono); // 30.0;
/*
double [] scales = (is_mono) ? (new double [] {1.0}) :(new double [] {
clt_parameters.gpu_weight_r, // 0.25
clt_parameters.gpu_weight_b, // 0.25
1.0 - clt_parameters.gpu_weight_r - clt_parameters.gpu_weight_b}); // 0.5
*/
double corr_green = 1.0/(1.0 + clt_parameters.gpu_weight_r + clt_parameters.gpu_weight_b); // green color
// the same, as col_weights, for separate debugging
double [] scales= (is_mono) ? (new double [] {1.0}) :(new double [] {
clt_parameters.gpu_weight_r * corr_green,
clt_parameters.gpu_weight_b * corr_green,
corr_green});
double cwgreen = 1.0/(1.0 + clt_parameters.corr_red + clt_parameters.corr_blue); // green color
double [] col_weights= (is_mono) ? (new double [] {1.0}) :(new double [] {
clt_parameters.corr_red * cwgreen,
......@@ -522,20 +532,20 @@ public class QuadCLT extends QuadCLTCPU {
};
quadCLT_main.getGPU().setLpfRbg( // constants memory - same for all cameras
lpf_rgb,
debugLevel > -1);
debugLevel > -1); // -3
float [] lpf_flat = image_dtt.floatGetCltLpfFd(clt_parameters.getGpuCorrSigma(is_mono));
quadCLT_main.getGPU().setLpfCorr(// constants memory - same for all cameras
"lpf_corr", // String const_name, // "lpf_corr"
lpf_flat,
debugLevel > -1);
debugLevel > -1); // -3
float [] lpf_rb_flat = image_dtt.floatGetCltLpfFd(clt_parameters.getGpuCorrRBSigma(is_mono));
quadCLT_main.getGPU().setLpfCorr(// constants memory - same for all cameras
"lpf_rb_corr", // String const_name, // "lpf_corr"
lpf_rb_flat,
debugLevel > -1);
debugLevel > -1); // -3
final boolean use_aux = false; // currently GPU is configured for a single quad camera
......@@ -1171,7 +1181,9 @@ public class QuadCLT extends QuadCLTCPU {
texture_woi, // texture_woi, // null or generated texture location/size
null, // iclt_fimg, // will return quad images or null to skip, use quadCLT.linearStackToColor
// new parameters, will replace some other?
clt_parameters.getFatZero(isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0
// clt_parameters.getFatZero(isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
clt_parameters.gpu_corr_scale, // gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
clt_parameters.getGpuFatZero(isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
clt_parameters.gpu_sigma_r, // 0.9, 1.1
clt_parameters.gpu_sigma_b, // 0.9, 1.1
clt_parameters.gpu_sigma_g, // 0.6, 0.7
......
......@@ -9954,7 +9954,7 @@ public class QuadCLTCPU {
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-PART_CORR-GPU-D"+clt_parameters.disparity);
image_name+sAux()+"-PART_CORR-CPU-D"+clt_parameters.disparity);
}
}
......
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