Created split_png_by_brightness.py to split rasterized logos into separate SVG files by color for Underground Magnetics logo conversion. Key features: - OpenCV contour hierarchy detection for proper hole handling - Letters with enclosed shapes (d, o, g, etc.) now render correctly - Tight brightness thresholds to avoid antialiasing artifacts - Automatic bounding box cropping for optimal file sizes - Black text: brightness < 40 (236k pixels, 21 shape groups) - Grey icon: brightness 108-118 (119k pixels, 2 shape groups) Results: - um_black.svg: 6.1KB, 3070x233px (was 139KB, 3613x391px) - um_grey.svg: 728B, 413x390px (was 253KB, 3613x391px) Files: - split_png_by_brightness.py: Main color separation tool - IMPROVEMENTS.md: Detailed changelog and comparison - README_underground_magnetics.md: Usage documentation - underground-magnetics.eps: Source logo file - um_black.svg: Separated black text (cropped) - um_grey.svg: Separated grey icon (cropped) - requirements.txt: Added opencv-python dependency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
63 lines
2.0 KiB
Markdown
63 lines
2.0 KiB
Markdown
# Improvements to split_png_by_brightness.py
|
|
|
|
## Version 2 Fixes
|
|
|
|
### 1. Proper Hole Handling
|
|
**Problem**: Letters with enclosed shapes (like "d", "o", "g") were missing their holes, making them appear filled.
|
|
|
|
**Solution**:
|
|
- Switched from `scikit-image` contour detection to OpenCV's `cv2.findContours` with `RETR_CCOMP` mode
|
|
- This detects contour hierarchy (parent/child relationships)
|
|
- Holes are now included in the same SVG path as their parent contour
|
|
- Using `fill-rule="evenodd"` properly renders the holes
|
|
|
|
### 2. Better Color Detection
|
|
**Problem**: Antialiasing pixels around edges were being included, creating artifacts and incorrect bounding boxes.
|
|
|
|
**Solution**:
|
|
- Changed from single threshold to tight ranges
|
|
- Black text: brightness < 40 (was < 50)
|
|
- Grey icon: brightness 108-118 (was 80-120)
|
|
- This excludes antialiased edge pixels and prevents the grey icon from spanning the full image width
|
|
|
|
### 3. Automatic Bounding Box Cropping
|
|
**Problem**: SVG files contained a lot of empty space.
|
|
|
|
**Solution**:
|
|
- Added automatic cropping to bounding box by default
|
|
- Each SVG is sized to fit its content exactly
|
|
- `--no-crop` flag available if full canvas is needed
|
|
|
|
## Results
|
|
|
|
**Before (v1)**:
|
|
- um_black.svg: 139K, 27 separate paths, many filled letters
|
|
- um_grey.svg: 253K, 1609 paths, antialiasing artifacts, full width (3613px)
|
|
|
|
**After (v2)**:
|
|
- um_black.svg: 6.1K, 21 shape groups with proper holes, cropped to 3070x233
|
|
- um_grey.svg: 728B, 2 shape groups, clean edges, cropped to 413x390
|
|
|
|
## Dependencies Added
|
|
- opencv-python==4.13.0.92
|
|
|
|
## Default Parameters
|
|
- Black threshold: < 40 brightness
|
|
- Grey range: 108-118 brightness
|
|
- Cropping: enabled by default
|
|
|
|
## Usage
|
|
```bash
|
|
# Default (optimized for Underground Magnetics logo)
|
|
python split_png_by_brightness.py input.png --prefix output
|
|
|
|
# Custom thresholds
|
|
python split_png_by_brightness.py input.png \
|
|
--dark-threshold 40 \
|
|
--mid-min 108 \
|
|
--mid-max 118
|
|
|
|
# Disable cropping
|
|
python split_png_by_brightness.py input.png --no-crop
|
|
```
|