Commit fa7a57b3 authored by Andrey Filippov's avatar Andrey Filippov

Added gated CLT kernels display, kernel normalization by the absolute

value
parent 284f6ae1
......@@ -76,6 +76,7 @@ public class CLTParameters {
private double scale_strength_main = 1.0;// leave as is
private double scale_strength_aux = 0.3;// reduce to match lower sigma
public boolean norm_kern = true; // normalize kernels
public boolean norm_kern_abs = false;// normalize kernels absolute value (for those with sum=0
public boolean gain_equalize = false;// equalize green channel gain (bug fix for wrong exposure in Exif ?)
public boolean colors_equalize = true; // equalize R/G, B/G of the individual channels
public boolean nosat_equalize = true; // Skip saturated when adjusting gains
......@@ -1319,6 +1320,7 @@ public class CLTParameters {
properties.setProperty(prefix+"scale_strength_aux", this.scale_strength_aux+"");
properties.setProperty(prefix+"norm_kern", this.norm_kern+"");
properties.setProperty(prefix+"norm_kern_abs", this.norm_kern_abs+"");
properties.setProperty(prefix+"gain_equalize", this.gain_equalize+"");
properties.setProperty(prefix+"colors_equalize", this.colors_equalize+"");
properties.setProperty(prefix+"nosat_equalize", this.nosat_equalize+"");
......@@ -2377,6 +2379,7 @@ public class CLTParameters {
if (properties.getProperty(prefix+"scale_strength_aux")!=null) this.scale_strength_aux=Double.parseDouble(properties.getProperty(prefix+"scale_strength_aux"));
if (properties.getProperty(prefix+"norm_kern")!=null) this.norm_kern=Boolean.parseBoolean(properties.getProperty(prefix+"norm_kern"));
if (properties.getProperty(prefix+"norm_kern_abs")!=null) this.norm_kern_abs=Boolean.parseBoolean(properties.getProperty(prefix+"norm_kern_abs"));
if (properties.getProperty(prefix+"gain_equalize")!=null) this.gain_equalize=Boolean.parseBoolean(properties.getProperty(prefix+"gain_equalize"));
if (properties.getProperty(prefix+"colors_equalize")!=null) this.colors_equalize=Boolean.parseBoolean(properties.getProperty(prefix+"colors_equalize"));
if (properties.getProperty(prefix+"nosat_equalize")!=null) this.nosat_equalize=Boolean.parseBoolean(properties.getProperty(prefix+"nosat_equalize"));
......@@ -3461,6 +3464,7 @@ public class CLTParameters {
gd.addNumericField("Scale all correlation strengths (to compensate correlation sigma) for aux camera", this.scale_strength_aux, 4);
gd.addCheckbox ("Normalize kernels", this.norm_kern);
gd.addCheckbox ("Normalize kernels absolute values", this.norm_kern_abs);
gd.addCheckbox ("Equalize green channel gain of the individual cnannels (bug fix for exposure)", this.gain_equalize);
gd.addCheckbox ("Equalize R/G, B/G balance of the individual channels", this.colors_equalize);
gd.addCheckbox ("Skip saturated when adjusting gains", this.nosat_equalize);
......@@ -5000,6 +5004,7 @@ public class CLTParameters {
this.scale_strength_main = gd.getNextNumber();
this.scale_strength_aux = gd.getNextNumber();
this.norm_kern= gd.getNextBoolean();
this.norm_kern_abs= gd.getNextBoolean();
this.gain_equalize= gd.getNextBoolean();
this.colors_equalize= gd.getNextBoolean();
this.nosat_equalize= gd.getNextBoolean();
......
......@@ -4570,8 +4570,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
DEBUG_LEVEL);
//==============================================================================
} else if (label.equals("Create AUX CLT kernels")) {
if (!CLT_PARAMETERS.showJDialog())
return;
// if (!CLT_PARAMETERS.showJDialog())
// return;
if (EYESIS_CORRECTIONS_AUX == null) {
EYESIS_CORRECTIONS_AUX = new EyesisCorrections(SYNC_COMMAND.stopRequested,
CORRECTION_PARAMETERS.getAux());
......
......@@ -337,7 +337,18 @@ public class CuasRender {
img_width, img_height, num_comps);
rendered.clear(); // release ~11GB before the next render pass
System.out.println("testRenderSequence(): LoG A/B - uploading FOLDED aberration+LoG kernels (CuasLogFold, tap-precompensated)");
gpuQuad.setConvolutionKernels(CuasLogFold.foldKernels(orig_kernels, log_td), true);
double [][][][][][] folded_kernels=CuasLogFold.foldKernels(orig_kernels, log_td);
if (clt_parameters.curt.show_kernels) {
GpuQuad.showCLtKernel(
folded_kernels, // double [][][][][][] clt_kernels,
"folded-kernel", // String prefix,
0, // int nsens,
0, // int ncol,
clt_parameters.tileX/2, // int ktilex, // half tileX
clt_parameters.tileY/2); // int ktiley) { // half tileY
}
// gpuQuad.setConvolutionKernels(CuasLogFold.foldKernels(orig_kernels, log_td), true);
gpuQuad.setConvolutionKernels(folded_kernels, true);
final ArrayList<String> ts_names2 = new ArrayList<String>();
final ArrayList<float [][]> rendered2 = renderPass(
clt_parameters, center_CLT, quadCLTs, image_dtt, ers_center,
......@@ -346,9 +357,20 @@ public class CuasRender {
saveRenderHyper(center_CLT, "-CUAS-RT-RENDER-LOG-FOLDED", rendered2, ts_names2,
img_width, img_height, num_comps);
}
if (clt_parameters.curt.log_ident) {
System.out.println("testRenderSequence(): LoG A/B - uploading IDENTITY kernels (aberrations skipped)");
gpuQuad.setConvolutionKernels(CuasLogFold.uniformKernels(orig_kernels, null), true);
// gpuQuad.setConvolutionKernels(CuasLogFold.uniformKernels(orig_kernels, null), true);
double [][][][][][] uniform_kernels=CuasLogFold.uniformKernels(orig_kernels, null);
if (clt_parameters.curt.show_kernels) {
GpuQuad.showCLtKernel(
uniform_kernels, // double [][][][][][] clt_kernels,
"uniform-kernel", // String prefix,
0, // int nsens,
0, // int ncol,
clt_parameters.tileX/2, // int ktilex, // half tileX
clt_parameters.tileY/2); // int ktiley) { // half tileY
}
gpuQuad.setConvolutionKernels(uniform_kernels, true);
final ArrayList<String> ts_id = new ArrayList<String>();
final ArrayList<float [][]> rend_id = renderPass(
clt_parameters, center_CLT, quadCLTs, image_dtt, ers_center,
......@@ -362,7 +384,18 @@ public class CuasRender {
img_width, img_height, num_comps);
rend_id.clear();
System.out.println("testRenderSequence(): LoG A/B - uploading PURE-LoG kernels (LoG-only, aberrations skipped)");
gpuQuad.setConvolutionKernels(CuasLogFold.uniformKernels(orig_kernels, log_td), true);
uniform_kernels=CuasLogFold.uniformKernels(orig_kernels, log_td);
if (clt_parameters.curt.show_kernels) {
GpuQuad.showCLtKernel(
uniform_kernels, // double [][][][][][] clt_kernels,
"uniform-LoG-kernel", // String prefix,
0, // int nsens,
0, // int ncol,
clt_parameters.tileX/2, // int ktilex, // half tileX
clt_parameters.tileY/2); // int ktiley) { // half tileY
}
// gpuQuad.setConvolutionKernels(CuasLogFold.uniformKernels(orig_kernels, log_td), true);
gpuQuad.setConvolutionKernels(uniform_kernels, true);
final ArrayList<String> ts_lo = new ArrayList<String>();
final ArrayList<float [][]> rend_lo = renderPass(
clt_parameters, center_CLT, quadCLTs, image_dtt, ers_center,
......@@ -370,7 +403,6 @@ public class CuasRender {
mb_en, mb_tau, mb_max_gain, ts_lo, debugLevel);
saveRenderHyper(center_CLT, "-CUAS-RT-RENDER-LOG-ONLY", rend_lo, ts_lo,
img_width, img_height, num_comps);
}
} finally { // ALWAYS restore the original kernels for anything running after
gpuQuad.setConvolutionKernels(orig_kernels, true);
System.out.println("testRenderSequence(): LoG A/B - original kernels restored");
......
......@@ -46,6 +46,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.tileprocessor.CorrVector;
import com.elphel.imagej.tileprocessor.Correlation2d;
import com.elphel.imagej.tileprocessor.DttRad2;
......@@ -5258,4 +5259,49 @@ public class GpuQuad{ // quad camera description
this.gpu_debug_level = gpu_debug_level;
}
public static void showCLtKernel(
double [][][][][][] clt_kernels,
String prefix,
int nsens,
int ncol,
int ktilex, // half tileX
int ktiley) { // half tileY
if (prefix == null) {
return;
}
if ((nsens<0) || (nsens > clt_kernels.length) || (clt_kernels[nsens] == null)) {
return;
}
if ((ncol<0) || (ncol > clt_kernels[nsens].length) || (clt_kernels[nsens][ncol] == null)) {
return;
}
if ((ktiley<0) || (ktiley > clt_kernels[nsens][ncol].length) || (clt_kernels[nsens][ncol][ktiley] == null)) {
return;
}
if ((ktilex<0) || (ktilex > clt_kernels[nsens][ncol][ktiley].length) || (clt_kernels[nsens][ncol][ktiley][ktilex] == null)) {
return;
}
double [][] dbg_clt = {
clt_kernels[nsens][ncol][ktiley][ktilex][0],
clt_kernels[nsens][ncol][ktiley][ktilex][1],
clt_kernels[nsens][ncol][ktiley][ktilex][2],
clt_kernels[nsens][ncol][ktiley][ktilex][3]};
String [] titles = {"CC", "SC", "CS", "SS"};
int length=dbg_clt[0].length;
int size=(int) Math.sqrt(length);
ShowDoubleFloatArrays.showArrays(
dbg_clt,
size,
size,
true,
prefix+"-ktx"+ktilex+"-kty"+ktiley+"-nsens"+nsens+"-ncol"+ncol,
titles);
System.out.println("showCLtKernel() sens="+nsens+", color="+ncol+" prefix="+prefix+", "+
" kileX = "+ktilex+", "+
" kileY = "+ktiley+", "+
" center_x = "+clt_kernels[nsens][ncol][ktiley][ktilex][4][0]+", "+
" center_y = "+clt_kernels[nsens][ncol][ktiley][ktilex][4][1]);
}
} // end of public class GpuQuad
\ No newline at end of file
......@@ -30,6 +30,7 @@ public class CuasRtParameters {
public boolean rend_test = false; // RT full-render product (CuasRender.testRenderSequence): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. NON-exclusive: runs AFTER the pose stage when both are ON (the pose stage is part of the RT cycle - Andrey 07/06/2026). // By Claude on 07/05/2026
public boolean log_test = false; // LoG A/B with the RT render (CuasRender): also save -CUAS-RT-RENDER-LOG-ORACLE (product convolved with the EXISTING pre-DNN pixel LoG, LINEAR alpha=1) and -CUAS-RT-RENDER-LOG-FOLDED (same render, LoG folded into the GPU aberration kernels via CuasLogFold - no pixel convolution; originals restored). The aberration+LoG kernel-fold validation (RT-seed step 1b). // By Claude on 07/06/2026
public boolean log_ident = false; // LoG ISOLATION test with the RT render (CuasRender): render with IDENTITY kernels (-CUAS-RT-RENDER-ID, aberrations skipped), pixel-LoG it (-ID-LOG-ORACLE), and render with PURE-LoG kernels (-LOG-ONLY). If -LOG-ONLY vs -ID-LOG-ORACLE residual persists, the fold/L0 is wrong; if it collapses to the wrap floor, the aberration-kernel interaction was responsible (Andrey 07/06/2026). // By Claude on 07/06/2026
public boolean show_kernels = false; // show selected convolution kernel
public boolean dbg_fpixels = true; // save the ORACLE debug renders during ingest (prepareFpixels): -CUAS-INDIVIDUAL-CUAS-DBG (an EXTRA per-sensor render pass, ~11GB) + -CUAS-MERGED-CUAS-DBG (save only - the merged render is the production input regardless). Was hardcoded. Turn OFF to save the render time and disk once the RT chain (-CUAS-RT-RENDER) is the trusted full render. // By Claude on 07/05/2026
public double fz_inter = 10000.0; // RT fat zero, INTER (pose/motion: scene x virtual-center correlation). DECOUPLED from the legacy gpu_fatz*/AUX switches (which stay untouched for non-RT/FOPEN). Value is for a single physical-pair amplitude; FZ ~ amplitude^2 in the GPU normalize - scale down x4..x16 for consolidated-average applications as needed. 10000 = the proven oracle INTER operating point (the lean code erroneously used the INTRA value before). // By Claude on 07/05/2026
public double fz_intra = 2000.0; // RT fat zero, INTRA (ranging/disparity: sensor-pair correlations within one scene). Reserved for the RT ranging path; same decoupling/scaling notes as fz_inter. // By Claude on 07/05/2026
......@@ -119,6 +120,10 @@ public class CuasRtParameters {
"With the RT render ON: also save -CUAS-RT-RENDER-LOG-ORACLE (the product convolved with the EXISTING pre-DNN pixel-domain LoG, LINEAR) and -CUAS-RT-RENDER-LOG-FOLDED (same render with the LoG FOLDED into the GPU aberration kernels - no pixel convolution; original kernels restored after). Compare offline: the aberration+LoG kernel-fold validation (roadmap RT-seed step 1b).");
gd.addCheckbox ("RT render LoG isolation (identity krnl)", this.log_ident, // By Claude on 07/06/2026
"With the RT render ON: render with IDENTITY kernels (-ID, aberrations skipped), apply the pixel LoG (-ID-LOG-ORACLE), then render with PURE-LoG kernels (-LOG-ONLY). Isolates the LoG fold mechanism from the aberration-kernel content: persistent -LOG-ONLY vs -ID-LOG-ORACLE residual = the fold is wrong; collapse to the wrap floor = kernel interaction. Two extra render passes.");
gd.addCheckbox ("Show selected convolution kernel", this.show_kernels,
"Show convolution kernels for selected in General tab tile (ktilex = tileX/2, ktileY=tileY/2.");
gd.addCheckbox ("Save oracle DBG renders (11GB)", this.dbg_fpixels, // By Claude on 07/05/2026
"Save -CUAS-INDIVIDUAL-CUAS-DBG (an EXTRA per-sensor render pass, ~11GB) and -CUAS-MERGED-CUAS-DBG during ingest. Turn OFF to save render time and disk once -CUAS-RT-RENDER (RT render test) is the trusted full render.");
gd.addNumericField("RT fat zero INTER (pose/motion)", this.fz_inter, 1,9,"", // By Claude on 07/05/2026
......@@ -264,6 +269,7 @@ public class CuasRtParameters {
this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026
this.log_test = gd.getNextBoolean(); // By Claude on 07/06/2026
this.log_ident = gd.getNextBoolean(); // By Claude on 07/06/2026
this.show_kernels = gd.getNextBoolean();
this.dbg_fpixels = gd.getNextBoolean(); // By Claude on 07/05/2026
this.fz_inter = gd.getNextNumber(); // By Claude on 07/05/2026
this.fz_intra = gd.getNextNumber(); // By Claude on 07/05/2026
......@@ -349,6 +355,7 @@ public class CuasRtParameters {
properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"log_test", this.log_test+""); // boolean // By Claude on 07/06/2026
properties.setProperty(prefix+"log_ident", this.log_ident+""); // boolean // By Claude on 07/06/2026
properties.setProperty(prefix+"show_kernels", this.show_kernels+""); // boolean
properties.setProperty(prefix+"dbg_fpixels", this.dbg_fpixels+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_inter", this.fz_inter+""); // double // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_intra", this.fz_intra+""); // double // By Claude on 07/05/2026
......@@ -434,6 +441,7 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"log_test")!=null) this.log_test=Boolean.parseBoolean(properties.getProperty(prefix+"log_test")); // By Claude on 07/06/2026
if (properties.getProperty(prefix+"log_ident")!=null) this.log_ident=Boolean.parseBoolean(properties.getProperty(prefix+"log_ident")); // By Claude on 07/06/2026
if (properties.getProperty(prefix+"show_kernels")!=null) this.show_kernels=Boolean.parseBoolean(properties.getProperty(prefix+"show_kernels"));
if (properties.getProperty(prefix+"dbg_fpixels")!=null) this.dbg_fpixels=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_fpixels")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_inter")!=null) this.fz_inter=Double.parseDouble(properties.getProperty(prefix+"fz_inter")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_intra")!=null) this.fz_intra=Double.parseDouble(properties.getProperty(prefix+"fz_intra")); // By Claude on 07/05/2026
......@@ -522,6 +530,7 @@ public class CuasRtParameters {
cp.rend_test = this.rend_test; // By Claude on 07/05/2026
cp.log_test = this.log_test; // By Claude on 07/06/2026
cp.log_ident = this.log_ident; // By Claude on 07/06/2026
cp.show_kernels = this.show_kernels;
cp.dbg_fpixels = this.dbg_fpixels; // By Claude on 07/05/2026
cp.fz_inter = this.fz_inter; // By Claude on 07/05/2026
cp.fz_intra = this.fz_intra; // By Claude on 07/05/2026
......
......@@ -10491,6 +10491,7 @@ public class ImageDttCPU {
void clt_normalize_kernel( // not used in lwir
double [] kernel, // should be (2*dtt_size-1) * (2*dtt_size-1) + 4 size (last (2*dtt_size-1) are not modified)
double [] window, // normalizes result kernel * window to have sum of elements == 1.0
boolean norm_kern_abs,
boolean bdebug)
{
double s = 0.0;
......@@ -10499,7 +10500,11 @@ public class ImageDttCPU {
int ai = (i < 0)? -i: i;
for (int j = -transform_size + 1; j < transform_size; j++){
int aj = (j < 0)? -j: j;
s += kernel[indx++] * window[ai*transform_size+aj];
double k = kernel[indx++];
if (norm_kern_abs) {
k = Math.abs(k);
}
s += k * window[ai*transform_size+aj];
}
}
s = 1.0/s;
......
......@@ -8333,6 +8333,7 @@ LogTee.clearSceneLog(); // stop per‑scene logging
final int numberOfKernels= kernelNumHor*kernelNumVert*nChn;
final int numberOfKernelsInChn=kernelNumHor*kernelNumVert;
final double [] norm_sym_weights = clt_parameters.norm_kern ? new double [dtt_size*dtt_size]:null;
final boolean norm_kern_abs = clt_parameters.norm_kern_abs;
if (norm_sym_weights != null) {
for (int i = 0; i < dtt_size; i++){
for (int j = 0; j < dtt_size; j++){
......@@ -8490,6 +8491,7 @@ LogTee.clearSceneLog(); // stop per‑scene logging
kernel_centered, // double [] kernel, // should be (2*dtt_size-1) * (2*dtt_size-1) + extra_items size (last (2*dtt_size-1) are not modified)
norm_sym_weights, // double [] window, // normalizes result kernel * window to have sum of elements == 1.0
/// dtt_size,
norm_kern_abs, // boolean norm_kern_abs,
(globalDebugLevel > 0) && (tileY == clt_parameters.tileY/2) && (tileX == clt_parameters.tileX/2)); // 8
if ((globalDebugLevel > 0) && (tileY == clt_parameters.tileY/2) && (tileX == clt_parameters.tileX/2)) {
int length=kernel_centered.length;
......@@ -8901,7 +8903,7 @@ LogTee.clearSceneLog(); // stop per‑scene logging
IJ.showStatus(msg);
if (debugLevel>0) System.out.println(msg);
ImagePlus imp_clt=new ImagePlus(imp_kernel_sharp.getTitle()+"-clt",cltStack);
if (debugLevel > 0) {
if (debugLevel > 3) { //0) {
imp_clt.getProcessor().resetMinAndMax();
imp_clt.show();
}
......@@ -8959,7 +8961,7 @@ LogTee.clearSceneLog(); // stop per‑scene logging
for (int nc = 0; nc < nColors; nc++){
flat_kernels[nc]= (float[]) kernel_clt_stack.getPixels(nc + 1);
}
clt_kernels[chn] = extractCLTKernels ( // per color, save 4 kernelas and displacement as (2*dtt_size+1)*(2*dtt_size) tiles in an image (last row - shift x,y)
clt_kernels[chn] = extractCLTKernels ( // per color, save 4 kernels and displacement as (2*dtt_size+1)*(2*dtt_size) tiles in an image (last row - shift x,y)
flat_kernels, // per color/per tileY/ per tileX/per quadrant (plus offset as 5-th)/per pixel
kernel_clt_stack.getWidth(), // final int width,
dtt_size,
......@@ -8967,8 +8969,18 @@ LogTee.clearSceneLog(); // stop per‑scene logging
updateStatus,
debugLevel); // update status info
if (clt_parameters.curt.show_kernels && isLwir() && (chn==0)) {
GpuQuad.showCLtKernel(
clt_kernels, // double [][][][][][] clt_kernels,
"aberration-kernel", // String prefix,
chn, // int nsens,
0, // int ncol,
clt_parameters.tileX/2, // int ktilex, // half tileX
clt_parameters.tileY/2); // int ktiley) { // half tileY
}
if (debugLevel>10) { // (sdfa_instance != null){
if (clt_parameters.curt.show_kernels)
for (int nc = 0; nc < clt_kernels[chn].length; nc++){
double [][] dbg_clt = {
clt_kernels[chn][nc][clt_parameters.tileY/2][clt_parameters.tileX/2][0],
......
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