Module Reference¶
Analysis¶
- class flametrack.analysis.flamespread.EdgeMethodSpec(short_id: str, display_name: str, description: str, make_fn: Callable[[float], EdgeFn], default_threshold_ir: float, default_threshold_image: float, use_otsu_masking: bool = True)[source]¶
Bases:
objectDescriptor for a named edge-detection method variant.
- default_threshold_image: float¶
- default_threshold_ir: float¶
- description: str¶
- display_name: str¶
- short_id: str¶
- use_otsu_masking: bool = True¶
- flametrack.analysis.flamespread.band_filter(frame: ndarray, low: float | None = None, high: float | None = None) ndarray[source]¶
Clip intensity values between low and high threshold.
- Parameters:
frame (np.ndarray) – Input image.
low (float) – Lower clipping limit.
high (float) – Upper clipping limit.
- Returns:
Filtered image.
- Return type:
np.ndarray
- flametrack.analysis.flamespread.calculate_edge_data(data: ~numpy.ndarray, find_edge_point: ~flametrack.analysis.flamespread.EdgeFn, custom_filter: ~collections.abc.Callable[[~numpy.ndarray], ~numpy.ndarray] = <function <lambda>>, use_otsu_masking: bool = True) list[list[int]][source]¶
Calculates the edge position for each row of each frame.
- Parameters:
data (np.ndarray) – 3D array of shape (H, W, T).
find_edge_point (Callable) – Method to find edge in 1D data.
custom_filter (Callable) – Optional filter to apply to each frame.
use_otsu_masking (bool) – If True (default), apply Otsu thresholding and morphological dilation to restrict the per-row search window. Set False to scan the full row without any masking (useful when a fixed intensity threshold alone is sufficient and Otsu would over-shrink the window, e.g. with a deliberately low threshold such as 117).
- Returns:
Edge coordinates per frame.
- Return type:
list[list[int]]
- flametrack.analysis.flamespread.calculate_edge_results_for_exp_name(exp_name: str, left: bool = False, dewarped_data: ndarray | None = None, save: bool = True) ndarray | None[source]¶
Run full edge detection pipeline for a given experiment name.
- Parameters:
exp_name (str) – Experiment identifier.
left (bool) – Whether to process left side.
dewarped_data (np.ndarray) – Optional preloaded data.
save (bool) – Whether to write result to HDF5.
- Returns:
Edge data (if save=False).
- Return type:
np.ndarray
- flametrack.analysis.flamespread.find_peaks_in_gradient(y: ndarray, min_distance: int = 10, min_height: float = 2, min_width: int = 2) ndarray[source]¶
Find peaks in the negative gradient of a 1D signal.
- Parameters:
y (np.ndarray) – 1D signal.
min_distance (int) – Minimum distance between peaks.
min_height (float) – Minimum peak height.
min_width (float) – Minimum peak width.
- Returns:
Indices of detected peaks.
- Return type:
np.ndarray
- flametrack.analysis.flamespread.highest_peak(y: ndarray, min_distance: int = 10, min_height: float = 2, min_width: int = 2) int[source]¶
Return the index of the peak with the highest gradient.
- Returns:
Index of the highest peak, or 0.
- Return type:
int
- flametrack.analysis.flamespread.highest_peak_to_lowest_value(y: ndarray, min_distance: int = 10, min_height: float = 2, min_width: int = 2, ambient_weighting: float = 2, high_val: float = 0, low_val: float = 10000000000.0, direction_weighting: float = 0.0, previous_peak: int | None = None, previous_velocity: float = 0) int[source]¶
Find the most plausible flame front peak using gradient + ambient suppression + direction.
- Returns:
Index of selected edge point.
- Return type:
int
- flametrack.analysis.flamespread.left_edge_of_rightmost_cluster(y: ndarray, threshold: float = 128, params: dict | None = None) int[source]¶
Find the leftmost pixel of the rightmost contiguous cluster above threshold.
This is the correct edge function for a flame spreading right-to-left in image/video data (0–255 range). Unlike
left_most_point_over_threshold, it ignores isolated bright artefacts (reflections, glare) that are not part of the main hot region.- Algorithm:
Find the rightmost pixel above threshold.
Walk left while still above threshold.
Return the index one step past the last hot pixel (= leftmost edge).
Returns
len(y)when no pixel exceeds the threshold.
- flametrack.analysis.flamespread.left_most_point_over_threshold(y: ndarray, threshold: float = 0, params: dict | None = None) int[source]¶
Find the first point in the signal above the given threshold.
- Parameters:
y (np.ndarray) – 1D signal.
threshold (float) – Threshold value.
params – Unused; kept for compatibility.
- Returns:
Index of the first point above threshold, or len(y).
- Return type:
int
- flametrack.analysis.flamespread.plot_edge(frame: ~numpy.ndarray, find_edge_point: ~collections.abc.Callable[[~numpy.ndarray], int] = <function right_most_peak>) None[source]¶
Plot detected edge for each line in the frame.
- Parameters:
frame (np.ndarray) – 2D thermal frame.
find_edge_point (Callable) – Edge detection function.
- flametrack.analysis.flamespread.right_edge_of_leftmost_cluster(y: ndarray, threshold: float = 128, params: dict | None = None) int[source]¶
Find the rightmost pixel of the leftmost contiguous cluster above threshold.
Mirror of
left_edge_of_rightmost_clusterfor flames spreading left-to-right.Returns 0 when no pixel exceeds the threshold.
- flametrack.analysis.flamespread.right_most_peak(y: ndarray, min_distance: int = 10, min_height: float = 2, min_width: int = 2) int[source]¶
Return the right-most peak in the gradient of the signal.
- Returns:
Index of last detected peak, or 0.
- Return type:
int
- flametrack.analysis.flamespread.right_most_point_over_threshold(y: ndarray, threshold: float = 0, params: dict | None = None) int[source]¶
Find the last point in the signal above the given threshold.
- Parameters:
y (np.ndarray) – 1D signal.
threshold (float) – Threshold value.
params – Unused; kept for compatibility.
- Returns:
Index of the last point above threshold, or 0.
- Return type:
int
- flametrack.analysis.flamespread.show_flame_contour(data: ndarray, edge_results: ndarray, frame: int) tuple[Figure, Axes][source]¶
Overlay detected edge on thermal image for a given frame.
- Parameters:
data (np.ndarray) – 3D image data.
edge_results (np.ndarray) – Edge matrix.
frame (int) – Frame index.
- Returns:
Matplotlib figure and axis.
- Return type:
fig, ax
- flametrack.analysis.flamespread.show_flame_spread(edge_results: ndarray, y_coord: int) tuple[Figure, Axes][source]¶
Plot flame front x-coordinate over time at a given y-line.
- Parameters:
edge_results (np.ndarray) – Edge matrix.
y_coord (int) – Line index from bottom.
- Returns:
Matplotlib figure and axis.
- Return type:
fig, ax
- flametrack.analysis.flamespread.show_flame_spread_velocity(edge_results: ndarray, y_coord: int, rolling_window: int = 3) tuple[Figure, Axes][source]¶
Plot local velocity of flame front at a fixed y-line.
- Parameters:
edge_results (np.ndarray) – Edge data.
y_coord (int) – Line index.
rolling_window (int) – Smoothing window size.
- Returns:
Matplotlib figure and axis.
- Return type:
fig, ax
- flametrack.analysis.dataset_handler.assert_h5_schema(h5: File, experiment_type: str) None[source]¶
Verifiziere, dass die nötigen Gruppen existieren. Praktisch für frühe, klare Fehlermeldungen.
- flametrack.analysis.dataset_handler.close_file() None[source]¶
Close the currently opened HDF5 file, if any.
- flametrack.analysis.dataset_handler.create_h5_file(exp_name: str | None = None, filename: str | None = None) File[source]¶
Create a new HDF5 file. Diese Funktion erzeugt KEINE experiment-spezifischen Gruppen.
- flametrack.analysis.dataset_handler.get_data(exp_name: str, group_name: str, left: bool = False) Dataset[source]¶
Retrieve dataset for given experiment and group.
- Parameters:
exp_name – Experiment name.
group_name – Group name in HDF5 file (‘dewarped_data’ or ‘edge_results’).
left – Use left variant if True.
- Returns:
Dataset object.
- Return type:
h5py.Dataset
- flametrack.analysis.dataset_handler.get_dewarped_data(exp_name: str, left: bool = False) Dataset[source]¶
Get dewarped data dataset from the experiment file.
- flametrack.analysis.dataset_handler.get_dewarped_metadata(exp_name: str, left: bool = False) dict[source]¶
Get metadata attributes from dewarped_data group.
- flametrack.analysis.dataset_handler.get_edge_results(exp_name: str, left: bool = False) Dataset[source]¶
Get edge results dataset from the experiment file.
- flametrack.analysis.dataset_handler.get_file(exp_name: str, mode: Literal['r', 'a'] = 'r', left: bool = False) File[source]¶
Open or reuse HDF5 file for the experiment.
- flametrack.analysis.dataset_handler.get_h5_file_path(exp_name: str, left: bool = False) str[source]¶
- flametrack.analysis.dataset_handler.init_h5_for_experiment(h5: File, experiment_type: str) None[source]¶
Lege die nötigen Gruppen je Experimenttyp an. Kann z. B. direkt nach create_h5_file(…) aufgerufen werden.
- flametrack.analysis.dataset_handler.save_edge_results(exp_name: str, edge_results: ndarray[tuple[int, ...], dtype[floating]] | ndarray[tuple[int, ...], dtype[integer]], left: bool = False) None[source]¶
Save edge results array to the experiment’s HDF5 file.
Opens a fresh file handle just for this write (no global handle usage).
- flametrack.analysis.ir_analysis.compute_remap_from_homography(homography: ndarray[tuple[int, ...], dtype[float32]] | ndarray[tuple[int, ...], dtype[float64]], width: int, height: int) tuple[ndarray[tuple[int, ...], dtype[float32]], ndarray[tuple[int, ...], dtype[float32]]][source]¶
Compute pixelwise remap grids from a homography.
- Parameters:
homography (numpy.ndarray) – 3×3 homography mapping output → input coordinates.
width (int) – Target image width in pixels.
height (int) – Target image height in pixels.
- Returns:
Two arrays
(src_x, src_y)with shape(height, width), dtypefloat32suitable forcv2.remap.- Return type:
tuple[numpy.ndarray, numpy.ndarray]
- flametrack.analysis.ir_analysis.get_dewarp_parameters(corners: ndarray[tuple[int, ...], dtype[float32]] | Sequence[tuple[float, float]], target_pixels_width: int | None = None, target_pixels_height: int | None = None, target_ratio: float | None = None, *, plate_width_m: float | None = None, plate_height_m: float | None = None, pixels_per_millimeter: int = 1) dict[str, Any][source]¶
Calculate homography and target geometry for dewarping.
You can either pass physical plate dimensions (
plate_width_m,plate_height_m) plus a pixel density, or infer target geometry from the selected corners and a desired aspect ratio.- Parameters:
corners (numpy.ndarray | Sequence[tuple[float, float]]) – Four corner points in pixel coordinates, ordered clockwise starting at top-left.
target_pixels_width (int, optional) – Target width in pixels. If omitted, it will be derived from
target_ratioand the measured corner distances.target_pixels_height (int, optional) – Target height in pixels. If omitted, it will be derived from
target_ratioand the measured corner distances.target_ratio (float, optional) – Desired aspect ratio
height / width. Required if target size is not specified and no physical plate size is provided.plate_width_m (float, optional) – Physical plate width in meters. Used with
pixels_per_millimeterto derive target size if provided withplate_height_m.plate_height_m (float, optional) – Physical plate height in meters. Used with
pixels_per_millimeterto derive target size if provided withplate_width_m.pixels_per_millimeter (int, optional) – Pixel density (px/mm) used when physical dimensions are given. Default is 1.
- Returns:
- Dictionary with:
transformation_matrix(numpy.ndarray): 3×3 homography (float32).target_pixels_width(int): Target width in pixels.target_pixels_height(int): Target height in pixels.target_ratio(float):height / widthof the target.
- Return type:
dict[str, Any]
- Raises:
ValueError – If neither physical dimensions nor a target ratio are provided.
Notes
Current conversion multiplies meter values by
pixels_per_millimeter. For strict unit consistency, consider using millimeters orpixels_per_meter.
- flametrack.analysis.ir_analysis.read_ir_data(filename: str) ndarray[tuple[int, ...], dtype[float64]][source]¶
Read raw IR data from a CSV-like ASCII export.
The file is scanned until a line
[Data]is found; subsequent lines are parsed using;as delimiter and a comma-to-dot decimal replacement.- Parameters:
filename (str) – Path to the IR data file.
- Returns:
2D array of IR values (dtype
float64).- Return type:
numpy.ndarray
- Raises:
ValueError – If no
[Data]section is found in the file.
GUI¶
The GUI layer (flametrack.gui) is based on PySide6 and is excluded from
the API reference — Qt widget subclasses are best understood by reading the
source directly. The architecture overview is in Architecture Overview.
- flametrack.gui.plotting_utils.rotate_points(points, image_shape, rotation_index)[source]¶
Converts points from a np.rot90-rotated display frame back to unrotated image coordinates.
- Parameters:
points – Liste von (x, y)-Punkten im rotierten Bild
image_shape – Form des UNROTIERTEN Bildes als (Höhe, Breite)
rotation_index – 0 = 0°, 1 = 90° CCW, 2 = 180°, 3 = 270° CCW
- Returns:
Punkte im unrotierten Bildkoordinatensystem als Liste von (x, y)
- flametrack.gui.plotting_utils.sort_corner_points(points, experiment_type='Room Corner', direction='clockwise') list[source]¶
Sort corner points depending on experiment type. - For ‘room_corner’ (6 points): Sort using angle-based method with defined start point - For ‘lateral_flame_spread’ (4 points): Sort using center angle
Processing¶
- class flametrack.processing.dewarping.CornerSets(left: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float32]], right: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float32]])[source]¶
Bases:
object- left: ndarray[tuple[int, ...], dtype[float32]]¶
- right: ndarray[tuple[int, ...], dtype[float32]]¶
- class flametrack.processing.dewarping.DewarpConfig(target_ratio: float, target_pixels_width: int, target_pixels_height: int, plate_width_mm: float | None = None, plate_height_mm: float | None = None, rotation_index: int = 0, frequency: int = 1, testing: bool = False, filename: str | None = None, datatype: str = 'IR')[source]¶
Bases:
object- datatype: str = 'IR'¶
- filename: str | None = None¶
- frequency: int = 1¶
- plate_height_mm: float | None = None¶
- plate_width_mm: float | None = None¶
- rotation_index: int = 0¶
- target_pixels_height: int¶
- target_pixels_width: int¶
- target_ratio: float¶
- testing: bool = False¶
- flametrack.processing.dewarping.dewarp_lateral_flame_spread(experiment: Any, points: Sequence[tuple[float, float]], config: DewarpConfig) Generator[int, None, None][source]¶
Dewarp für Lateral Flame Spread (warpPerspective).
- flametrack.processing.dewarping.dewarp_room_corner_remap(experiment: Any, points: ndarray[tuple[int, ...], dtype[float32]] | Sequence[tuple[float, float]], config: DewarpConfig) Generator[int, None, None][source]¶
Dewarp für Room Corner anhand vorberechneter Remap‑Grids.
- flametrack.processing.dewarping.rotate_image_and_points(image: ndarray[tuple[int, ...], dtype[float32]] | ndarray[tuple[int, ...], dtype[uint8]], points: ndarray[tuple[int, ...], dtype[float32]], angle_degrees: float) tuple[ndarray[tuple[int, ...], dtype[float32]], ndarray[tuple[int, ...], dtype[float32]]][source]¶
Rotate both image and corresponding points.
- Parameters:
image – Input image.
points – Nx2 array of (x, y) points.
angle_degrees – Rotation angle in degrees.
- Returns:
A tuple (rotated_image, rotated_points)
Utils¶
- flametrack.utils.math_utils.estimate_resolution_from_points(p0, p1, p3, plate_width_mm, plate_height_mm, *, assumed_error_px: float = 0.5) dict[source]¶
Estimate spatial resolution and absolute measurement uncertainty based on manually marked rectangle.
- Parameters:
p0 (array-like) – Top-left point of rectangle in pixels.
p1 (array-like) – Top-right point of rectangle in pixels.
p3 (array-like) – Bottom-left point of rectangle in pixels.
plate_width_mm (float) – Real-world width of the physical plate in millimeters.
plate_height_mm (float) – Real-world height of the physical plate in millimeters.
assumed_error_px (float, optional) – Pixel accuracy assumed for manual point selection (default is ±0.5 px).
- Returns:
Dictionary with estimated resolution and error terms (all float): - mm_per_px_width - mm_per_px_height - error_mm_width - error_mm_height - assumed_pixel_error
- Return type:
dict