Automated video chapter generation using template matching and OCR
Project description
โพ Loups
Automated video chapter generation using template matching and OCR
Automatically scan any video with on-screen text overlays to extract information and generate timestamped YouTube chapters! ๐ฅโจ
Originally designed for Lights Out HB fastpitch softball games, but works with any video content that has consistent identifying frames or text overlays.
โจ What is Loups?
Loups uses template matching and OCR to automatically scan videos, detect specific frames with identifying information, and generate timestamped chapters.
Use cases include:
- ๐ฅ Sports Games - Track player at-bats, shifts, or appearances (originally designed for fastpitch softball)
- ๐ Educational Content - Chapter markers for different topics or speakers
- ๐๏ธ Podcasts/Interviews - Detect guest name overlays or topic cards
- ๐ฎ Gaming - Mark level changes, character selections, or game modes
- ๐บ TV Shows/Series - Detect episode titles or scene markers
- ๐ฌ Any Video - With consistent text overlays or identifying frames
๐ฆ Installation
Coming soon to PyPI! For now, install from source:
pip install loups
๐ Quick Start
# ๐ฌ For Lights Out HB games (uses bundled template)
loups game_video.mp4
# ๐จ For any other video (use your own template)
loups -t my_template.png video.mp4
# ๐พ Save results to a file for YouTube chapters
loups -o chapters.txt video.mp4
# ๐คซ Quiet mode for automation/batch processing
loups -q -o chapters.txt video.mp4
Important: Options must be specified before the video argument.
๐ผ๏ธ Thumbnail Extraction
Loups can automatically extract thumbnails from your videos using SSIM (Structural Similarity Index) matching!
# Extract thumbnail using default template
loups video.mp4 thumbnail
# Use custom thumbnail template
loups video.mp4 thumbnail --thumbnail-template my_thumb_template.png
# Customize output location
loups video.mp4 thumbnail --thumbnail-output ./thumbnails/game_thumb.jpg
# Fine-tune the matching
loups video.mp4 thumbnail --thumbnail-threshold 0.85 --thumbnail-scan-duration 180
# Extract thumbnail during chapter scanning (options BEFORE video)
loups --extract-thumbnail --thumbnail-output thumb.jpg video.mp4
How Thumbnail Extraction Works
- ๐ฏ Template Matching - Scans video frames from the beginning using SSIM scoring
- โก First-Match Strategy - Stops as soon as a frame exceeds the similarity threshold
- ๐พ Automatic Saving - Saves the matched frame as a JPEG thumbnail
- โฑ๏ธ Configurable Duration - Only scans the first N seconds (default: 120s)
Key Features:
- ๐ฏ SSIM-based matching - More accurate than simple template matching
- โก Efficient scanning - Stops at first match, doesn't scan entire video
- ๐จ Default template support - Include
thumbnail_template.pngin package data - ๐ง Highly configurable - Control threshold, scan duration, and frame sampling
Options:
--thumbnail-template- Path to template image (uses default if not specified)--thumbnail-output- Where to save thumbnail (default:<video>-thumbnail.jpgin current directory)--thumbnail-threshold- Minimum SSIM score (0.0-1.0, default: 0.35)--thumbnail-scan-duration- Max seconds to scan from start (default: 120)--thumbnail-frames-per-second- Frame sampling rate (default: 3)
๐ Common Workflows
๐น Creating YouTube Chapters
# Scan video and save chapters for YouTube description
loups -o youtube_chapters.txt my_video.mp4
# Copy the contents of youtube_chapters.txt to your video description!
๐จ Using Custom Templates
# Step 1: Create a template from a clear frame
# (Screenshot the text/overlay you want to detect)
# Step 2: Use your template
loups -t my_custom_template.png -o chapters.txt video.mp4
๐ง Troubleshooting with Logs
# Enable logging to debug detection issues
loups --log video.mp4
# Use custom log location with debug level
loups --log /path/to/debug.log --debug video.mp4
๐ค Automation & Batch Processing
# Process multiple videos quietly
loups -q -o video1_chapters.txt video1.mp4
loups -q -o video2_chapters.txt video2.mp4
loups -q -o video3_chapters.txt video3.mp4
๐ผ๏ธ Creating Thumbnails for YouTube
# Extract thumbnail with chapters in one command
loups -o chapters.txt --extract-thumbnail --thumbnail-output thumbnail.jpg game_video.mp4
# Or extract thumbnail separately
loups game_video.mp4 thumbnail --thumbnail-template title_screen.png
# Batch thumbnail extraction
loups video1.mp4 thumbnail --thumbnail-output vid1_thumb.jpg
loups video2.mp4 thumbnail --thumbnail-output vid2_thumb.jpg
loups video3.mp4 thumbnail --thumbnail-output vid3_thumb.jpg
โ๏ธ CLI Options
Command Structure:
- Default scanning:
loups [OPTIONS] VIDEO- Options must come BEFORE the video path - Thumbnail extraction:
loups VIDEO thumbnail [OPTIONS]- Thumbnail options come AFTER the subcommand
Main Command: loups [OPTIONS] VIDEO
Scan video for chapters (batter at-bats or any detected frames).
Required Arguments:
| Argument | Description |
|---|---|
VIDEO |
๐ฅ Path to the video file to scan (must come AFTER options) |
Optional Flags:
| Flag | Short | Description |
|---|---|---|
--template PATH |
-t |
๐จ Path to template image for detection โข Defaults to bundled Lights Out HB template โข Provide your own for any video content |
--output PATH |
-o |
๐พ Save results to file in YouTube chapter format |
--log [PATH] |
-l |
๐ Enable logging (defaults to loups.log, or specify custom path)โข Rotates at 10MB โข Keeps 3 backup files |
--quiet |
-q |
๐คซ Suppress progress display (errors still shown) |
--debug |
-d |
๐ Enable DEBUG level logging (requires --log) |
--extract-thumbnail |
๐ผ๏ธ Extract thumbnail during chapter scan | |
--thumbnail-template PATH |
๐จ Path to thumbnail template (optional) | |
--thumbnail-output PATH |
๐พ Thumbnail save location (default: <video>-thumbnail.jpg) |
|
--thumbnail-threshold FLOAT |
๐ฏ SSIM threshold 0.0-1.0 (default: 0.35) | |
--thumbnail-scan-duration INT |
โฑ๏ธ Max seconds to scan for thumbnail (default: 120) | |
--thumbnail-frames-per-second INT |
๐ Frame sampling rate (default: 3) |
Thumbnail Command: loups VIDEO thumbnail [OPTIONS]
Extract thumbnail from video using SSIM-based template matching.
Required Arguments:
| Argument | Description |
|---|---|
VIDEO |
๐ฅ Path to the video file (comes BEFORE the thumbnail subcommand) |
Optional Flags:
| Flag | Description |
|---|---|
--thumbnail-template PATH |
๐จ Path to thumbnail template (defaults to bundled template) |
--thumbnail-output PATH |
๐พ Output path (default: <video>-thumbnail.jpg in cwd) |
--thumbnail-threshold FLOAT |
๐ฏ Minimum SSIM score 0.0-1.0 (default: 0.35) |
--thumbnail-scan-duration INT |
โฑ๏ธ Max seconds to scan from start (default: 120) |
--thumbnail-frames-per-second INT |
๐ Frame sampling rate (default: 3) |
--quiet |
๐คซ Suppress output |
โญ Features
๐ฏ Core Features
- ๐ฅ Animated Progress Display - Real-time scanning with fun animations
- ๐ Template Matching - Detects specific frames using image templates
- ๐ OCR Text Extraction - Reads text from matched frames to create chapter titles
- ๐บ YouTube-Ready Output - Generates properly formatted chapter timestamps
- ๐ผ๏ธ Thumbnail Extraction - SSIM-based automatic thumbnail extraction
- ๐จ Universal Custom Templates - Works with ANY video content
- ๐ Bundled Templates - Ready to use with Lights Out HB fastpitch games
๐ ๏ธ Technical Features
- ๐ Optional Logging - File logging with automatic rotation (10MB, 3 backups)
- ๐ง Debug Mode - Detailed logs for troubleshooting
- ๐คซ Quiet Mode - Perfect for automation and scripting
- โก Efficient Processing - Optimized video frame analysis
- ๐ฏ Smart OCR - Confidence-based text extraction with filtering
- ๐ Smart Text Sorting - Left-to-right ordering of OCR results
๐ How It Works
Loups processes your video in several steps to create YouTube chapters:
-
๐ Template Matching - Scans video frames looking for your template image
- The template acts as a "trigger" that identifies frames of interest
- When a match is found, Loups knows this frame contains information to extract
-
๐ OCR Text Extraction - On each matched frame, OCR reads the visible text
- Extracts all text from the matched region (names, numbers, titles, etc.)
- Applies confidence filtering to ensure accuracy
- Sorts text elements left-to-right for proper ordering
-
โฑ๏ธ Chapter Title & Timestamp - Combines the extracted text with video timestamp
- Creates a chapter entry like:
0:05:23 John Smith #12 - Each detection becomes a new YouTube chapter marker
- Creates a chapter entry like:
-
๐พ YouTube Format Output - Exports chapters in YouTube-ready format
- Copy and paste directly into your video description
- Format:
HH:MM:SS Chapter Title
Example:
0:00:00 Game Start
0:05:23 Sarah Johnson #7
0:08:45 Emma Martinez #12
0:12:30 Lily Garcia #9
๐จ Creating Custom Templates
Loups works with any video - just provide a template!
- Find a clear frame - Pause your video where the text/overlay is visible
- Take a screenshot - Capture the region you want to detect
- Crop the template - Include the area where text appears
- Use it -
loups -t my_template.png video.mp4
Tips for good templates:
- โ Clear, high-contrast text
- โ Consistent position throughout video
- โ No motion blur or partial occlusion
- โ Crop tightly around the target region
Example use cases:
- ๐ฎ Game mode indicators or level titles
- ๐ Speaker name overlays in lectures
- ๐บ Episode titles or scene markers
- ๐ Scoreboard player names (original use case)
- ๐ต Song title overlays in music videos
- ๐ฐ News segment titles or chyrons
๐ก Tips & Best Practices
๐ฏ For Best Results
- โ Use high-quality video recordings (720p or higher recommended)
- โ Ensure your template region is consistently visible throughout the video
- โ Steady lighting/contrast improves OCR accuracy
- โ Test on a short clip before processing full videos
- โ The text in matched frames becomes your chapter titles - ensure it's readable!
๐ง Troubleshooting
- Missed detections? Enable
--log --debugto see template matches and OCR results - Wrong text extracted? Your template might be too large or including unwanted regions
- False positives? Consider cropping your template more tightly around the identifying region
- Template not matching? Ensure the template exactly matches the video frames
- Names in wrong order? OCR results are automatically sorted left-to-right
- Blank chapter titles? OCR confidence might be too low - check logs with
--debug
๐ค Contributing
Contributions are welcome! Whether it's:
- ๐ Bug reports
- ๐ก Feature suggestions
- ๐ Documentation improvements
- ๐ง Code contributions
- ๐จ Sharing interesting use cases and templates
Please open an issue or pull request on GitHub.
๐ License
This project is licensed under the MIT License.
๐ Acknowledgments
Originally created for Lights Out HB fastpitch softball coverage, now a flexible tool for any video content creator!
Made with โค๏ธ for content creators ๐ฌ
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file loups-0.1.0.tar.gz.
File metadata
- Download URL: loups-0.1.0.tar.gz
- Upload date:
- Size: 461.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3f4fc32d09d32d65680cf873f709730f2e2e5e0c5f8dca5d0ba12e76e1a604e
|
|
| MD5 |
f1ce8e8e7da40b83e2d41c5370d06313
|
|
| BLAKE2b-256 |
86e793d150206903033b0dfd1129c184679c485905d9b9eb208bc76e2650e890
|
Provenance
The following attestation bundles were made for loups-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yaml on jcspeegs/loups
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loups-0.1.0.tar.gz -
Subject digest:
a3f4fc32d09d32d65680cf873f709730f2e2e5e0c5f8dca5d0ba12e76e1a604e - Sigstore transparency entry: 719536635
- Sigstore integration time:
-
Permalink:
jcspeegs/loups@c34fd46b8688f8e46747b751bfae6cb8844f46b6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jcspeegs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yaml@c34fd46b8688f8e46747b751bfae6cb8844f46b6 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file loups-0.1.0-py3-none-any.whl.
File metadata
- Download URL: loups-0.1.0-py3-none-any.whl
- Upload date:
- Size: 402.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
122c06358d86c5d8a74f709b6a42932a3b2b7faf9daca761fd2d42817a1234fe
|
|
| MD5 |
8f338e052a32ae3374338132450cec30
|
|
| BLAKE2b-256 |
884fde55752bb09d51e5dfd707d1a5fbf1274d5e3eee08ececcf160c11ab432d
|
Provenance
The following attestation bundles were made for loups-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yaml on jcspeegs/loups
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loups-0.1.0-py3-none-any.whl -
Subject digest:
122c06358d86c5d8a74f709b6a42932a3b2b7faf9daca761fd2d42817a1234fe - Sigstore transparency entry: 719536638
- Sigstore integration time:
-
Permalink:
jcspeegs/loups@c34fd46b8688f8e46747b751bfae6cb8844f46b6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jcspeegs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yaml@c34fd46b8688f8e46747b751bfae6cb8844f46b6 -
Trigger Event:
workflow_dispatch
-
Statement type: