Commit 9d06cce7 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: Derive DNN temporal depth from ONNX input shape (8/9 swap)

CuasDnnInfer reads N (temporal frame count) from the model's input
shape [B,N,H,W] and exposes getNFrames(); the constructor arg is now
only a fallback hint. CuasDetectRT uses dnn.getNFrames() instead of the
hardcoded 8, so an 8- vs 9-frame ONNX swaps purely by changing
curt_dnn_model (N follows automatically).
Co-Authored-By: 's avatarClaude Opus 4.8 (1M context) <noreply@anthropic.com>
parent 1f04cb6a
......@@ -1162,15 +1162,15 @@ public class CuasDetectRT {
} // By Claude on 06/11/2026
// DNN front-end (-DNN): if curt_dnn_model is set, run the trained FCN per-pixel // By Claude on 06/13/2026
// (stride-1, matching training) over the ROI -> (Vx,Vy,s) field = softmax(vel)*s,
// same shape as the C5P output, saved as -DNN-RECT / -DNN-HYPER-RECT. N=8 frames
// (training). Reuses curt_c5_levels for level gating. Recurrent feed is the next step
// same shape as the C5P output, saved as -DNN-RECT / -DNN-HYPER-RECT. N (temporal
// depth, 8 or 9) is read from the loaded ONNX. Reuses curt_c5_levels for level gating. Recurrent feed is the next step
// (the field is [0,1]-scaled, unlike the C5P matched-filter response - needs rescale).
if (!clt_parameters.imp.curt_dnn_model.isEmpty() && (curt_save_select != null)) { // By Claude on 06/13/2026
final int N_dnn = 8; // By Claude on 06/13/2026
final int vr_dnn = clt_parameters.imp.curt_vel_radius; // By Claude on 06/13/2026
final int dnn_stride = Math.max(1, clt_parameters.imp.curt_dnn_stride); // 1 = every slice (testing), 4 = production 50% overlap // By Claude on 06/14/2026
try { // By Claude on 06/13/2026
CuasDnnInfer dnn = new CuasDnnInfer(clt_parameters.imp.curt_dnn_model, N_dnn); // By Claude on 06/13/2026
CuasDnnInfer dnn = new CuasDnnInfer(clt_parameters.imp.curt_dnn_model, 8); // 8 = fallback hint only // By Claude on 06/13/2026
final int N_dnn = dnn.getNFrames(); // 8 or 9, read from the loaded ONNX input shape -> 8/9 models swap at runtime // By Claude on 06/15/2026
for (int nlev = 0; nlev < pyramid_levels; nlev++) { // By Claude on 06/13/2026
if (!c5LevelSelected(c5_levels, nlev)) continue; // level gating (curt_c5_levels) // By Claude on 06/13/2026
double [][] framesD = dpixels_pyramid[nlev]; // By Claude on 06/13/2026
......
......@@ -34,16 +34,29 @@ public class CuasDnnInfer implements AutoCloseable {
public CuasDnnInfer(String modelSpec, int nframes) throws Exception {
String local = resolveModel(modelSpec);
this.nframes = nframes;
this.env = OrtEnvironment.getEnvironment();
OrtSession.SessionOptions opts = new OrtSession.SessionOptions();
// CPU EP by default. GPU later: opts.addCUDA(deviceId) once cuDNN 9 is present.
this.session = env.createSession(local, opts);
this.inputName = session.getInputNames().iterator().next(); // "frames"
// Derive temporal depth (N frames) from the model's input shape [B, N, H, W] so an
// 8- vs 9-frame model swaps at runtime; the constructor arg is only a fallback hint.
// By Claude on 06/15/2026
int modelN = nframes;
try {
ai.onnxruntime.NodeInfo ni = session.getInputInfo().get(inputName);
long[] shape = ((ai.onnxruntime.TensorInfo) ni.getInfo()).getShape();
if ((shape != null) && (shape.length >= 2) && (shape[1] > 0)) modelN = (int) shape[1];
} catch (Exception e) { /* keep the hint value */ }
this.nframes = modelN;
System.out.println("CuasDnnInfer: loaded " + local + " input=" + inputName
+ " outputs=" + session.getOutputNames());
+ " outputs=" + session.getOutputNames() + " nframes=" + this.nframes
+ ((modelN != nframes) ? " (hint was " + nframes + ")" : ""));
}
/** Temporal depth the loaded model expects (N frames), read from its input shape. By Claude on 06/15/2026 */
public int getNFrames() { return nframes; }
/** Run one patch. frames = [N][H][W] (newest first). Returns the raw output channels
* [outCh] for the center output pixel: [0]=det logit, [1..V*V]=vel logits, last 2 = offset. */
public float[] inferRaw(float[][][] frames) throws Exception {
......
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