...
 
Commits (2)
......@@ -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();
......
......@@ -705,8 +705,8 @@ private Panel panel1,
panelClt_GPU.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("JCUDA TEST", panelClt_GPU);
addButton("TF TEST", panelClt_GPU);
addButton("GPU simulate", panelClt_GPU, color_conf_process);
addButton("GPU RUN", panelClt_GPU, color_conf_process);
addButton("GPU simulate", panelClt_GPU, color_conf_process);
addButton("GPU RUN", panelClt_GPU, color_conf_process);
// addButton("ShowGPU", panelClt_GPU, color_conf_process);
addButton("LWIR_TEST", panelClt_GPU, color_conf_process);
......
......@@ -63,7 +63,10 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.tileprocessor.DttRad2;
......@@ -739,6 +742,13 @@ public class GPUTileProcessor {
Sizeof.FLOAT); // int ElementSizeBytes)
texture_stride_rgba = (int)(device_stride[0] / Sizeof.FLOAT);
}
public int getTilesX() {
return img_width / DTT_SIZE;
}
public int getTilesY() {
return img_height / DTT_SIZE;
}
public void resetGeometryCorrection() {
geometry_correction_set = false;
......@@ -760,7 +770,6 @@ public class GPUTileProcessor {
}
public void setGeometryCorrectionVector() { // will reset geometry_correction_vector_set when running GPU kernel
// if (geometry_correction_vector_set) return;
setExtrinsicsVector(
quadCLT.getGeometryCorrection().getCorrVector());
}
......@@ -794,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
......@@ -1210,6 +1219,63 @@ public class GPUTileProcessor {
}
return tp_tasks;
}
public GPUTileProcessor.TpTask[] setTpTask(
// final GPUTileProcessor.GpuQuad gpuQuad,
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final double disparity_corr,
final boolean [] need_corrs, // should be initialized to boolean[1] or null
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final int corr_mask, // <0 - use corr mask from the tile tile_op, >=0 - overwrite all with non-zero corr_mask_tp
final int threadsMax) // maximal number of threads to launch
{
final int tilesX = getTilesX();
final int tilesY = getTilesY();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicBoolean acorrs = new AtomicBoolean(false);
final List<GPUTileProcessor.TpTask> task_list = new CopyOnWriteArrayList<GPUTileProcessor.TpTask>();
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tilesX * tilesY; nTile = ai.getAndIncrement()) {
int tileY = nTile /tilesX;
int tileX = nTile % tilesX;
// tIndex = tileY * tilesX + tileX;
if (tile_op[tileY][tileX] == 0) continue; // nothing to do for this tile
// which images to use
int img_mask = ImageDtt.getImgMask(tile_op[tileY][tileX]);
// which pairs to combine in the combo: 1 - top, 2 bottom, 4 - left, 8 - right
int corr_mask_tp = ImageDtt.getPairMask(tile_op[tileY][tileX]); // limited to 4 bits only!
if (corr_mask_tp != 0) {
if (corr_mask >=0) {
corr_mask_tp = corr_mask;
}
if (corr_mask_tp != 0) {
acorrs.set(true);
}
}
task_list.add(new GPUTileProcessor.TpTask(
tileX,
tileY,
(float) (disparity_array[tileY][tileX] + disparity_corr),
((img_mask & 0x0f) << 0) |
((corr_mask_tp & 0x3f) << 4)
)); // task == 1 for now
// mask out pairs that use missing channels
}
}
};
}
ImageDtt.startAndJoin(threads);
if (need_corrs != null) {
need_corrs[0] = acorrs.get();
}
return task_list.toArray(new GPUTileProcessor.TpTask[task_list.size()]);
}
/**
......@@ -1653,6 +1719,21 @@ public class GPUTileProcessor {
cuCtxSynchronize();
}
public int [] getCorrIndices() {
float [] fnum_corrs = new float[1];
cuMemcpyDtoH(Pointer.to(fnum_corrs), gpu_num_corr_tiles, 1 * Sizeof.FLOAT);
int num_corrs = Float.floatToIntBits(fnum_corrs[0]);
float [] fcorr_indices = new float [num_corrs];
cuMemcpyDtoH(Pointer.to(fcorr_indices), gpu_corr_indices, num_corrs * Sizeof.FLOAT);
int [] corr_indices = new int [num_corrs];
for (int i = 0; i < num_corrs; i++) {
corr_indices[i] = Float.floatToIntBits(fcorr_indices[i]);
}
num_corr_tiles = num_corrs;
return corr_indices;
}
public float [][] getCorr2D(int corr_rad){
int corr_size = (2 * corr_rad + 1) * (2 * corr_rad + 1);
float [] cpu_corrs = new float [ num_corr_tiles * corr_size];
......@@ -1677,20 +1758,6 @@ public class GPUTileProcessor {
return corrs;
}
public int [] getCorrIndices() {
float [] fnum_corrs = new float[1];
cuMemcpyDtoH(Pointer.to(fnum_corrs), gpu_num_corr_tiles, 1 * Sizeof.FLOAT);
int num_corrs = Float.floatToIntBits(fnum_corrs[0]);
float [] fcorr_indices = new float [num_corrs];
cuMemcpyDtoH(Pointer.to(fcorr_indices), gpu_corr_indices, num_corrs * Sizeof.FLOAT);
int [] corr_indices = new int [num_corrs];
for (int i = 0; i < num_corrs; i++) {
corr_indices[i] = Float.floatToIntBits(fcorr_indices[i]);
}
num_corr_tiles = num_corrs;
return corr_indices;
}
//
/**
......@@ -2011,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(
......@@ -2027,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(
......
......@@ -60,6 +60,9 @@ public class CLTPass3d{
public boolean [] border_tiles = null; // these are border tiles, zero out alpha
public boolean [] selected = null; // which tiles are selected for this layer
public double [][][][] texture_tiles;
public float [][] texture_img = null; // [3][] (RGB) or [4][] RGBA
public Rectangle texture_woi = null; // null or generated texture location/size
public double [][] max_tried_disparity = null; //[ty][tx] used for combined passes, shows maximal disparity for this tile, regardless of results
public boolean is_combo = false;
public boolean is_measured = false;
......@@ -96,13 +99,27 @@ public class CLTPass3d{
{
return texture_tiles;
}
public float [][] getTextureImages()
{
return texture_img;
}
public Rectangle getTextureWoi()
{
return texture_woi;
}
public double [][] getMaxTriedDisparity()
{
return max_tried_disparity;
}
public double [][] getTileRBGA(
int num_layers)
int num_layers) // 4 or 12
{
if (texture_img != null) {
System.out.println("FIXME: implement replacement for the GPU-generated textures (using macro mode?)");
}
if (texture_tiles == null) return null;
int tilesY = texture_tiles.length;
int tilesX = 0;
......@@ -163,15 +180,32 @@ public class CLTPass3d{
int tilesY = tileProcessor.getTilesY();
selected = new boolean[tilesY*tilesX];
int minX = tilesX, minY = tilesY, maxX = -1, maxY = -1;
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
if (texture_tiles[ty][tx] != null) {
selected[ty * tilesX + tx] = true;
if (maxX < tx) maxX = tx;
if (minX > tx) minX = tx;
if (maxY < ty) maxY = ty;
if (minY > ty) minY = ty;
} else {
selected[ty * tilesX + tx] = false; // may be omitted
if (texture_img != null) { // using GPU output
//tileProcessor.getTileSize()
if (texture_woi != null) {
int tile_size = tileProcessor.getTileSize();
texture_bounds = new Rectangle(
texture_woi.x/tile_size, texture_woi.y/tile_size, texture_woi.width/tile_size, texture_woi.height/tile_size);
// setting full rectangle as selected, not just textures? Use some other method?
for (int ty = texture_bounds.y; ty < (texture_bounds.y + texture_bounds.height); ty++) {
for (int tx = texture_bounds.x; tx < (texture_bounds.x + texture_bounds.width); tx++) {
selected[ty*tilesX+tx] = true;
}
}
return;
}
}
if (texture_tiles != null) {
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
if (texture_tiles[ty][tx] != null) {
selected[ty * tilesX + tx] = true;
if (maxX < tx) maxX = tx;
if (minX > tx) minX = tx;
if (maxY < ty) maxY = ty;
if (minY > ty) minY = ty;
} else {
selected[ty * tilesX + tx] = false; // may be omitted
}
}
}
if (maxX < 0) {
......
......@@ -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
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -28,8 +28,10 @@ import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog;
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)
......@@ -97,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
......@@ -173,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;
}
......@@ -191,9 +208,13 @@ public class ImageDttParameters {
public void dialogQuestions(GenericJTabbedDialog gd) {
gd.addCheckbox ("Debug CPU->GPU matching", this.gpu_mode_debug,
"output clt_corr_partial");
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)");
......@@ -312,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,
......@@ -467,8 +502,10 @@ public class ImageDttParameters {
}
public void dialogAnswers(GenericJTabbedDialog gd) {
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();
......@@ -536,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();
......@@ -608,8 +652,10 @@ public class ImageDttParameters {
public void setProperties(String prefix,Properties properties){
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+"");
......@@ -674,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 +"");
......@@ -749,8 +802,10 @@ public class ImageDttParameters {
}
public void getProperties(String prefix,Properties properties){
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"));
......@@ -818,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"));
......@@ -890,8 +952,10 @@ public class ImageDttParameters {
@Override
public ImageDttParameters clone() throws CloneNotSupportedException {
ImageDttParameters idp = new 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;
......@@ -957,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;
......
......@@ -47,7 +47,7 @@ import ij.ImagePlus;
import ij.ImageStack;
public class QuadCLT extends QuadCLTCPU {
GPUTileProcessor.GpuQuad gpuQuad = null;
private GPUTileProcessor.GpuQuad gpuQuad = null;
public QuadCLT(
String prefix,
Properties properties,
......@@ -66,8 +66,8 @@ public class QuadCLT extends QuadCLTCPU {
public GPUTileProcessor.GpuQuad getGPU() {
return this.gpuQuad;
}
public CLTPass3d CLTBackgroundMeasGPU( // measure background
/*
public CLTPass3d CLTBackgroundMeasGPU( // measure background - not used at all?
CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
......@@ -110,6 +110,17 @@ public class QuadCLT extends QuadCLTCPU {
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
double [][][][][] clt_corr_partial = null;
if (clt_parameters.img_dtt.gpu_mode_debug) {
clt_corr_combo = null;
clt_corr_partial = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial[i][j] = null;
}
}
}
image_dtt.clt_aberrations_quad_corr(
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
1, // final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
......@@ -119,7 +130,7 @@ public class QuadCLT extends QuadCLTCPU {
saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
// correlation results - final and partial
clt_corr_combo, // [tp.tilesY][tp.tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_corr_partial, // null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_map, // [12][tp.tilesY * tp.tilesX]
......@@ -172,11 +183,37 @@ public class QuadCLT extends QuadCLTCPU {
scan_rslt.is_measured = true;
scan_rslt.is_combo = false;
scan_rslt.resetProcessed();
if (clt_corr_partial!=null){ // only to debug matching gpu/cpu
if (debugLevel > -1){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
titles[i]=allColorNames[i % allColorNames.length]+"_"+(i / allColorNames.length);
}
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
System.out.println("corr_rslt_partial.length = "+corr_rslt_partial.length+", titles.length = "+titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-PART_CORR-GPU-D"+clt_parameters.disparity);
}
}
return scan_rslt;
}
*/
public void processCLTQuadCorrGPU(
ImagePlus [] imp_quad,
boolean [][] saturation_imp, // (near) saturated pixels or null // Not needed use this.saturation_imp
......@@ -240,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));
......@@ -462,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,
......@@ -485,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
......@@ -1037,4 +1084,173 @@ public class QuadCLT extends QuadCLTCPU {
}
// overwrites super method
public CLTPass3d CLTBackgroundMeas( // measure background // USED in lwir
CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
if ((gpuQuad == null) || !(isAux()?clt_parameters.gpu_use_aux : clt_parameters.gpu_use_main)) {
return super.CLTBackgroundMeas( // measure background // USED in lwir
clt_parameters,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
}
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
CLTPass3d scan_rslt = new CLTPass3d(tp);
int d = ImageDtt.setImgMask(0, 0xf);
d = ImageDtt.setPairMask(d,0xf);
d = ImageDtt.setForcedDisparity(d,true);
int [][] tile_op = tp.setSameTileOp(clt_parameters, d, debugLevel);
double [][] disparity_array = tp.setSameDisparity(0.0); // [tp.tilesY][tp.tilesX] - individual per-tile expected disparity
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][tilesY][tilesX][]; // will only be used inside?
// double min_corr_selected = clt_parameters.min_corr; // 0.02 was not used !
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
/*
double [][] shiftXY = new double [4][2];
// not used
if (!clt_parameters.fine_corr_ignore) {
double [][] shiftXY0 = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
shiftXY = shiftXY0;
}
double [][][][] texture_tiles = new double [tilesY][tilesX][][]; // ["RGBA".length()][];
*/
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
isMonochrome(),
isLwir(),
clt_parameters.getScaleStrength(isAux()),
gpuQuad);
double z_correction = clt_parameters.z_correction;
if (clt_parameters.z_corr_map.containsKey(image_name)){ // not used in lwir
z_correction +=clt_parameters.z_corr_map.get(image_name);
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
int disparity_modes =
ImageDtt.BITS_ALL_DISPARITIES |
ImageDtt.BITS_ALL_DIFFS |
ImageDtt.BITS_OVEREXPOSED |
ImageDtt.BITS_TONE_RGB;
double [][][][][] clt_corr_partial = null;
if (clt_parameters.img_dtt.gpu_mode_debug) {
clt_corr_combo = null;
clt_corr_partial = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial[i][j] = null;
}
}
}
float [][] texture_img = new float [isMonochrome()?2:4][];
Rectangle texture_woi = new Rectangle();
image_dtt.clt_aberrations_quad_corr_GPU( // USED in LWIR
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
1, // final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
clt_corr_combo, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [type][tilesY][tilesX] should be set by caller
// types: 0 - selected correlation (product+offset), 1 - sum
clt_corr_partial, // clt_corr_partial,// [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [tilesY][tilesX] should be set by caller
// When clt_mismatch is non-zero, no far objects extraction will be attempted
null, // clt_mismatch, // [12][tilesY * tilesX] // ***** transpose unapplied ***** ?. null - do not calculate
// values in the "main" directions have disparity (*_CM) subtracted, in the perpendicular - as is
disparity_map, // disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
disparity_modes, // disparity_modes, // bit mask of disparity_map slices to calculate/return
texture_img, // texture_img, // null or [3][] (RGB) or [4][] RGBA
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.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
clt_parameters.gpu_sigma_m, // = 0.4; // 0.7;
(isMonochrome()? 1.0 : clt_parameters.gpu_sigma_rb_corr), // final double gpu_sigma_rb_corr, // = 0.5; // apply LPF after accumulating R and B correlation before G, monochrome ? 1.0 : gpu_sigma_rb_corr;
clt_parameters.gpu_sigma_corr, // = 0.9;gpu_sigma_corr_m
image_dtt.transform_size - 1, // clt_parameters.gpu_corr_rad, // = transform_size - 1 ?
clt_parameters.corr_red, // +used
clt_parameters.corr_blue, // +used
clt_parameters.max_corr_radius,// 3.9;
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_parameters.clt_window,
disparity_corr, // final double disparity_corr, // disparity at infinity
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debugLevel);
scan_rslt.disparity = disparity_array;
scan_rslt.tile_op = tile_op;
scan_rslt.disparity_map = disparity_map;
scan_rslt.texture_tiles = null; // texture_tiles;
scan_rslt.texture_img = texture_img;
scan_rslt.texture_woi = texture_woi;
scan_rslt.is_measured = true;
scan_rslt.is_combo = false;
scan_rslt.resetProcessed();
if (clt_corr_partial!=null){ // only to debug matching gpu/cpu
if (debugLevel > -3){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
titles[i]=allColorNames[i % allColorNames.length]+"_"+(i / allColorNames.length);
}
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
System.out.println("corr_rslt_partial.length = "+corr_rslt_partial.length+", titles.length = "+titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-PART_CORR-GPU-D"+clt_parameters.disparity);
}
}
return scan_rslt;
}
}
......@@ -51,7 +51,6 @@ import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.correction.CorrectionColorProc;
import com.elphel.imagej.correction.EyesisCorrections;
import com.elphel.imagej.gpu.GPUTileProcessor;
import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.tileprocessor.GeometryCorrection.CorrVector;
import com.elphel.imagej.x3d.export.WavefrontExport;
......@@ -7145,7 +7144,8 @@ public class QuadCLTCPU {
debugLevel);
tp.clt_3d_passes.add(bgnd_data);
// if (show_init_refine)
if ((debugLevel > -2) && clt_parameters.show_first_bg) {
// if ((debugLevel > -2) && clt_parameters.show_first_bg) {
if ((debugLevel > -3) && clt_parameters.show_first_bg) {
tp.showScan(
tp.clt_3d_passes.get(0), // CLTPass3d scan,
"bgnd_data-"+tp.clt_3d_passes.size());
......@@ -9412,14 +9412,14 @@ public class QuadCLTCPU {
)
{
final boolean new_mode = false;
boolean dbg_gpu_transition = true;
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
ShowDoubleFloatArrays sdfa_instance = null;
if (clt_parameters.debug_filters && (debugLevel > -1))
if ((clt_parameters.debug_filters && (debugLevel > -1)) || dbg_gpu_transition)
// if ((debugLevel > -1))
sdfa_instance = new ShowDoubleFloatArrays(); // just for debugging?
......@@ -9514,7 +9514,7 @@ public class QuadCLTCPU {
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
texture_tiles_bgnd[tileY][tileX]= null;
if ((texture_tiles[tileY][tileX] != null) &&
if ((texture_tiles[tileY][tileX] != null) && // null pointer
bgnd_tiles[tileY * tilesX + tileX]) {
if (bgnd_tiles_grown2[tileY * tilesX + tileX]) {
texture_tiles_bgnd[tileY][tileX]= texture_tiles[tileY][tileX];
......@@ -9628,6 +9628,7 @@ public class QuadCLTCPU {
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
boolean [] borderTiles = scan.border_tiles;
double [][][][] texture_tiles = scan.texture_tiles;
// only place that uses updateSelection()
scan.updateSelection(); // update .selected field (all selected, including border) and Rectangle bounds
if (scan.getTextureBounds() == null) { // not used in lwir
System.out.println("getPassImage(): Empty image!");
......@@ -9857,6 +9858,17 @@ public class QuadCLTCPU {
z_correction +=clt_parameters.z_corr_map.get(image_name);
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
double [][][][][] clt_corr_partial = null;
if (clt_parameters.img_dtt.gpu_mode_debug) {
clt_corr_combo = null;
clt_corr_partial = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial[i][j] = null;
}
}
}
image_dtt.clt_aberrations_quad_corr(
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
......@@ -9867,7 +9879,7 @@ public class QuadCLTCPU {
saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
// correlation results - final and partial
clt_corr_combo, // [tp.tilesY][tp.tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_corr_partial, // null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_map, // [12][tp.tilesY * tp.tilesX]
......@@ -9897,7 +9909,7 @@ public class QuadCLTCPU {
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
/// image_dtt.transform_size,
/// image_dtt.transform_size,
clt_parameters.clt_window,
shiftXY, //
disparity_corr, // final double disparity_corr, // disparity at infinity
......@@ -9920,6 +9932,32 @@ public class QuadCLTCPU {
scan_rslt.is_measured = true;
scan_rslt.is_combo = false;
scan_rslt.resetProcessed();
if (clt_corr_partial!=null){ // only to debug matching gpu/cpu
if (debugLevel > -3){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
titles[i]=allColorNames[i % allColorNames.length]+"_"+(i / allColorNames.length);
}
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
System.out.println("corr_rslt_partial.length = "+corr_rslt_partial.length+", titles.length = "+titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-PART_CORR-CPU-D"+clt_parameters.disparity);
}
}
return scan_rslt;
}
......