Interactive ROI selection tool to blur parts of an image for privacy redaction using OpenCV, with ICC color-profile preservation.
Project description
ROI Blur
A simple, interactive OpenCV-based utility for selecting regions of interest (ROIs) in an image and applying Gaussian blur to those regions. Perfect for privacy redaction, hiding sensitive information, or creative effects.
Features
- Interactive Selection: Click and drag to draw ROI rectangles
- Undo Support: Remove accidentally drawn ROIs with 'u' key
- Adjustable Blur: Control kernel size and sigma via CLI
- Multiple Formats: Supports JPG, PNG, BMP, TIFF, WebP
- Color Preservation: Maintains ICC color profiles and metadata
- Robust: Handles edge cases, validates inputs, clamps to bounds
Installation
Prerequisites
- Python 3.8+
- OpenCV 4.x
Quick Run with uvx (no install)
uvx --from git+https://github.com/techquestsdev/roi-blur roi-blur input.jpg output.jpg
Install via uv (recommended)
# Clone and install
git clone https://github.com/techquestsdev/roi-blur.git
cd roi-blur
uv sync
# Run
uv run roi-blur input.jpg output.jpg
Install via pip
# Clone the repository
git clone https://github.com/techquestsdev/roi-blur.git
cd roi-blur
# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install the package
pip install -e .
Usage
Basic Usage
python roi_blur.py input.jpg output.jpg
With Custom Blur Settings
python roi_blur.py photo.png blurred.png --ksize 51 --sigma 50
Interactive Controls
| Key | Action |
|---|---|
| Click + Drag | Draw ROI rectangle |
| ENTER / SPACE | Confirm selection |
| ESC | Cancel current selection |
| u | Undo last ROI |
| q | Finish and apply blur |
usage: roi_blur [-h] [-k N] [-s N] [-v] INPUT OUTPUT
Interactively select regions in an image and apply Gaussian blur.
positional arguments:
INPUT Path to the input image file
OUTPUT Path for the output image file
options:
-h, --help show this help message and exit
-k N, --ksize N Blur kernel size (positive odd integer, default: 23)
-s N, --sigma N Blur sigma/strength (positive float, default: 30.0)
-v, --version show program's version number and exit
Examples
Blur Faces for Privacy
python roi_blur.py family_photo.jpg privacy_safe.jpg --ksize 45 --sigma 60
Redact Sensitive Text
python roi_blur.py document.png redacted.png --ksize 31 --sigma 40
Artistic Background Blur
python roi_blur.py portrait.jpg artistic.jpg --ksize 15 --sigma 20
Programmatic Usage
You can also use the blur function programmatically:
import cv2
from roi_blur import blur_boxes
# Load image
image = cv2.imread("photo.jpg")
# Define ROIs: list of (x, y, width, height) tuples
boxes = [
(100, 100, 200, 150), # First region
(400, 300, 100, 100), # Second region
]
# Apply blur
result = blur_boxes(image, boxes, ksize=31, sigma=40)
# Save result
cv2.imwrite("blurred.jpg", result)
How It Works
- Load Image: OpenCV reads the input image into a NumPy array
- ROI Selection: User draws rectangles using OpenCV's selectROI
- Gaussian Blur: Each selected region is extracted, blurred, and replaced
- Output: Result is displayed and optionally saved to disk
Technical Details
- Uses Pillow for loading/saving to preserve ICC color profiles
- Uses
cv2.GaussianBlurwithBORDER_REPLICATEto avoid edge artifacts - Kernel size is automatically adjusted to be odd (OpenCV requirement)
- ROI coordinates are clamped to image bounds for safety
- Original image is never modified (copy-on-write pattern)
Development
Setup
git clone https://github.com/techquestsdev/roi-blur.git
cd roi-blur
uv sync --all-extras
Running Tests
uv run pytest tests/ -v
Code Quality
# Linting
uv run ruff check roi_blur.py
# Type checking
uv run mypy roi_blur.py
# Formatting
uv run black roi_blur.py
Project Structure
roi-blur/
├── roi_blur.py # Main application
├── pyproject.toml # Project configuration & dependencies
├── uv.lock # Locked dependencies
├── tests/
│ └── test_roi_blur.py # Unit tests
├── LICENSE # GPL-3.0
└── README.md # This file
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (git checkout -b feature/AmazingFeature)
- Commit your changes (git commit -m 'Add some AmazingFeature')
- Push to the branch (git push origin feature/AmazingFeature)
- Open a Pull Request
License
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
Acknowledgments
- OpenCV for the computer vision library
- NumPy for array operations
- Pillow for image I/O with color profile support
Made with ❤️ and Python
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 roi_blur-1.0.0.tar.gz.
File metadata
- Download URL: roi_blur-1.0.0.tar.gz
- Upload date:
- Size: 27.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca96b06ef29a8e87585f1e0029ef7f14d42b1f8b0128d215f68131436715298f
|
|
| MD5 |
94915b0649a682a11e9ca40f476f6987
|
|
| BLAKE2b-256 |
18c5de3d49ff82f7b5db09256bda4f7050e6f5d4e4b298c375813458846fc450
|
Provenance
The following attestation bundles were made for roi_blur-1.0.0.tar.gz:
Publisher:
release.yml on techquestsdev/roi-blur
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roi_blur-1.0.0.tar.gz -
Subject digest:
ca96b06ef29a8e87585f1e0029ef7f14d42b1f8b0128d215f68131436715298f - Sigstore transparency entry: 960678088
- Sigstore integration time:
-
Permalink:
techquestsdev/roi-blur@e452be671dfc187f7fd0cd04befa42f896a8cc1a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/techquestsdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e452be671dfc187f7fd0cd04befa42f896a8cc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file roi_blur-1.0.0-py3-none-any.whl.
File metadata
- Download URL: roi_blur-1.0.0-py3-none-any.whl
- Upload date:
- Size: 22.3 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 |
f3220a1082838bac3f2c8fb24c0e2013e886fa9d7c4d88e75b4649b1d299a5e9
|
|
| MD5 |
561dbc5873450d7e363ed0d3c5c74caf
|
|
| BLAKE2b-256 |
be8d7a1200122522716a5c9e4cc043267a28d33c693f77f0e21aaecf3c31d423
|
Provenance
The following attestation bundles were made for roi_blur-1.0.0-py3-none-any.whl:
Publisher:
release.yml on techquestsdev/roi-blur
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roi_blur-1.0.0-py3-none-any.whl -
Subject digest:
f3220a1082838bac3f2c8fb24c0e2013e886fa9d7c4d88e75b4649b1d299a5e9 - Sigstore transparency entry: 960678146
- Sigstore integration time:
-
Permalink:
techquestsdev/roi-blur@e452be671dfc187f7fd0cd04befa42f896a8cc1a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/techquestsdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e452be671dfc187f7fd0cd04befa42f896a8cc1a -
Trigger Event:
push
-
Statement type: