dicmultiwindow_util.hpp

Functions

void multiwindow_init(std::vector<WindowLevel> &level, const bool *img_roi, const util::Config &conf, const MultiwindowConfig &mwconf, const common_util::SaveConfig &saveconf)

Initialize a multi-resolution FFT-CC pyramid (window levels).

Builds the sequence of FFT window levels from the configuration by creating progressively smaller subset sizes (powers of two) down to the final configured subset size, and associates each level with the previous one for seeding/coarse-to-fine propagation.

The constructed levels are appended to level using emplace_back(...) with:

  • mask/ROI pointer (img_roi),

  • step size for this level (half of size for power-of-two levels, or conf.ss_step for the last),

  • subset size for this level,

  • pixel pitch (conf.px_hori, conf.px_vert),

  • a boolean indicating whether there is a finer (next) level,

  • the level index,

  • a pointer to the previous level’s layout (or nullptr for the first level).

Parameters:
  • level[out] Output container to which new levels are appended.

  • img_roi[in] Pointer to the image ROI (mask) used by the layouts. Must remain valid during level construction.

  • conf[in] Runtime configuration containing max_disp, ss_size, ss_step, px_hori, px_vert.

  • saveconf[in] Configuration for saving intermediate FFT results .

void multiwindow_init_partial(std::vector<WindowLevel> &level, const bool *img_roi, const util::Config &conf, const MultiwindowConfig &mwconf, const common_util::SaveConfig &saveconf, const size_t num_levels)
struct MultiwindowConfig
#include <dicmultiwindow_util.hpp>

Configuration struct for multiwindow correlation parameters.

Members:

  • overlap : percentage overlap between adjacent subsets at each level (e.g., 50 for 50% overlap).

  • subset_size : vector of subset sizes for each level, ordered from coarsest (largest window) to finest (smallest window).

  • search_area : vector of search area sizes (in pixels) for FFT correlation at each level, ordered from coarsest to finest.

Public Members

std::vector<int> overlap
std::vector<int> subset_size
std::vector<int> search_area
struct WindowLevel
#include <dicmultiwindow_util.hpp>

Represents one level in a multiwindow FFT-based correlation hierarchy.

A WindowLevel defines:

  • the subset layout (grid) at a particular window size,

  • allocated storage for displacement fields (u, v),

  • peak metrics (max_val, cost),

  • neighbour relationships to the previous (coarser) level for seeding.

Members:

  • u, v : displacement fields for each subset at this level.

  • cost : user-defined cost value per subset (e.g., ZNSSD or debug metric).

  • max_val : peak height from FFT cross-correlation for this subset.

  • neigh_list : flattened list of neighbouring indices (previous level).

  • num_neigh_list : number of neighbours used for each subset.

  • max_num_neigh : maximum neighbours assigned per subset (default: 4).

  • level : multi-window level index (0 = coarsest / largest window).

  • layout : subset grid definition (coords, mask, sizes, steps).

Note

The constructor builds the grid and optionally generates neighbour lists if a pointer to prev_layout is provided.

Warning

The pointer img_roi must remain valid during grid construction.

Public Functions

WindowLevel() = default
inline WindowLevel(const bool *img_roi, const int step, const int template_size, const int search_area, const int px_hori, const int px_vert, const bool allow_outside, const size_t level, const bool fft_filter, const double fft_filter_threshold, const int fft_filter_radius, const double fft_filter_corr_power, const bool fft_save, const common_util::SaveConfig &saveconf, const subset::Grid *prev_layout)
void gen_neighlist(const subset::Grid &layout_prev)

Generate nearest-neighbour mappings from a previous level’s grid.

For each subset in the current level’s layout, finds up to max_num_neigh nearest valid subsets from layout_prev within a fixed search window (roughly 10x10 cells in the previous level’s grid index space). Stores the neighbour count in num_neigh_list[ss] and neighbour indices in the flattened neigh_list buffer at positions [ss*max_num_neigh + k].

This method uses OpenMP for parallelization over current subsets.

Threading

Uses #pragma omp parallel for over subsets; writes to disjoint regions of num_neigh_list and neigh_list, making it thread-safe for the given buffers.

Note

If no neighbours are found for a subset (rare with a sensible ROI and step), the function prints diagnostics to stderr and terminates the process with EXIT_FAILURE.

Note

Uses std::nth_element to select the closest K neighbours (by squared distance).

Note

Neighbour validity is determined via layout_prev.mask (value -1 indicates invalid).

Parameters:

layout_prev[in] Previous level grid layout used as the source of neighbours.

Pre:

layout and layout_prev must be initialized.

Pre:

max_num_neigh > 0.

Post:

num_neigh_list is resized to layout.num and filled.

Post:

neigh_list is resized to max_num_neigh * layout.num and filled for found neighbours.

void calc_rigid_displacements(const WindowLevel &prev, const Interpolator &interp_ref, const Interpolator &interp_def, const int img_num_ref, const int img_num_def, const int window_level, const int num_levels, const std::vector<std::string> &filenames, const util::FFTPrecision fft_precision)

Compute rigid (translation-only) displacements at this level using FFT-CC.

For every valid subset in the current level’s layout, this method:

  1. Seeds an initial guess from the previous level via weighted neighbours (if available).

  2. Extracts the reference subset from img_ref.

  3. Samples the deformed subset from interp_def at subpixel-shifted coordinates.

  4. Zero-normalizes both subsets (ZNSSD).

  5. Performs FFT-based cross-correlation and 2D Gaussian subpixel peak estimation.

  6. Stores u, v (accumulated with the seed) and the peak amplitude (max_val).

OpenMP is used to parallelize over subsets. Each thread owns a local FFT instance. Optionally applies a MAD-based outlier removal at the end if the level is configured to do so.

Threading

Uses #pragma omp parallel with a private FFT instance per thread and a dynamic schedule. Writes to disjoint indices of u, v, max_val, making it thread-safe.

Note

Currently forces subpixel refinement to true (TODO flag in code).

Note

Uses Gaussian 2D peak estimation in frequency-domain correlation surface.

Note

Progress reporting depends on g_debug_level and may incur minor overhead.

Parameters:
  • prev[in] Previous level (for seeding); may be ignored if this is the first level.

  • img_ref[in] Pointer to reference image pixel buffer.

  • img_def[in] Pointer to deformed image pixel buffer (not directly sampled if using interp_def).

  • interp_def[in] Interpolator providing subpixel access to the deformed image.

  • img_num_ref[in] Index of the reference image in filenames (for diagnostics/progress text).

  • img_num_def[in] Index of the deformed image in filenames (for diagnostics/progress text).

  • filenames[in] Filenames vector used for progress-bar labeling.

Pre:

layout, u, v, and max_val must be sized to layout.num.

Pre:

interp_def must be valid and thread-safe for concurrent sampling (or internally synchronized).

Post:

u and v contain the estimated translations per subset for this level; max_val stores peak amplitudes.

void get_displacement_from_prev_window(double &prev_x, double &prev_y, const WindowLevel &prev, const int ss, const double ss_x, const double ss_y)

Seed current-level displacement from previous level using inverse-distance weighting.

Computes a weighted average of the prev level’s displacements for the nearest neighbours associated with the current subset ss. The weight is defined as w = 1 / (dist^2 + epsilon), where dist is the Euclidean distance between current subset center (ss_x, ss_y) and the neighbour’s center.

Note

Uses a small epsilon (10.0) to avoid singularity and to bound weights.

Note

Assumes prev.u and prev.v contain already computed displacements at the previous level.

Parameters:
  • prev_x[out] Output seed for x-displacement at the current subset.

  • prev_y[out] Output seed for y-displacement at the current subset.

  • prev[in] Previous window level providing neighbour mappings and displacements.

  • ss[in] Index of current subset (into this level’s layout).

  • ss_x[in] X-coordinate (pixels) of the current subset center or top-left (consistent with layout).

  • ss_y[in] Y-coordinate (pixels) of the current subset center or top-left (consistent with layout).

Pre:

Neighbour lists for the current level were generated against prev (via gen_neighlist).

Pre:

For ss, prev.num_neigh_list[ss] > 0 and the indices in prev.neigh_list are valid.

Post:

prev_x and prev_y contain the weighted average seed displacement for the current subset.

void remove_outliers_vector(std::vector<double> &u, std::vector<double> &v, const std::vector<double> &max_val, double threshold = 3.0, int radius = 3, double corr_power = 2.0, double eps = 1e-6)

Public Members

std::vector<double> u
std::vector<double> v
std::vector<double> cost
std::vector<double> max_val
std::vector<int> neigh_list
std::vector<int> num_neigh_list
size_t max_num_neigh = 4
size_t level
subset::Grid layout
bool fft_filter
double fft_filter_threshold
int fft_filter_radius
double fft_filter_corr_power
bool fft_save
common_util::SaveConfig saveconf
int step
int template_size
int search_area