Commit 88737b12 authored by Andrey Filippov's avatar Andrey Filippov

more editing for lwir/monochrome, Bayer images are OK

parent 15babaaf
package com.elphel.imagej.cameras;
public class ThermalColor {
private static double PALETTE_RANGE = 255.0;
double [][] palette = null;
double min = 0.0;
double max = 1.0;
double out_range = 255.0;
public ThermalColor(
int palette_indx,
double min,
double max,
double out_range) {
this.min = min;
this.max = max;
this.out_range = out_range;
int [] ipalette = setupPalette(palette_indx);
this.palette = new double [ipalette.length][3];
for (int i = 0; i < ipalette.length; i++) {
this.palette[i][0] = (ipalette[i] >> 16) & 0xff; // Red
this.palette[i][1] = (ipalette[i] >> 8) & 0xff; // Green
this.palette[i][2] = (ipalette[i] >> 0) & 0xff; // Blue
}
}
public double [] getRGB(double v) { // Get R,G,B (0..255) triplet for input value in the range 0..1
double k = out_range/PALETTE_RANGE;
double value = (v-min)/(max-min);
int ivalue = (int) (value/(this.palette.length - 1));
if (ivalue < 0) return this.palette[0];
if (ivalue >= (this.palette.length -1)) return this.palette[this.palette.length -1];
double a = (value-ivalue)*(this.palette.length - 1); // 0..1
double [] rslt = {
k*((1 - a) * this.palette[ivalue][0] + a * this.palette[ivalue+1][0]),
k*((1 - a) * this.palette[ivalue][1] + a * this.palette[ivalue+1][1]),
k*((1 - a) * this.palette[ivalue][2] + a * this.palette[ivalue+1][2])};
return rslt;
}
private int [] setupPalette(int indx) {
//https://stackoverflow.com/questions/28495390/thermal-imaging-palette
int [] white_hot_palette = {0x000000, 0xffffff};
int [] black_hot_palette = {0xffffff, 0x000000};
int [] iron_palette = {
0x00000a, 0x000014, 0x00001e, 0x000025, 0x00002a, 0x00002e, 0x000032, 0x000036,
0x00003a, 0x00003e, 0x000042, 0x000046, 0x00004a, 0x00004f, 0x000052, 0x010055,
0x010057, 0x020059, 0x02005c, 0x03005e, 0x040061, 0x040063, 0x050065, 0x060067,
0x070069, 0x08006b, 0x09006e, 0x0a0070, 0x0b0073, 0x0c0074, 0x0d0075, 0x0d0076,
0x0e0077, 0x100078, 0x120079, 0x13007b, 0x15007c, 0x17007d, 0x19007e, 0x1b0080,
0x1c0081, 0x1e0083, 0x200084, 0x220085, 0x240086, 0x260087, 0x280089, 0x2a0089,
0x2c008a, 0x2e008b, 0x30008c, 0x32008d, 0x34008e, 0x36008e, 0x38008f, 0x390090,
0x3b0091, 0x3c0092, 0x3e0093, 0x3f0093, 0x410094, 0x420095, 0x440095, 0x450096,
0x470096, 0x490096, 0x4a0096, 0x4c0097, 0x4e0097, 0x4f0097, 0x510097, 0x520098,
0x540098, 0x560098, 0x580099, 0x5a0099, 0x5c0099, 0x5d009a, 0x5f009a, 0x61009b,
0x63009b, 0x64009b, 0x66009b, 0x68009b, 0x6a009b, 0x6c009c, 0x6d009c, 0x6f009c,
0x70009c, 0x71009d, 0x73009d, 0x75009d, 0x77009d, 0x78009d, 0x7a009d, 0x7c009d,
0x7e009d, 0x7f009d, 0x81009d, 0x83009d, 0x84009d, 0x86009d, 0x87009d, 0x89009d,
0x8a009d, 0x8b009d, 0x8d009d, 0x8f009c, 0x91009c, 0x93009c, 0x95009c, 0x96009b,
0x98009b, 0x99009b, 0x9b009b, 0x9c009b, 0x9d009b, 0x9f009b, 0xa0009b, 0xa2009b,
0xa3009b, 0xa4009b, 0xa6009a, 0xa7009a, 0xa8009a, 0xa90099, 0xaa0099, 0xab0099,
0xad0099, 0xae0198, 0xaf0198, 0xb00198, 0xb00198, 0xb10197, 0xb20197, 0xb30196,
0xb40296, 0xb50295, 0xb60295, 0xb70395, 0xb80395, 0xb90495, 0xba0495, 0xba0494,
0xbb0593, 0xbc0593, 0xbd0593, 0xbe0692, 0xbf0692, 0xbf0692, 0xc00791, 0xc00791,
0xc10890, 0xc10990, 0xc20a8f, 0xc30a8e, 0xc30b8e, 0xc40c8d, 0xc50c8c, 0xc60d8b,
0xc60e8a, 0xc70f89, 0xc81088, 0xc91187, 0xca1286, 0xca1385, 0xcb1385, 0xcb1484,
0xcc1582, 0xcd1681, 0xce1780, 0xce187e, 0xcf187c, 0xcf197b, 0xd01a79, 0xd11b78,
0xd11c76, 0xd21c75, 0xd21d74, 0xd31e72, 0xd32071, 0xd4216f, 0xd4226e, 0xd5236b,
0xd52469, 0xd62567, 0xd72665, 0xd82764, 0xd82862, 0xd92a60, 0xda2b5e, 0xda2c5c,
0xdb2e5a, 0xdb2f57, 0xdc2f54, 0xdd3051, 0xdd314e, 0xde324a, 0xde3347, 0xdf3444,
0xdf3541, 0xdf363d, 0xe0373a, 0xe03837, 0xe03933, 0xe13a30, 0xe23b2d, 0xe23c2a,
0xe33d26, 0xe33e23, 0xe43f20, 0xe4411d, 0xe4421c, 0xe5431b, 0xe54419, 0xe54518,
0xe64616, 0xe74715, 0xe74814, 0xe74913, 0xe84a12, 0xe84c10, 0xe84c0f, 0xe94d0e,
0xe94d0d, 0xea4e0c, 0xea4f0c, 0xeb500b, 0xeb510a, 0xeb520a, 0xeb5309, 0xec5409,
0xec5608, 0xec5708, 0xec5808, 0xed5907, 0xed5a07, 0xed5b06, 0xee5c06, 0xee5c05,
0xee5d05, 0xee5e05, 0xef5f04, 0xef6004, 0xef6104, 0xef6204, 0xf06303, 0xf06403,
0xf06503, 0xf16603, 0xf16603, 0xf16703, 0xf16803, 0xf16902, 0xf16a02, 0xf16b02,
0xf16b02, 0xf26c01, 0xf26d01, 0xf26e01, 0xf36f01, 0xf37001, 0xf37101, 0xf37201,
0xf47300, 0xf47400, 0xf47500, 0xf47600, 0xf47700, 0xf47800, 0xf47a00, 0xf57b00,
0xf57c00, 0xf57e00, 0xf57f00, 0xf68000, 0xf68100, 0xf68200, 0xf78300, 0xf78400,
0xf78500, 0xf78600, 0xf88700, 0xf88800, 0xf88800, 0xf88900, 0xf88a00, 0xf88b00,
0xf88c00, 0xf98d00, 0xf98d00, 0xf98e00, 0xf98f00, 0xf99000, 0xf99100, 0xf99200,
0xf99300, 0xfa9400, 0xfa9500, 0xfa9600, 0xfb9800, 0xfb9900, 0xfb9a00, 0xfb9c00,
0xfc9d00, 0xfc9f00, 0xfca000, 0xfca100, 0xfda200, 0xfda300, 0xfda400, 0xfda600,
0xfda700, 0xfda800, 0xfdaa00, 0xfdab00, 0xfdac00, 0xfdad00, 0xfdae00, 0xfeaf00,
0xfeb000, 0xfeb100, 0xfeb200, 0xfeb300, 0xfeb400, 0xfeb500, 0xfeb600, 0xfeb800,
0xfeb900, 0xfeb900, 0xfeba00, 0xfebb00, 0xfebc00, 0xfebd00, 0xfebe00, 0xfec000,
0xfec100, 0xfec200, 0xfec300, 0xfec400, 0xfec500, 0xfec600, 0xfec700, 0xfec800,
0xfec901, 0xfeca01, 0xfeca01, 0xfecb01, 0xfecc02, 0xfecd02, 0xfece03, 0xfecf04,
0xfecf04, 0xfed005, 0xfed106, 0xfed308, 0xfed409, 0xfed50a, 0xfed60a, 0xfed70b,
0xfed80c, 0xfed90d, 0xffda0e, 0xffda0e, 0xffdb10, 0xffdc12, 0xffdc14, 0xffdd16,
0xffde19, 0xffde1b, 0xffdf1e, 0xffe020, 0xffe122, 0xffe224, 0xffe226, 0xffe328,
0xffe42b, 0xffe42e, 0xffe531, 0xffe635, 0xffe638, 0xffe73c, 0xffe83f, 0xffe943,
0xffea46, 0xffeb49, 0xffeb4d, 0xffec50, 0xffed54, 0xffee57, 0xffee5b, 0xffee5f,
0xffef63, 0xffef67, 0xfff06a, 0xfff06e, 0xfff172, 0xfff177, 0xfff17b, 0xfff280,
0xfff285, 0xfff28a, 0xfff38e, 0xfff492, 0xfff496, 0xfff49a, 0xfff59e, 0xfff5a2,
0xfff5a6, 0xfff6aa, 0xfff6af, 0xfff7b3, 0xfff7b6, 0xfff8ba, 0xfff8bd, 0xfff8c1,
0xfff8c4, 0xfff9c7, 0xfff9ca, 0xfff9cd, 0xfffad1, 0xfffad4, 0xfffbd8, 0xfffcdb,
0xfffcdf, 0xfffde2, 0xfffde5, 0xfffde8, 0xfffeeb, 0xfffeee, 0xfffef1, 0xfffef4, 0xfffff};
int [][] palettes = {white_hot_palette, black_hot_palette, iron_palette};
if (indx <0) indx = 0;
else if (indx >= palettes.length) indx = palettes.length - 1;
return palettes[indx];
}
}
......@@ -43,6 +43,8 @@ public class Correlation2d {
private final double [] corr_wndx;
private final double [] corr_wndy;
private final double [] corr_wndy_notch;
private final boolean monochrome;
// configuration for 8-lens and 4-lens cameras. 8-lens has baseline = 1 for 1..4 and 1/2 for 4..7
/*0 1
......@@ -89,6 +91,7 @@ public class Correlation2d {
{-2, -3, 0, 1},
{ 3, -2, -1, 0}};
public boolean isMonochrome() {return monochrome;}
// for 8 cameras and 16 pairs. Following data moved from ImageDtt
// which images to use (0..3 - external, 4..7 - internal)
public static int getImgMask (int data){ return (data & 0xff);}
......@@ -127,7 +130,9 @@ public class Correlation2d {
ImageDttParameters imgdtt_params,
int transform_size,
double wndx_scale, // (wndy scale is always 1.0)
boolean monochrome,
boolean debug) {
this.monochrome = monochrome;
this.dtt = new DttRad2(transform_size);
this.transform_size = transform_size;
this.transform_len = transform_size * transform_size;
......
......@@ -63,6 +63,8 @@ public class ImageDtt {
static int QUAD = 4; // number of cameras in camera
static int GREEN_CHN = 2; // index of green channel
static int MONO_CHN = 2; // index of channel used in monochrome mode
static int DISPARITY_INDEX_INT = 0; // 0 - disparity from correlation integer pixels, 1 - ortho
// Now DISPARITY_INDEX_CM may be POLY with backup from CM (for bad correlation)
static int DISPARITY_INDEX_CM = 2; // 2 - disparity from correlation "center mass", 3 - ortho (only used for fine correction)
......@@ -199,7 +201,7 @@ public class ImageDtt {
static int TCORR_COMBO_VERT = 3; // combined correlation from 2 vertical pairs (0,1). Used to detect horizontal features
static String [] TCORR_TITLES = {"combo","sum","hor","vert"};
public boolean monochrome = false;
private final boolean monochrome;
public static int getImgMask (int data){ return (data & 0xf);} // which images to use
......@@ -211,8 +213,12 @@ public class ImageDtt {
public static boolean getOrthoLines (int data){return (data & 0x200) != 0;}
public static int setOrthoLines (int data, boolean force) {return (data & ~0x200) | (force?0x200:0);}
public ImageDtt(boolean monochrome){
this.monochrome = monochrome;
public ImageDtt(boolean mono){
monochrome = mono;
}
public boolean isMonochrome() {
return monochrome;
}
public double [][][][] mdctStack(
......@@ -1522,10 +1528,6 @@ public class ImageDtt {
final double min_corr, // 0.02; // minimal correlation value to consider valid
final double max_corr_sigma, // 1.2; // weights of points around global max to find fractional
final double max_corr_radius, // 3.9;
// final int enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
// final double enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
final boolean max_corr_double, //"Double pass when masking center of mass to reduce preference for integer values
final int corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
final double min_shot, // 10.0; // Do not adjust for shot noise if lower than
......@@ -1555,12 +1557,11 @@ public class ImageDtt {
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
// final boolean debug_ports_coordinates = (debug_tileX == -1234);
// final double poly_corr = imgdtt_params.poly_corr_scale; // maybe add per-tile task bits to select none/near/far
final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data
final int quad = 4; // number of subcameras
final int numcol = 3; // number of colors
final int numcol = 3; // number of colors // keep the same, just do not use [0] and [1], [2] - green
final int nChn = image_data[0].length;
final int height=image_data[0][0].length/width;
final int tilesX=width/transform_size;
......@@ -1570,6 +1571,8 @@ public class ImageDtt {
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final double [] col_weights= new double [numcol]; // colors are RBG
// 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;
......@@ -1724,15 +1727,11 @@ public class ImageDtt {
}
}
// final double [] corr_max_weights_poly =(((max_corr_sigma > 0) && (disparity_map != null))?
// setMaxXYWeights(max_corr_sigma,max_search_radius_poly): null); // here use square anyway
dtt.set_window(window_type);
final double [] lt_window = dtt.getWin2d(); // [256]
final double [] lt_window2 = new double [lt_window.length]; // squared
for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i];
if (globalDebugLevel > 1) {
ShowDoubleFloatArrays sdfa_instance = new ShowDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(lt_window, 2*transform_size, 2*transform_size, "lt_window");
......@@ -1763,19 +1762,16 @@ public class ImageDtt {
double [][][] tcorr_partial = null; // [quad][numcol+1][15*15]
double [][][][] tcorr_tpartial = null; // [quad][numcol+1][4][8*8]
double [] ports_rgb = null;
// PolynomialApproximation pa = null;
// if (corr_max_weights_poly !=null) pa = new PolynomialApproximation(0); // debug level
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.enhortho_width, // double enhortho_width,
imgdtt_params.enhortho_scale, //double enhortho_scale,
(imgdtt_params.lma_debug_level > 1)); // boolean debug);
// public int enhortho_width = 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
// public double enhortho_scale = 0.0; // 0.2; // multiply center correlation pixels (inside enhortho_width)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
......@@ -1902,8 +1898,8 @@ public class ImageDtt {
dtt
);
}
for (int chn = 0; chn <numcol; chn++) {
// See if macro_mode uses color channels for non-color?
for (int chn = 0; chn <numcol; chn++) if (!isMonochrome() || (chn == MONO_CHN) || macro_mode) { // in monochrome mode skip all non-mono (green) channels
boolean debug_for_fpga = FPGA_COMPARE_DATA && (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2);
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println("\nUsing "+(macro_mode?"MACRO":"PIXEL")+" mode, centerX="+centerX+", centerY="+centerY);
......@@ -2023,8 +2019,7 @@ public class ImageDtt {
false, // ); // transpose);
((saturation_imp != null) ? saturation_imp[i] : null), //final boolean [][] saturation_imp, // (near) saturated pixels or null
((saturation_imp != null) ? overexp_all: null)); // final double [] overexposed)
}
} // for (int i = 0; i < quad; i++)
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println();
}
......@@ -2044,7 +2039,6 @@ public class ImageDtt {
}
}
// if (!no_fract_shift && !FPGA_COMPARE_DATA) {
if (!no_fract_shift) {
// apply residual shift
for (int i = 0; i < quad; i++) {
......@@ -2054,7 +2048,9 @@ public class ImageDtt {
fract_shiftsXY[i][0], // double shiftX,
fract_shiftsXY[i][1], // double shiftY,
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
((globalDebugLevel > 1) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
((globalDebugLevel > 1) &&
((chn==0) || isMonochrome()) &&
(tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
}
if ((globalDebugLevel > 0) && (debug_tileX == tileX) && (debug_tileY == tileY)) {
......@@ -2068,7 +2064,7 @@ public class ImageDtt {
}
}
} // end of for (int chn = 0; chn <numcol; chn++) if (!isMonochrome() || (chn == MONO_CHN) || macro_mode) { // in monochrome mode skip all non-mono (green) channels
int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? imgdtt_params.lma_debug_level : -1;
......@@ -3860,8 +3856,8 @@ public class ImageDtt {
public double [][] combineRGBATiles(
// in monochrome mode only MONO_CHN == GREEN_CHN is used, R and B are null
public double [][] combineRBGATiles(
final double [][][][] texture_tiles, // array [tilesY][tilesX][4][4*transform_size] or [tilesY][tilesX]{null}
final int transform_size,
final boolean overlap, // when false - output each tile as 16x16, true - overlap to make 8x8
......@@ -3932,13 +3928,21 @@ public class ImageDtt {
for (int i = 0; i < n2;i++){
int start_line = ((tileY*transform_size + i) * tilesX + tileX)*transform_size - offset;
for (int chn = 0; chn < texture_tile.length; chn++) {
if ((chn != 3) || !sharp_alpha) {
for (int j = 0; j<n2;j++) {
dpixels[chn][start_line + j] += texture_tile[chn][n2 * i + j];
}
} else if ((i >= n_half) && (i < (n2-n_half))) {
for (int j = n_half; j < (n2 - n_half); j++) {
dpixels[chn][start_line + j] += texture_tile[chn][n2 * i + j];
int schn = chn;
if (isMonochrome() && (chn<3)) {
schn = MONO_CHN; // clone green to red and blue output
}
if (texture_tile[schn] == null) {
dpixels[chn] = null;
} else {
if ((chn != 3) || !sharp_alpha) {
for (int j = 0; j<n2;j++) {
dpixels[chn][start_line + j] += texture_tile[schn][n2 * i + j];
}
} else if ((i >= n_half) && (i < (n2-n_half))) {
for (int j = n_half; j < (n2 - n_half); j++) {
dpixels[chn][start_line + j] += texture_tile[schn][n2 * i + j];
}
}
}
}
......@@ -3950,20 +3954,28 @@ public class ImageDtt {
((tileY == lastY) && (i < (n2 - n_half)))) {
int start_line = ((tileY*transform_size + i) * tilesX + tileX)*transform_size - offset;
for (int chn = 0; chn < texture_tile.length; chn++) {
if ((chn != 3) || !sharp_alpha) {
for (int j = 0; j<n2;j++) {
if ( ((tileX > 0) && (tileX < lastX)) ||
((tileX == 0) && (j >= n_half)) ||
((tileX == lastX) && (j < (n2 - n_half)))) {
dpixels[chn][start_line + j] += texture_tile[chn][n2 * i + j];
int schn = chn;
if (isMonochrome() && (chn<3)) {
schn = MONO_CHN; // clone green to red and blue output
}
if (texture_tile[schn] == null) {
dpixels[chn] = null;
} else {
if ((chn != 3) || !sharp_alpha) {
for (int j = 0; j<n2;j++) {
if ( ((tileX > 0) && (tileX < lastX)) ||
((tileX == 0) && (j >= n_half)) ||
((tileX == lastX) && (j < (n2 - n_half)))) {
dpixels[chn][start_line + j] += texture_tile[schn][n2 * i + j];
}
}
}
} else if ((i >= n_half) && (i < (n2-n_half))) {
for (int j = n_half; j < (n2 - n_half); j++) {
if ( ((tileX > 0) && (tileX < lastX)) ||
((tileX == 0) && (j >= n_half)) ||
((tileX == lastX) && (j < (n2 - n_half)))) {
dpixels[chn][start_line + j] += texture_tile[chn][n2 * i + j];
} else if ((i >= n_half) && (i < (n2-n_half))) {
for (int j = n_half; j < (n2 - n_half); j++) {
if ( ((tileX > 0) && (tileX < lastX)) ||
((tileX == 0) && (j >= n_half)) ||
((tileX == lastX) && (j < (n2 - n_half)))) {
dpixels[chn][start_line + j] += texture_tile[schn][n2 * i + j];
}
}
}
}
......@@ -3975,12 +3987,21 @@ public class ImageDtt {
} else { //if (overlap) - just copy tiles w/o overlapping
for (int i = 0; i < n2;i++){
for (int chn = 0; chn < texture_tile.length; chn++) {
System.arraycopy(
texture_tile[chn],
i * n2,
dpixels[chn],
(tileY * n2 + i)* width + tileX*n2,
n2);
int schn = chn;
if (isMonochrome() && (chn<3)) {
schn = MONO_CHN; // clone green to red and blue output
}
if (texture_tile[schn] == null) {
dpixels[chn] = null;
} else {
System.arraycopy(
texture_tile[schn],
i * n2,
dpixels[chn],
(tileY * n2 + i)* width + tileX*n2,
n2);
}
}
}
}
......@@ -4894,6 +4915,12 @@ public class ImageDtt {
if (debug_fpga) debugLevel = 1;
if (debug_gpu) debugLevel = 0; // 1; // skip too many images
int chn_kernel = chn;
// use zero kernel channel for monochrome images
if ((clt_kernels != null) && (clt_kernels.length <= chn_kernel)) {
chn_kernel = clt_kernels.length - 1;
}
boolean use_kernels = (clt_kernels != null) && !dbg_no_deconvolution;
boolean bdebug0 = debugLevel > 0;
boolean bdebug = debugLevel > 1;
......@@ -4912,11 +4939,11 @@ public class ImageDtt {
ktileX = (int) Math.round(centerX/kernel_step) + 1;
ktileY = (int) Math.round(centerY/kernel_step) + 1;
if (ktileY < 0) ktileY = 0;
else if (ktileY >= clt_kernels[chn].length) ktileY = clt_kernels[chn].length-1;
else if (ktileY >= clt_kernels[chn_kernel].length) ktileY = clt_kernels[chn_kernel].length-1;
if (ktileX < 0) ktileX = 0;
else if (ktileX >= clt_kernels[chn][ktileY].length) ktileX = clt_kernels[chn][ktileY].length-1;
else if (ktileX >= clt_kernels[chn_kernel][ktileY].length) ktileX = clt_kernels[chn_kernel][ktileY].length-1;
// extract center offset data stored with each kernel tile
CltExtra ce = new CltExtra (clt_kernels[chn][ktileY][ktileX][4]);
CltExtra ce = new CltExtra (clt_kernels[chn_kernel][ktileY][ktileX][4]);
// 2. calculate correction for center of the kernel offset
double kdx = centerX - (ktileX -1 +0.5) * kernel_step; // difference in pixel
double kdy = centerY - (ktileY -1 +0.5) * kernel_step;
......@@ -4926,7 +4953,7 @@ public class ImageDtt {
px = centerX - transform_size - (ce.data_x + ce.dxc_dx * kdx + ce.dxc_dy * kdy) ; // fractional left corner
py = centerY - transform_size - (ce.data_y + ce.dyc_dx * kdx + ce.dyc_dy * kdy) ; // fractional top corner
if (debug_gpu) {
System.out.println("========= Color channel "+chn+" =============");
System.out.println("========= Color channel "+chn+" , kernel channel "+chn_kernel+" =============");
System.out.println("ce.data_x="+ce.data_x+", ce.data_y="+ce.data_y);
System.out.println("ce.center_x="+ce.center_x+", ce.center_y="+ce.center_y);
System.out.println("ce.dxc_dx="+ce.dxc_dx+", ce.dxc_dy="+ce.dxc_dy);
......@@ -4986,7 +5013,6 @@ public class ImageDtt {
if (debug_fpga){ // show extended tile, all colors
// //FPGA_TILE_SIZE
System.out.println("\nFull Bayer fpga tile data");
int lt = (FPGA_TILE_SIZE - transform_size2)/2;
double [][] fpga_tile = new double [3][FPGA_TILE_SIZE * FPGA_TILE_SIZE];
......@@ -5009,9 +5035,7 @@ public class ImageDtt {
}
if ((chn == GREEN_CHN) && (saturation_imp != null)) {
// double overexp_fract = 1.0/(transform_size2 * transform_size2 * QUAD);
// int num_overexp = 0;
if (((chn == GREEN_CHN) || isMonochrome()) && (saturation_imp != null)) {
//overexp_all
if ((ctile_left >= 0) && (ctile_left < (width - transform_size2)) &&
(ctile_top >= 0) && (ctile_top < (height - transform_size2))) {
......@@ -5263,29 +5287,8 @@ public class ImageDtt {
}
}
// clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size);
/*
if (bdebug) {
double [] clt_tile_dbg = clt_tile[dct_mode].clone();
double [] clt_tile_dbg1 = clt_tile[dct_mode].clone();
clt_tile_dbg1 = dtt.dttt_ivn (clt_tile_dbg1, dct_mode, transform_size,true);
clt_tile_dbg = dtt.dttt_ivn (clt_tile_dbg, dct_mode, transform_size,false);
clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size);
System.out.println("\n-------- 2: dct_mode="+dct_mode+" ---#, standard, good, bad, diff---");
for (int nt = 0; nt < clt_tile_dbg.length; nt++) {
System.out.println(String.format("%2d: %8f %8f %8f %8f %8f",
nt, clt_tile[dct_mode][nt],clt_tile_dbg[nt], clt_tile_dbg1[nt],clt_tile_dbg[nt] - clt_tile_dbg[nt], clt_tile_dbg1[nt] - clt_tile_dbg[nt]));
}
System.out.println("done debug");
} else {
*/
clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size);
/*
}
*/
if (debug_gpu) {
System.out.println("=== Image tile DTT converted for color="+chn+", dct_mode="+dct_mode+" ===");
for (int i = 0; i < transform_size; i++) {
......@@ -5375,12 +5378,7 @@ public class ImageDtt {
System.out.println();
}
System.out.println();
//apply rotation
}
} // end of if (debug_fpga){
......@@ -5392,9 +5390,9 @@ public class ImageDtt {
}
// deconvolve with kernel
if (use_kernels) {
double [][] ktile = clt_kernels[chn][ktileY][ktileX];
double [][] ktile = clt_kernels[chn_kernel][ktileY][ktileX];
if (debug_gpu) {
System.out.println("=== kernel tile for color="+chn+" ===");
System.out.println("=== kernel tile for color="+chn_kernel+" (color = "+chn+") ===");
for (int dct_mode = 0; dct_mode < 4; dct_mode++) {
System.out.println("dct_mode="+dct_mode);
for (int i = 0; i < transform_size; i++) {
......@@ -5944,7 +5942,7 @@ public class ImageDtt {
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
if (imgdtt_params.corr_var_cam) {
if (imgdtt_params.corr_var_cam) { // New correlation mode compatible with 8 subcameras
return clt_aberrations_quad_corr_new(
imgdtt_params, // Now just extra correlation parameters, later will include, most others
macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
......@@ -5977,10 +5975,6 @@ public class ImageDtt {
min_corr, // 0.02; // minimal correlation value to consider valid
max_corr_sigma, // 1.2; // weights of points around global max to find fractional
max_corr_radius, // 3.9;
// final int enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
// final double enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
max_corr_double, //"Double pass when masking center of mass to reduce preference for integer values
corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
min_shot, // 10.0; // Do not adjust for shot noise if lower than
......@@ -6009,7 +6003,7 @@ public class ImageDtt {
no_deconvolution,
threadsMax, // maximal number of threads to launch
globalDebugLevel);
} else {
} else { // old way?
return clt_aberrations_quad_corr_old(
imgdtt_params, // Now just extra correlation parameters, later will include, most others
macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
......@@ -6357,6 +6351,7 @@ public class ImageDtt {
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(
......@@ -8142,6 +8137,7 @@ public class ImageDtt {
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(globalDebugLevel > -1)); // boolean debug)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
......@@ -8651,6 +8647,7 @@ public class ImageDtt {
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(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;
......@@ -8941,6 +8938,7 @@ public class ImageDtt {
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(globalDebugLevel > -1)); // boolean debug)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
......@@ -9425,6 +9423,7 @@ public class ImageDtt {
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(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;
......@@ -9661,6 +9660,7 @@ public class ImageDtt {
clt_parameters.img_dtt, // ImageDttParameters imgdtt_params,
clt_parameters.transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(globalDebugLevel > -1)); // boolean debug)
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
......
......@@ -43,6 +43,7 @@ import com.elphel.imagej.calibration.PixelMapping;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters;
import com.elphel.imagej.cameras.EyesisCorrectionParameters;
import com.elphel.imagej.cameras.ThermalColor;
import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.correction.CorrectionColorProc;
......@@ -100,7 +101,10 @@ public class QuadCLT {
// magic scale should be set before using TileProcessor (calculated disparities depend on it)
public boolean isMonochrome() {return is_mono;} // clt_kernels
public void resetGroundTruthByRig() {
public boolean isLwir() {return !Double.isNaN(lwir_offset);} // clt_kernels
public double getLwirOffset() {return lwir_offset;}
public void resetGroundTruthByRig() {
tp.rig_disparity_strength = null;
}
public double [][] getGroundTruthByRig(){
......@@ -3983,11 +3987,12 @@ public class QuadCLT {
// visualize texture tiles as RGBA slices
double [][] texture_nonoverlap = null;
double [][] texture_overlap = null;
String [] rgba_titles = {"red","blue","green","alpha"};
String [] rgba_weights_titles = {"red","blue","green","alpha","port0","port1","port2","port3","r-rms","b-rms","g-rms","w-rms"};
String [] rbga_titles = {"red","blue","green","alpha"};
String [] rbga_weights_titles = {"red","blue","green","alpha","port0","port1","port2","port3","r-rms","b-rms","g-rms","w-rms"};
// In monochrome mode only G is used ImageDtt.MONO_CHN(==2), others are null
if (texture_tiles != null){
if (clt_parameters.show_nonoverlap){
texture_nonoverlap = image_dtt.combineRGBATiles(
texture_nonoverlap = image_dtt.combineRBGATiles(
texture_tiles, // array [tp.tilesY][tp.tilesX][4][4*transform_size] or [tp.tilesY][tp.tilesX]{null}
clt_parameters.transform_size,
false, // when false - output each tile as 16x16, true - overlap to make 8x8
......@@ -4000,12 +4005,12 @@ public class QuadCLT {
tilesY * (2 * clt_parameters.transform_size),
true,
name + "-TXTNOL-D"+clt_parameters.disparity,
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
(clt_parameters.keep_weights?rbga_weights_titles:rbga_titles));
}
if (!infinity_corr && (clt_parameters.show_overlap || clt_parameters.show_rgba_color)){
int alpha_index = 3;
texture_overlap = image_dtt.combineRGBATiles(
texture_overlap = image_dtt.combineRBGATiles(
texture_tiles, // array [tp.tilesY][tp.tilesX][4][4*transform_size] or [tp.tilesY][tp.tilesX]{null}
clt_parameters.transform_size,
true, // when false - output each tile as 16x16, true - overlap to make 8x8
......@@ -4030,7 +4035,7 @@ public class QuadCLT {
tilesY * clt_parameters.transform_size,
true,
name + "-TXTOL-D"+clt_parameters.disparity,
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
(clt_parameters.keep_weights?rbga_weights_titles:rbga_titles));
}
if (!batch_mode && clt_parameters.show_rgba_color) {
// for now - use just RGB. Later add option for RGBA
......@@ -4481,8 +4486,9 @@ public class QuadCLT {
ShowDoubleFloatArrays sdfa_instance = new ShowDoubleFloatArrays(); // just for debugging?
// convert to ImageStack of 3 slices
String [] sliceNames = {"red", "blue", "green"};
int green_index = 2;
double [] alpha = null; // (0..1.0)
double [][] rgb_in = {iclt_data[0],iclt_data[1],iclt_data[2]};
double [][] rbg_in = {iclt_data[0],iclt_data[1],iclt_data[2]};
float [] alpha_pixels = null;
if (iclt_data.length > 3) {
alpha = iclt_data[3];
......@@ -4493,8 +4499,26 @@ public class QuadCLT {
}
}
}
if (isLwir()) {
double offset = getLwirOffset();
double mn = colorProcParameters.lwir_low - offset;
double mx = colorProcParameters.lwir_high - offset;
ThermalColor tc = new ThermalColor(
colorProcParameters.lwir_palette,
mn,
mx,
255.0);
rbg_in = new double [3][iclt_data[green_index].length];
for (int i = 0; i < rbg_in.length; i++) {
double [] rgb = tc.getRGB(iclt_data[green_index][i]);
rbg_in[i][0] = rgb[0]; // red