final double [][][] image_data_main, // first index - number of image in a quad
final double [][][] image_data_aux, // first index - number of image in a quad
final boolean [][] saturation_main, // (near) saturated pixels or null
final boolean [][] saturation_aux, // (near) saturated pixels or null
// correlation results - combo will be for the correlation between two quad cameras
final double [][][][] 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
final double [][] disparity_bimap, // [23][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
final double [][] ml_data, // data for ML - 18 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
final double [][][][] texture_tiles_main, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
final double [][][][] texture_tiles_aux, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
final int width, // may be not multiple of 8, same for the height
final GeometryCorrection geometryCorrection_main,
final GeometryCorrection geometryCorrection_aux,
final double [][][][][][] clt_kernels_main, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
final double [][][][][][] clt_kernels_aux, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
final double corr_magic_scale, // still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
final boolean keep_clt_data,
// final int [][] woi_tops,
final double [][][] ers_delay, // if not null - fill with tile center acquisition delay
final int threadsMax, // maximal number of threads to launch
final int debugLevel,
final double [][][] port_xy_main_dbg, // for each tile/port save x,y pixel coordinates (gpu code development)
final double [][][] port_xy_aux_dbg) // for each tile/port save x,y pixel coordinates (gpu code development)
{
final int globalDebugLevel = clt_parameters.rig.rig_mode_debug?debugLevel:-2;
final int debug_tileX = clt_parameters.tileX;
final int debug_tileY = clt_parameters.tileY;
final int quad_main = image_data_main.length; // number of subcameras
final int quad_aux = image_data_aux.length; // number of subcameras
final int numcol = 3; // number of colors
final int nChn = image_data_main[0].length;
final int height=image_data_main[0][0].length/width;
final int tilesX=width/clt_parameters.transform_size;
final int tilesY=height/clt_parameters.transform_size;
final int nTilesInChn=tilesX*tilesY;
// clt_data does not need to be for the whole image (no, it is used for textures)
final double [][][][][][][] clt_bidata = (keep_clt_data)? (new double[2][][][][][][]):null;
if (clt_bidata != null) {
clt_bidata[0] = new double[quad_main][nChn][tilesY][tilesX][][];
clt_bidata[1] = new double[quad_aux][nChn][tilesY][tilesX][][];
}
final double [][] lt_corr = (lt_rad > 0)? (new double [nTilesInChn][]):null; // will keep inter-camera combo correlation, later combined in a separate multi-thread run
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final double [] col_weights= new double [numcol]; // colors are RBG
col_weights[2] = 1.0/(1.0 + clt_parameters.corr_red + clt_parameters.corr_blue); // green color
// If it was low-texture mode, use lt_corr to average bi-quad inter-correlation between neighbor tiles and then calculate disparity/strength
if (lt_corr != null) {
//notch_mode
// prepare weights for neighbors
final int lt_rad_x = notch_mode? 0: lt_rad;
final double [][] neib_weights = new double[lt_rad+1][lt_rad_x+1];
for (int i = 0; i <= lt_rad; i++) {
for (int j = 0; j <= lt_rad_x; j++) {
neib_weights[i][j] = Math.cos(Math.PI * i /(2 * lt_rad + 1)) * Math.cos(Math.PI * j /(2 * lt_rad + 1)); // no need to normalize - it will need to skip empty tiles anyway
}
}
// final int corr_size = clt_parameters.transform_size * 2 -1;
final TileNeibs tnImage = new TileNeibs(tilesX, tilesY);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
(globalDebugLevel > -1)); // boolean debug)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) if (lt_corr[nTile] != null){ // center must be non-null (from tile_op)
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
double [] tile_corrs = new double [corr_size * corr_size];
double sw = 0.0;
for (int dy = -lt_rad; dy <= lt_rad; dy++) {
int ady = (dy > 0)? dy:(-dy);
for (int dx = -lt_rad_x; dx <= lt_rad_x; dx++) {
int nTile1 = tnImage.getNeibIndex(nTile, dx, dy);
if (nTile1 >= 0) {
double [] ot_corr = lt_corr[nTile1];
if (ot_corr != null) {
int adx = (dx > 0)? dx:(-dx);
double nw = neib_weights[ady][adx];
for (int i = 0; i < tile_corrs.length; i++) {
tile_corrs[i] += nw * ot_corr[i];
}
sw+=nw;
}
}
}
}
if (sw > 0.0) { // with the current window should always be so, as te center tile is non-null
double s = 1.0/sw;
for (int i = 0; i < tile_corrs.length; i++) {
tile_corrs[i] *= s;
}
if (clt_corr_combo != null) { // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
tcorr_combo = new double [TCORR_TITLES.length][corr_size * corr_size];