Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI

on:
push:
branches: [master, develop]
pull_request:

permissions:
contents: read

jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13"]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip

- name: Install FFmpeg (Ubuntu)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install --yes ffmpeg

- name: Install FFmpeg (macOS)
if: runner.os == 'macOS'
run: brew install ffmpeg

- name: Install FFmpeg (Windows)
if: runner.os == 'Windows'
run: choco install ffmpeg --yes --no-progress

- name: Install package and test dependencies
run: python -m pip install --upgrade pip && python -m pip install -r requirements.txt

- name: Run tests
run: python -m pytest -q

- name: Build wheel
run: python -m pip wheel . --no-deps --wheel-dir dist
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ All notable changes to the Sharp Frames project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.0] - 2026-07-16

### Added
- Scrollable frame timeline with keyboard navigation and full-result visualization
- Resolution-normalized focus scoring for more consistent comparisons across source sizes
- Cross-platform CI coverage for Python 3.10 through 3.13 on Linux, macOS, and Windows
- Regression coverage for selection quality, output collisions, cancellation, and runtime cleanup

### Changed
- Selection methods now balance sharpness and temporal distribution more consistently
- Frame extraction, analysis, preview, and saving pipelines provide stricter validation and failure reporting
- Image-directory exports preserve content while correctly handling format conversion and case-insensitive filename collisions
- Configuration and selection screens provide clearer controls, status, and keyboard behavior

### Fixed
- FFmpeg and FFprobe process cleanup, cancellation, timeout, and pipe handling
- Partial or failed image reads being treated as valid zero-quality frames
- Selection previews disagreeing with the frames produced during processing
- Output metadata reporting frames that were not successfully saved
- Platform-specific dependency guidance and Windows-safe process startup

## [0.3.1] - 2025-01-29

### Fixed
Expand Down Expand Up @@ -136,4 +157,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- outlier-removal: Remove outliers based on comparison with neighbors
- Interactive mode with guided prompts
- Proper Python package structure for pip and pipx installation
- Command-line interface with `sharp-frames` command
- Command-line interface with `sharp-frames` command
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ Or with pipx for isolated installation:
pipx install sharp-frames
```

**IMPORTANT: Video Processing Requirement**: Install FFmpeg separately for video input support.
**IMPORTANT: Video Processing Requirement**: Install an FFmpeg distribution that includes both `ffmpeg` and `ffprobe`. Both executables must be on `PATH`; image-directory processing does not require them.
- **Windows**: Download from [FFmpeg website](https://ffmpeg.org/download.html) and add to PATH
- **macOS**: `brew install ffmpeg`
- **Linux**: `sudo apt install ffmpeg`

HDR-to-SDR extraction additionally requires an FFmpeg build with the `zscale` filter (`libzimg`). You can verify support with `ffmpeg -filters | grep zscale`. Non-HDR video processing does not require `zscale`.

## Quick Start

### Modern Interface (Default)
Expand All @@ -45,9 +47,9 @@ sharp-frames <input> <output> [options]
```

**Input Types:**
- Video files: `.mp4`, `.avi`, `.mov`, `.mkv`, `.wmv`, `.flv`, `.webm`, `.m4v`, etc.
- Video files: `.mp4`, `.avi`, `.mov`, `.mkv`, `.wmv`, `.flv`, `.webm`, `.m4v`, `.3gp`, `.3g2`, `.ogv`, `.ts`, `.mts`, `.m2ts`, `.mpg`, `.mpeg`, `.vob`
- Video directories: Processes all videos in a folder
- Image directories: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.tiff`, `.webp`, etc.
- Image directories: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.tif`, `.tiff`, `.webp`, `.ppm`, `.pgm`, `.pbm`

## Selection Methods

Expand All @@ -63,10 +65,10 @@ Divides content into batches and selects the sharpest frame from each batch.
--selection-method batched --batch-size 5 --batch-buffer 2
```

### Outlier Removal
### Outlier Detection
Removes unusually blurry frames by comparing each frame to its neighbors.
```bash
--selection-method outlier-removal --outlier-window-size 15 --outlier-sensitivity 50
--selection-method outlier-removal --outlier-window-size 15 --outlier-sensitivity 60
```

## Command Line Options
Expand All @@ -79,11 +81,11 @@ Removes unusually blurry frames by comparing each frame to its neighbors.

### Selection Method Parameters
- `--num-frames <int>`: Number of frames to select (best-n, default: 300)
- `--min-buffer <int>`: Minimum gap between selected frames (best-n, default: 3)
- `--min-buffer <int>`: Minimum number of intervening frames between selected frames (best-n, default: 3)
- `--batch-size <int>`: Frames per batch (batched, default: 5)
- `--batch-buffer <int>`: Frames to skip between batches (batched, default: 2)
- `--outlier-window-size <int>`: Neighbor comparison window (outlier-removal, default: 15)
- `--outlier-sensitivity <int>`: Removal aggressiveness 0-100 (outlier-removal, default: 50)
- `--outlier-window-size <int>`: Local comparison window, minimum 5 (outlier-removal, default: 15)
- `--outlier-sensitivity <int>`: Detection sensitivity 0-100 (outlier-removal, default: 60)

## Examples

Expand Down Expand Up @@ -125,23 +127,27 @@ sharp-frames photos selected --selection-method outlier-removal --outlier-sensit

## Requirements

- Python 3.7 or higher
- Python 3.10 or higher
- Dependencies installed automatically: `opencv-python`, `numpy`, `tqdm`, `textual`
- FFmpeg (for video processing only)
- FFmpeg and FFprobe (for video processing only)
- FFmpeg `zscale`/`libzimg` support (for HDR-to-SDR processing only)

## How It Works

1. **Validation**: Checks input paths, file formats, and system dependencies
2. **Extraction**: Videos are extracted to frames at specified FPS using FFmpeg
3. **Analysis**: Calculates sharpness scores using Laplacian variance in parallel
4. **Selection**: Applies chosen algorithm to select the best frames/images
3. **Analysis**: Normalizes analysis resolution, lightly denoises each image,
and combines Laplacian variance with Tenengrad focus scoring in parallel.
Unreadable inputs are excluded and reported.
4. **Selection**: Applies the chosen source-aware algorithm to select the best
naturally ordered frames/images.
5. **Output**: Saves selected content with metadata including scores and parameters

## Output

- Selected frames/images with descriptive filenames
- `selected_metadata.json` with processing details, parameters, and sharpness scores
- Preserves original formats for image directory input
- Transcodes selected images to the configured output format (`jpg` by default)
- Automatic output directory creation with permission validation

## Help & Support
Expand Down
55 changes: 16 additions & 39 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,30 @@
# Sharp Frames v0.2.0 Release Notes
# Sharp Frames v0.4.0 Release Notes

## New Features
## Highlights

### Textual Interface (Default)
- Replaces command-line prompts with step-by-step wizard
- Real-time input validation and error feedback
- Enhanced error messages with specific guidance
- Explore the complete analyzed frame set in a scrollable timeline with keyboard navigation.
- Get more reliable selections from resolution-normalized focus scoring and improved temporal distribution.
- Preview and execution now share the same selection rules, so displayed counts and chosen frames agree.

### Video Directory Processing
- Process all videos in a folder with a single command
- Automatically detects and processes supported video formats
- Maintains individual processing settings for each video
## Reliability and Compatibility

### Usage Changes
```bash
# New default behavior
sharp-frames # Launches textual interface

# Existing functionality unchanged
sharp-frames input.mp4 output/ # Direct processing
sharp-frames video_folder/ output/ # Process all videos in folder
sharp-frames --interactive # Legacy prompts
```

## Technical Changes
- Hardened FFmpeg and FFprobe cancellation, timeouts, output draining, and temporary-directory cleanup.
- Unreadable images are excluded and reported instead of silently receiving valid-looking scores.
- Image exports handle format conversion, partial failures, metadata accuracy, and case-insensitive filename collisions.
- CI covers Linux, macOS, and Windows on Python 3.10, 3.11, 3.12, and 3.13.

### Added
- Path validation with existence/permission checking
- Numeric field validation with range checking
- Thread-safe subprocess management
- UI component testing
- Enhanced error analysis and reporting
## Interface Improvements

### Fixed
- Configuration parameter mapping
- Resource cleanup (temp files, subprocesses)
- Error message specificity
- Clearer configuration controls and validation feedback.
- Improved selection chart contrast, spacing, scrolling, and keyboard controls.
- More actionable dependency and processing errors across supported platforms.

## Breaking Changes
- `sharp-frames` without arguments now launches UI instead of showing help
- Use `sharp-frames --help` for command-line help
## Upgrade

## Installation
```bash
pip install --upgrade sharp-frames
# or
pipx upgrade sharp-frames
```

## Dependencies
- Added: `textual>=0.41.0`
- All existing dependencies unchanged
FFmpeg and FFprobe remain required for video processing and must be available on `PATH`.
Loading
Loading