Usage
blurdetector <PATH>... [OPTIONS]
Inputs can be files, directories, or a mix. Directories are scanned for supported files; --recursive descends into subdirectories. The resulting list is deduplicated and sorted, so a path given twice is analyzed once and the report order is stable. Nonexistent paths print a warning on stderr and are skipped; if nothing is left to analyze, the program exits with code 1.
Options
| Option | Default | Effect |
|---|---|---|
--threshold <SCORE> | 100 | Verdict cut-off: a photo is sharp when its sharpness score reaches this value |
--grid-size <N> | 6 | The image is analyzed on an N×N grid of tiles |
--top-fraction <F> | 0.10 | Fraction of the best tiles averaged into the sharpness score |
--pre-blur <SIGMA> | 0 (off) | Gaussian filter applied before the Laplacian, to tame sensor noise |
--long-edge <PIXELS> | 1600 | Images are downscaled to this long edge before scoring |
--jobs <N> | one per CPU core | Number of files analyzed in parallel |
--csv <FILE> | — | Also write the report to FILE as CSV |
--move-blurry-to <DIR> | — | Move blurry photos to DIR (created if missing) |
--move-sharp-to <DIR> | — | Move sharp photos to DIR (created if missing) |
--recursive | off | Recurse into subdirectories |
--sort | off | Print results from blurriest to sharpest |
--timing | off | Print cumulative per-stage CPU timings after the report |
The analysis options (--threshold, --grid-size, --top-fraction, --pre-blur, --long-edge) all change the score scale or its meaning — see Calibration before touching them.
Examples
# Score a directory, blurriest photos first
blurdetector photos --sort
# Whole photo tree, results exported to CSV
blurdetector photos --recursive --csv report.csv
# Quarantine the rejects
blurdetector photos --move-blurry-to rejects
# Stricter verdicts plus light denoising for high-ISO shots
blurdetector photos --threshold 150 --pre-blur 0.8
# From a source checkout
cargo run --release -- photos --sort
Moving files
--move-blurry-to and --move-sharp-to sort the analyzed photos into directories after the report is printed. Both can be used in the same run. The destination directory (and its parents) is created if missing. Each file is moved with a plain rename first, falling back to copy-then-delete when the destination is on another file system.
error rows are never moved: a file the tool could not score stays where it is. A file that cannot be moved (already deleted, permission denied, …) prints a warning and the rest of the batch continues; only a destination directory that cannot be created aborts the move and turns the exit code into 1.
Parallelism
Files are analyzed concurrently on the rayon thread pool, one file per task. By default the pool has one thread per processor core; --jobs N caps it, which is useful to keep the machine responsive during a big batch or to benchmark single-thread performance. If the pool cannot be configured the run continues on the default pool after a warning.
Timing
--timing appends a per-stage breakdown (decode, grayscale, resize, gaussian, score) after the report. The values are CPU totals summed over all worker threads, so they measure the compute cost of each stage independently of the wall clock — see Performance.