Commit eb6a764f authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: Add showConvKernel5d(ROI) visualization and wire curt_save_c5rect

New CuasRTUtils.showConvKernel5d(data, roi, titles, title): renders the
vout_dim×vout_dim velocity map for each ROI pixel as a tiled flat image,
with a 1-px NaN separator grid between pixel blocks (visible in ImageJ).
Sub-pixels (pixel_decimate>1) tile within each block.

CuasDetectRT: add curt_save_c5rect save calls at level-0 and each pyramid
level (title suffix "-RECT", "-LEVn-RECT"). curt_save_c5full path unchanged.
Co-authored-by: 's avatarClaude <claude@elphel.com>
parent e5955421
......@@ -306,6 +306,14 @@ public class CuasDetectRT {
title_conv5d);
QuadCLTCPU.saveImagePlusInDirectory(imp_5d, getModelDirectory());
}
if (curt_save_c5rect && num_5d_lev0 > 0) {
ImagePlus imp_5d_rect = cuasRTUtils.showConvKernel5d(
dpixels_5d_pyramid[0],
curt_save_select,
ts_5d_lev0,
title_conv5d+"-RECT");
QuadCLTCPU.saveImagePlusInDirectory(imp_5d_rect, getModelDirectory());
}
for (int nlev = 0; nlev < pyramid_levels; nlev++) {
if (save_LoG_pixels) {
String title_conv2d_lev = getBaseName()+SUFFIX_CONV2D+"-PSF"+d2s(cuasRTUtils.getPsfRadius())+
......@@ -374,6 +382,14 @@ public class CuasDetectRT {
title_conv5d+"-LEV"+(nlev+1));
QuadCLTCPU.saveImagePlusInDirectory(imp_5d, getModelDirectory());
}
if (curt_save_c5rect && num_5d_lev > 0) {
ImagePlus imp_5d_rect = cuasRTUtils.showConvKernel5d(
dpixels_5d_pyramid[nlev+1],
curt_save_select,
ts_5d_lev,
title_conv5d+"-LEV"+(nlev+1)+"-RECT");
QuadCLTCPU.saveImagePlusInDirectory(imp_5d_rect, getModelDirectory());
}
}
}
return null;
......
package com.elphel.imagej.cuas.rt;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -1071,4 +1072,86 @@ public class CuasRTUtils {
return imp;
}
/**
* Render fine-velocity output for a pixel ROI as a flat image stack (one slice per scene).
* For each pixel in the ROI a (vout_dim × vout_dim) velocity-map square is drawn.
* Squares are tiled in the output image with a 1-pixel NaN separator column/row
* (renders as visible grid in ImageJ). Sub-pixels (pixel_decimate > 1) tile inside each square.
*
* Output dimensions:
* width = roi.width * (vout_dim + 1) * sub_dim
* height = roi.height * (vout_dim + 1) * sub_dim
*
* @param data [nscene][width*height][nsub][nvel] — output of convolve3d
* @param roi pixel rectangle to render (full-image coordinates)
* @param scene_titles per-slice labels, or null
* @param title image title, or null
*/
public ImagePlus showConvKernel5d(
double [][][][] data,
Rectangle roi,
String [] scene_titles,
String title) {
int num_scenes = data.length;
int num_vout = kernel5d[0].length;
int vout_dim = (int) Math.sqrt(num_vout);
int num_sub = kernel5d[0][0].length;
int sub_dim = (int) Math.sqrt(num_sub);
int roi_width = roi.width * (vout_dim + 1) * sub_dim;
int roi_height = roi.height * (vout_dim + 1) * sub_dim;
int block_w = (vout_dim + 1) * sub_dim;
int block_h = (vout_dim + 1) * sub_dim;
if (title == null) title = "CONV5D-ROI";
if (scene_titles == null) {
scene_titles = new String[num_scenes];
for (int i = 0; i < scene_titles.length; i++) {
scene_titles[i] = String.format("scene-%03d", i);
}
}
double [][] rendered = new double[num_scenes][roi_width * roi_height];
for (double [] slice : rendered) Arrays.fill(slice, Double.NaN);
for (int nscene = 0; nscene < num_scenes; nscene++) {
for (int py_roi = 0; py_roi < roi.height; py_roi++) {
int py_img = roi.y + py_roi;
if (py_img < 0 || py_img >= height) continue;
for (int px_roi = 0; px_roi < roi.width; px_roi++) {
int px_img = roi.x + px_roi;
if (px_img < 0 || px_img >= width) continue;
int pixel_idx = py_img * width + px_img;
int block_x = px_roi * block_w;
int block_y = py_roi * block_h;
double [][] pix_data = data[nscene][pixel_idx]; // [nsub][nvel]
for (int sy = 0; sy < sub_dim; sy++) {
for (int sx = 0; sx < sub_dim; sx++) {
int sub_idx = sy * sub_dim + sx;
int slot_x = block_x + sx * (vout_dim + 1);
int slot_y = block_y + sy * (vout_dim + 1);
for (int vy = 0; vy < vout_dim; vy++) {
for (int vx = 0; vx < vout_dim; vx++) {
int v_out_idx = vy * vout_dim + vx;
int rx = slot_x + vx;
int ry = slot_y + vy;
rendered[nscene][ry * roi_width + rx] = pix_data[sub_idx][v_out_idx];
}
}
}
}
}
}
}
ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
rendered,
roi_width,
roi_height,
title,
scene_titles);
imp.setDisplayRange(IMP_MINMAX[0], IMP_MINMAX[1]);
return imp;
}
}
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