Commit aac34c6a authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Claude: Add temporal LPF to shiftAndRenderAccumulate and refineMotionVectors inputs



- Extract precorr_ra, accum_ra, cuas_gaussian_ra in locateAndFreezeTargetsMulti
- Compute fpixels_accum (LPF with cuas_accum_ra) for shiftAndRenderAccumulate in both loops
- Compute fpixels_refine (LPF with cuas_precorr_ra) for refineMotionVectors
- Both use Gaussian or running-average depending on cuas_gaussian_ra flag
- When ra==1, LPF is a no-op (passes fpixels_tum through unchanged)

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 7f0ce136
Loading
Loading
Loading
Loading
+34 −11
Original line number Original line Diff line number Diff line
@@ -2240,6 +2240,7 @@ public class CuasMotion {
			int                 half_accum_range,   // corr_pairs/2
			int                 half_accum_range,   // corr_pairs/2
			boolean             smooth,
			boolean             smooth,
			int                 corr_offset,        // inter-frame distance for correlation pairs
			int                 corr_offset,        // inter-frame distance for correlation pairs
			int                 dbg_iter_index,     // to generate different image names for different iteration to simplify "save as" images
			int                 debugLevel) {
			int                 debugLevel) {


		final int tileSize = GPUTileProcessor.DTT_SIZE;   // 8 pixels
		final int tileSize = GPUTileProcessor.DTT_SIZE;   // 8 pixels
@@ -2257,8 +2258,8 @@ public class CuasMotion {
		final int corr_pairs_ref = (int) Math.round(2 * half_accum_range * recalc_mv_boost);
		final int corr_pairs_ref = (int) Math.round(2 * half_accum_range * recalc_mv_boost);


		// Hard-coded debug selectors: set >= 0 to enable per-scan/per-tile visualisation
		// Hard-coded debug selectors: set >= 0 to enable per-scan/per-tile visualisation
		final int dbg_nseq = 116; // 57; // 20; // -1;
		final int dbg_nseq = 157; // -(116); // 57; // 20; // -1;
		final int dbg_tile = 17 + 33*80; // 48+32*80; // 50+38*80; // -1;
		final int dbg_tile = 55+38*80; // -(17 + 33*80); // 48+32*80; // 50+38*80; // -1;


		// Pre-compute integer-pixel raised-cosine mask kernel once (shared across all nseq)
		// Pre-compute integer-pixel raised-cosine mask kernel once (shared across all nseq)
		final int r1i = (int) Math.ceil(recalc_mv_r1);
		final int r1i = (int) Math.ceil(recalc_mv_r1);
@@ -2276,7 +2277,7 @@ public class CuasMotion {
		}
		}
		if ((dbg_nseq >= 0 || dbg_tile >= 0) && debugLevel >= 0) {
		if ((dbg_nseq >= 0 || dbg_tile >= 0) && debugLevel >= 0) {
			ShowDoubleFloatArrays.showArrays(mask_kernel.clone(), mside, mside,
			ShowDoubleFloatArrays.showArrays(mask_kernel.clone(), mside, mside,
					"refineMotionVectors-mask-r0_" + recalc_mv_r0 + "-r1_" + recalc_mv_r1);
					"refineMotionVectors-mask-r0_" + recalc_mv_r0 + "-r1_" + recalc_mv_r1+"-niter"+dbg_iter_index);
		}
		}


		// Allocate staging array once; each nseq clears only the frames it needs
		// Allocate staging array once; each nseq clears only the frames it needs
@@ -2380,7 +2381,7 @@ public class CuasMotion {
							? scene_titles_all[f] : "f" + f;
							? scene_titles_all[f] : "f" + f;
				}
				}
				ShowDoubleFloatArrays.showArrays(stack_slices, width, height, true,
				ShowDoubleFloatArrays.showArrays(stack_slices, width, height, true,
						"refineMotionVectors-masked-nseq" + nseq, stack_titles);
						"refineMotionVectors-masked-nseq" + nseq+"-niter"+dbg_iter_index, stack_titles);
			}
			}
			if (nseq == dbg_nseq && debugLevel >= 0) {
			if (nseq == dbg_nseq && debugLevel >= 0) {
				int fcount = fmax_alloc - fmin_alloc + 1;
				int fcount = fmax_alloc - fmin_alloc + 1;
@@ -2393,7 +2394,7 @@ public class CuasMotion {
							? scene_titles_all[f] : "f" + f;
							? scene_titles_all[f] : "f" + f;
				}
				}
				ShowDoubleFloatArrays.showArrays(stack_slices, width, height, true,
				ShowDoubleFloatArrays.showArrays(stack_slices, width, height, true,
						"refineMotionVectors-nseq" + nseq, stack_titles);
						"refineMotionVectors-nseq" + nseq+"-niter"+dbg_iter_index, stack_titles);
			}
			}


			TDCorrTile[] tdCorrTiles = cuasMotion.correlatePairs( // By Claude on 05/06/2026
			TDCorrTile[] tdCorrTiles = cuasMotion.correlatePairs( // By Claude on 05/06/2026
@@ -2468,7 +2469,7 @@ public class CuasMotion {
					dbg_2d_corrs,
					dbg_2d_corrs,
					cuasMotion.tilesX * (corr_size + 1),
					cuasMotion.tilesX * (corr_size + 1),
					cuasMotion.tilesY * (corr_size + 1),
					cuasMotion.tilesY * (corr_size + 1),
					"refineMotionVectors-CORR2D",
					"refineMotionVectors-CORR2D"+"-n"+dbg_iter_index,
					slice_titles_ref).show();
					slice_titles_ref).show();
		}
		}
	}
	}
@@ -3527,7 +3528,7 @@ public class CuasMotion {
		}		      
		}		      
		ImageDtt.startAndJoin(threads);
		ImageDtt.startAndJoin(threads);
		ai.set(0);
		ai.set(0);
		return fpixels;
		return fpixels; // should be fpixels_filtered ???
	}
	}
	
	
	public static float [][] subtract(
	public static float [][] subtract(
@@ -7953,6 +7954,9 @@ public class CuasMotion {
		double  duplicate_tolerance = clt_parameters.imp.cuas_duplicate_tolerance ; // 2.0; // (pix) Remove weaker maximums closer than this to a stronger one   		
		double  duplicate_tolerance = clt_parameters.imp.cuas_duplicate_tolerance ; // 2.0; // (pix) Remove weaker maximums closer than this to a stronger one   		
		boolean debug_more =     clt_parameters.imp.cuas_debug_more;
		boolean debug_more =     clt_parameters.imp.cuas_debug_more;
		double  boost_accum_pairs =    slow_mode? 1.0: clt_parameters.imp.cuas_boost_accum; //  4.0;   // if >1 and the motion vector is below tile_size/cuas_boost_slow, scale corr_pairs
		double  boost_accum_pairs =    slow_mode? 1.0: clt_parameters.imp.cuas_boost_accum; //  4.0;   // if >1 and the motion vector is below tile_size/cuas_boost_slow, scale corr_pairs
		int     precorr_ra =           clt_parameters.imp.cuas_precorr_ra;   // By Claude on 05/07/2026
		int     accum_ra =             clt_parameters.imp.cuas_accum_ra;     // By Claude on 05/07/2026: LPF for shiftAndRenderAccumulate
		boolean cuas_gaussian_ra =     clt_parameters.imp.cuas_gaussian_ra;  // By Claude on 05/07/2026


		for (int i = 0; i < target_frac.length; i++) {
		for (int i = 0; i < target_frac.length; i++) {
			if (clt_parameters.imp.cuas_target_frac[i].length >= 2) {
			if (clt_parameters.imp.cuas_target_frac[i].length >= 2) {
@@ -8003,6 +8007,24 @@ public class CuasMotion {
		}
		}
		final int num_seq = motion_sequence.length;
		final int num_seq = motion_sequence.length;
		final int num_tiles = motion_sequence[0].length;
		final int num_tiles = motion_sequence[0].length;
		// By Claude on 05/07/2026: temporal LPF for accumulation and MV refinement inputs
		// fpixels_accum: LPF for shiftAndRenderAccumulate (accum_ra); fpixels_refine: LPF for refineMotionVectors (precorr_ra)
		final float [][] fpixels_accum;
		if (accum_ra > 1) {
			fpixels_accum = cuas_gaussian_ra ?
					runningGaussian(fpixels_tum, accum_ra, cuasMotion.gpu_max_width) :
					runningAverage( fpixels_tum, accum_ra, cuasMotion.gpu_max_width);
		} else {
			fpixels_accum = fpixels_tum;
		}
		final float [][] fpixels_refine;
		if (precorr_ra > 1) {
			fpixels_refine = cuas_gaussian_ra ?
					runningGaussian(fpixels_tum, precorr_ra, cuasMotion.gpu_max_width) :
					runningAverage( fpixels_tum, precorr_ra, cuasMotion.gpu_max_width);
		} else {
			fpixels_refine = fpixels_tum;
		}
		if (target_sequence_multi == null) {
		if (target_sequence_multi == null) {
			//		final double [][][][]
			//		final double [][][][]
			target_sequence_multi = new double [num_seq][num_tiles][][];
			target_sequence_multi = new double [num_seq][num_tiles][][];
@@ -8138,7 +8160,7 @@ public class CuasMotion {
						clt_parameters,   // CLTParameters       clt_parameters,
						clt_parameters,   // CLTParameters       clt_parameters,
						false,            // final boolean       center,
						false,            // final boolean       center,
						false,            // final boolean       fill_zeros,
						false,            // final boolean       fill_zeros,
						fpixels_tum,      // final float [][]    fpixels,
						fpixels_accum,    // By Claude on 05/07/2026: LPF'd with accum_ra (was fpixels_tum)
						extended_scan,    // final double [][][] vector_field,
						extended_scan,    // final double [][][] vector_field,
						frame0,           // final int           frame0,      // for vector_field[0]
						frame0,           // final int           frame0,      // for vector_field[0]
						corr_inc,         // final int           frame_step,
						corr_inc,         // final int           frame_step,
@@ -8486,13 +8508,14 @@ public class CuasMotion {
						recalc_mv_boost,     // double          recalc_mv_boost,
						recalc_mv_boost,     // double          recalc_mv_boost,
						recalc_mv_r0,        // double          recalc_mv_r0,
						recalc_mv_r0,        // double          recalc_mv_r0,
						recalc_mv_r1,        // double          recalc_mv_r1,
						recalc_mv_r1,        // double          recalc_mv_r1,
						fpixels_tum,         // float [][]      fpixels,
						fpixels_refine,      // By Claude on 05/07/2026: LPF'd with precorr_ra (was fpixels_tum)
						targets_nonoverlap,  // double [][][]   targets_nonoverlap,
						targets_nonoverlap,  // double [][][]   targets_nonoverlap,
						frame0,              // int             frame0,
						frame0,              // int             frame0,
						corr_inc,            // int             corr_inc,
						corr_inc,            // int             corr_inc,
						half_accum_range,    // int             half_accum_range,
						half_accum_range,    // int             half_accum_range,
						smooth,              // boolean         smooth,
						smooth,              // boolean         smooth,
						corr_offset,         // int             corr_offset,
						corr_offset,         // int             corr_offset,
						niter, // int                 dbg_iter_index,
						debugLevel);         // int             debugLevel)
						debugLevel);         // int             debugLevel)
			}
			}
			double [][][] extended_scan = extendMotionScan(
			double [][][] extended_scan = extendMotionScan(
@@ -8515,7 +8538,7 @@ public class CuasMotion {
					clt_parameters,   // CLTParameters       clt_parameters,
					clt_parameters,   // CLTParameters       clt_parameters,
					true, // false,            // final boolean       center, // why is it false here?
					true, // false,            // final boolean       center, // why is it false here?
					false,            // final boolean       fill_zeros,
					false,            // final boolean       fill_zeros,
					fpixels_tum,      // final float [][]    fpixels,
					fpixels_accum,    // By Claude on 05/07/2026: LPF'd with accum_ra (was fpixels_tum)
					extended_scan,    // final double [][][] vector_field,
					extended_scan,    // final double [][][] vector_field,
					frame0,           // final int           frame0,      // for vector_field[0]
					frame0,           // final int           frame0,      // for vector_field[0]
					corr_inc,         // final int           frame_step,  // keep for slow
					corr_inc,         // final int           frame_step,  // keep for slow