Skip to content

Commit df6936b

Browse files
committed
Add parameter definitions for centroid-detection algorithms
Introduce `params.py` under `source/core/` to centralize algorithm parameter configurations (SLIC, Felzenszwalb, Quickshift, FBM, CCL, and Bessel). Implement frozen dataclasses to ensure immutability and reusability across datasets and algorithms.
1 parent 441b1d1 commit df6936b

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

source/core/params.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""Algorithm parameters for the centroid-detection methods.
2+
3+
Frozen dataclasses so the call sites can pass a single value object instead
4+
of a long, easy-to-mismatch keyword list, and so per-dataset configurations
5+
can be defined once and reused across algorithms.
6+
7+
All defaults below are the fine-tuned values from the pre-refactor code at
8+
commit ``ab17d7b`` (the laser-spot dataset under ``images/``). When changing
9+
any default, also update the regression range in ``tests/test_smoke.py``.
10+
11+
Notes on the Gaussian-blur sigmas (FBM + Bessel)
12+
------------------------------------------------
13+
The original code called ``cv2.GaussianBlur(img, (5, 5), 0)`` which lets
14+
OpenCV auto-compute sigma from the kernel size:
15+
16+
sigma = 0.3 * ((ksize - 1) * 0.5 - 1) + 0.8
17+
= 0.3 * 1 + 0.8 = 1.1 for ksize = 5
18+
19+
We now go through :func:`source.core.gpu_utils.gaussian_blur` (which uses
20+
``scipy.ndimage.gaussian_filter`` on CPU and ``cupyx.scipy.ndimage`` on GPU),
21+
so sigma is passed explicitly. ``blur_sigma = 1.1`` preserves the original
22+
smoothing strength.
23+
"""
24+
from __future__ import annotations
25+
26+
from dataclasses import dataclass
27+
28+
29+
@dataclass(frozen=True)
30+
class SLICParams:
31+
n_segments: int = 125
32+
compactness: float = 10.0
33+
sigma: float = 5.0
34+
35+
36+
@dataclass(frozen=True)
37+
class FelzenszwalbParams:
38+
scale: float = 200.0
39+
sigma: float = 0.5
40+
min_size: int = 150
41+
42+
43+
@dataclass(frozen=True)
44+
class QuickshiftParams:
45+
kernel_size: int = 21
46+
max_dist: float = 50.0
47+
ratio: float = 5.0
48+
49+
50+
@dataclass(frozen=True)
51+
class FBMParams:
52+
"""OpenCV-moments centroid: blur, threshold, morph close."""
53+
blur_sigma: float = 1.1 # matches cv2.GaussianBlur(_, (5, 5), 0) default
54+
threshold: int = 100
55+
threshold_max: int = 255 # uint8 binary mask ceiling
56+
morph_kernel: int = 5
57+
58+
59+
@dataclass(frozen=True)
60+
class CCLParams:
61+
"""scikit-image connected-components centroid."""
62+
blur_sigma: float = 2.0
63+
morph_disk: int = 5
64+
65+
66+
@dataclass(frozen=True)
67+
class BesselParams:
68+
"""Airy-disk (Bessel) fit.
69+
70+
``window_size`` is the half-width of the ROI extracted around the
71+
initial peak guess. ``initial_blur_sigma`` smooths the image before
72+
locating that peak. The ``fit_*`` fields seed ``scipy.optimize.curve_fit``:
73+
74+
p0 = [A0, x0_init, y0_init, fit_sigma_init, offset_init]
75+
bounds = [[0, x_min, y_min, fit_sigma_min, 0 ],
76+
[inf, x_max, y_max, inf, offset_max ]]
77+
"""
78+
window_size: int = 80 # half-width of the ROI around the peak
79+
initial_blur_sigma: float = 1.1 # matches cv2.GaussianBlur(_, (5, 5), 0)
80+
fit_sigma_init: float = 5.0 # initial guess for the Airy sigma
81+
fit_sigma_min: float = 0.1 # lower bound for the Airy sigma
82+
fit_offset_max: float = 1.0 # upper bound for the background offset

0 commit comments

Comments
 (0)