This work is dedicated to the public domain under CC0 1.0 Universal.
English | 日本語
TransientTracker is a Proof of Concept (PoC) for detecting and tracking moving-object candidates in a time series of astronomical images taken of the same field of view.
This is a PoC created to learn xtensor.
https://github.com/xtensor-stack/xtensor
This repository is a PoC and has not been tested on real astronomical photographs.
It currently consists of the following two commands.
transient_tracker_generateGenerates a synthetic dataset as a substitute for real astronomical images.transient_tracker_analyzeAnalyzes a generated dataset and extracts tracks.
The analyzer processes data roughly in the following flow.
- Loads the sequence of frame images.
- Estimates the inter-frame positional shift and registers (aligns) the frames.
- Builds a reference image and residual images.
- Extracts candidate points from the residual.
- Links candidate points across frames to form tracks.
- Outputs track CSV, summary JSON, and visualization images.
The current scenario is the single Scenario S-01.
Scenario S-01: a PoC scenario that places 20 moving objects randomly from a seed.
The initial position, velocity, and flux of each moving object are generated deterministically from --seed. There is no upper limit on the number of detections in the analyzer.
The analyzer automatically switches between two modes depending on whether ground truth is available.
- Observation mode: when
labels.csvis absent. Outputssummary.json,tracks.csv, etc., and does not perform ground-truth matching (evaluation.json). - Evaluation mode: when
labels.csvis present. In addition to the observation-mode outputs, it generatesevaluation.json.
The output data are summarized below (see How to read the outputs for details).
summary.json: Overview of the whole analysis. Aggregates key metrics such as the number of detected tracks and high-confidence accepted tracks.tracks.csv: List of detected tracks. Records per-track score, fit error, autonomous accept/reject result, and so on.evaluation.json: Ground-truth matching results (evaluation mode only). Records the correspondence between detected tracks and ground-truth objects.
- OS: macOS (developed and verified with Apple Clang)
- Compiler: Apple Clang (C++20 capable)
- CMake 3.16 or later
- OpenCV
- xtensor
Compilers other than those on macOS (e.g., g++) have not been verified.
Example installation with Homebrew:
brew install cmake opencv xtensorRun the following at the project root.
cd /Users/mitsuruk/devs/@GitHub/@Project/TransientTracker
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
ctest --test-dir build --output-on-failureExample of generating S-01.
./build/transient_tracker_generate \
--scenario S-01 \
--output ./output/S-01 \
--seed 20260608 \
--write-all-previewMain arguments:
--scenario <name>--output <dir>--seed <value>--width <value>--height <value>--num-frames <value>--num-stars <value>--write-all-preview
./build/transient_tracker_analyze \
--dataset ./output/S-01 \
--output ./analysis/S-01 \
--threshold-scale 3.5 \
--tolerance-radius 1 \
--area-min 1 \
--area-max 64 \
--max-velocity 3.0 \
--min-track-length 3 \
--fit-error-threshold 1.5 \
--min-continuity-ratio 0.6 \
--duplicate-merge-distance 1.5 \
--truth-match-distance 2.0 \
--write-debug-imagesMain arguments:
--dataset <dir>--output <dir>--tolerance-radius <value>--threshold-scale <value>--area-min <value>--area-max <value>--max-velocity <value>--min-track-length <value>--fit-error-threshold <value>(upper bound of the line-fit error for high-confidence acceptance)--min-continuity-ratio <value>(lower bound of the frame continuity ratio for high-confidence acceptance)--duplicate-merge-distance <value>(distance threshold for merging duplicate tracks)--truth-match-distance <value>(evaluation mode only)--write-debug-images--disable-registration
TransientTracker/
├── apps/
├── build/
├── design-docs/
├── include/
├── output/
├── src/
└── tests/
Example of a generated dataset:
output/S-01/
├── frames/
├── labels.csv
├── metadata.json
└── preview/
Example of analysis output:
analysis/S-01/
├── detections.csv
├── evaluation.json (evaluation mode only)
├── summary.json
├── tracks.csv
├── results/
└── debug/
Basic information about the whole dataset. Check the following first.
scenario_namenum_framesnum_objectsseed
The ground truth of the synthetic data. Mainly check the following.
frame_indexobject_idobject_xobject_yobject_visible
Preview images for visual inspection. Used to confirm the synthesized moving-object positions.
A summary of the whole analysis. Mainly check the following.
num_detected_tracks(number of detected tracks)num_high_confidence_tracks(number of accepted high-confidence tracks; the primary metric in observation mode)has_truth(true in evaluation mode)num_matched_objects(valid in evaluation mode only)status
A list of detected tracks. Mainly check the following.
track_idframe_indextrack_scorefit_erroris_high_confidence(result of autonomous acceptance)matched_object_id(valid in evaluation mode only)
Ground-truth matching results, generated only in evaluation mode (with labels.csv). Mainly check the following.
num_visible_objectsnum_matched_tracksnum_matched_objectsmatched_objects
A summary image with detected tracks overlaid on the first star field. A good image to look at first.
Result images with tracks overlaid on each frame. Lets you check the tracking status per frame.
Intermediate products. The following images let you isolate each processing step.
reference/the reference imagealigned/the registered (aligned) framesresidual/the residual imagesmask/the candidate-extraction masksoverlay/the candidate overlay images
Using the images in analysis/S-01/ (generated with --write-debug-images), two images are shown for each processing step. This is an example with seed 20260608, 1024x1024, 16 frames. The appearance changes with the seed and resolution.
The "static background" reference, built from the per-frame median with a max-envelope of a tolerance radius applied. Only stationary stars whose positions do not change across frames remain; moving objects are removed (by nature of this step, only one image).
Each frame after cancelling the translational shift estimated by phase correlation, so the stationary-star positions are aligned. After registration, the stars overlap on the same pixels.
The difference of each aligned frame minus the reference image. Stationary stars cancel out and almost disappear, leaving only the moving objects—absent from the reference—as bright points (stationary-star positions remain as faint dark dots due to small subtraction residuals).
A binary mask in which pixels exceeding the threshold (threshold_scale times the noise sigma estimated from the residual via MAD, Median Absolute Deviation) are set to white. It shows the positions of candidate pixels.
Connected components extracted from the mask as candidate points, overlaid as circles on the aligned frame. Lets you confirm where moving-object candidates were detected in each frame.
Tracks formed by linking candidates across frames, drawn on each frame. In the first frame (0000) each object starts as a point; by the last frame (0015) the track extends as a line. Labels read "obj (truth ID) / track (track ID)".
A summary image overlaying all 20 accepted object tracks—with start and end markers—on the first star field. The overall analysis flow is as follows.
- Load frames and normalize by the median.
- Estimate translational shift by phase correlation → register (
aligned). - Build the reference image with the median + max-envelope (
reference). - Aligned frame − reference = residual (
residual). - Estimate noise via MAD → threshold mask (
mask). - Extract candidates from the mask (
overlay). - Link candidates across frames → form tracks.
- Accept high-confidence tracks by track length, line-fit error, and frame continuity ratio, then merge duplicate tracks.
- Draw the accepted tracks →
trajectory_result.png.
All 20 moving objects are detected and drawn as individual tracks.
When you analyze Scenario S-01, looking at the following first makes it easier to grasp the overall picture.
output/S-01/metadata.jsonanalysis/S-01/summary.jsonanalysis/S-01/evaluation.json(evaluation mode only)analysis/S-01/results/trajectory_result.png
- The generator is a program for creating PoC datasets with ground truth.
- The analyzer supports ground-truth-independent autonomous track detection (observation mode). When ground truth is available, it also generates
evaluation.jsonin evaluation mode. - There is no upper limit on the number of detected moving objects. In Scenario S-01, 20 objects are placed randomly from a seed, and all 20 are confirmed to be recognized at the default size (1024x1024, 16 frames).