Kuwahara filter in python
Project description
pykuwahara
Kuwahara filter in Python (numpy + OpenCV).
The Kuwahara filter is a non-linear smoothing filter used in image processing for adaptive noise reduction. It is able to apply smoothing on the image while preserving the edges. Source: Wikipedia
This implementation provide two variants of the filter:
- The classic one, using a uniform kernel to compute the window mean.
- A gaussian based filter, by computing the window gaussian mean. This is inspired by the ImageMagick approach.
Installation
Requires Python 3.9+.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install pykuwahara
For development or running tests:
pip install -e ".[dev]"
pytest -q
Dependencies
Runtime wheels pulled in by pip:
| Package | Role |
|---|---|
| numpy | Arrays (>=1.26,<3). |
| opencv-python-headless | OpenCV without GUI (no HighGUI). Same main cv2 API used here (imgproc); no contrib modules. Smaller and suited to servers and CI than opencv-python. Pip selects a wheel compatible with your NumPy line (for example NumPy 1.x pairs with OpenCV 4.11.x; NumPy 2.x uses newer wheels). |
Install only one of the PyPI meta-packages that ship cv2 (opencv-python, opencv-python-headless, opencv-contrib-python, opencv-contrib-python-headless). They replace each other; mixing them causes broken or unpredictable installs.
Breaking change: releases now depend on opencv-python-headless instead of opencv-contrib-python. This project only needs the standard cv2 API. If you still have contrib installed, uninstall it and reinstall pykuwahara so pip resolves opencv-python-headless:
pip uninstall -y opencv-contrib-python opencv-contrib-python-headless opencv-python opencv-python-headless # remove any old cv2 wheel
pip install pykuwahara
PEP 668 (externally managed environments)
On recent Debian/Ubuntu (and similar), the system Python may refuse global pip install with an externally-managed-environment error. Use a virtual environment or a tool like uv. Avoid --break-system-packages unless you fully accept overwriting distro Python.
Test matrix (CI)
| Python | NumPy |
|---|---|
| 3.9 | 1.x (>=1.26,<2) |
| 3.11 | 1.x (>=1.26,<2) |
| 3.13 | 2.x (>=2,<3) |
* CI installs NumPy and OpenCV in one step so pip resolves a compatible pair.
OpenCV is always opencv-python-headless from package metadata (not a separate CI axis).
Usage
Simple example
import cv2
from pykuwahara import kuwahara
image = cv2.imread('lena_std.jpg')
filt1 = kuwahara(image, method='mean', radius=3)
filt2 = kuwahara(image, method='gaussian', radius=3) # default sigma: computed by OpenCV
cv2.imwrite('lena-kfilt-mean.jpg', filt1)
cv2.imwrite('lena-kfilt-gaus.jpg', filt2)
Original image
Filtered with Kuwahara (mean)
Filtered with Kuwahara (gaussian)
Painting effect
Kuwahara filter can be used to apply a painting effet on pictures.
import cv2
from pykuwahara import kuwahara
image = cv2.imread('photo.jpg')
# Set radius according to the image dimensions and the desired effect
filt1 = kuwahara(image, method='mean', radius=4)
# NOTE: with sigma >= radius, this is equivalent to using 'mean' method
# NOTE: with sigma << radius, the radius has no effect
filt2 = kuwahara(image, method='gaussian', radius=4, sigma=1.5)
cv2.imwrite('photo-kfilt-mean.jpg', filt1)
cv2.imwrite('photo-kfilt-gaus.jpg', filt2)
Original image (source: wikipedia)
Filtered with Kuwahara (mean)
Filtered with Kuwahara (gaussian)
Advanced usage
Color image are supported by grayscaling the source image and using the gray channel to calculate the variance.
The user can provide another channel at his convenience, and alternatively give the right color conversion code (default is COLOR_BGR2GRAY).
import cv2
from pykuwahara import kuwahara
image = cv2.imread('selfie.jpg')
image = (image / 255).astype('float32') # pykuwahara supports float32 as well
lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2Lab)
l, a, b = cv2.split(lab_image)
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)
filt1 = kuwahara(image, method='gaussian', radius=5, sigma=2., image_2d=l)
filt2 = kuwahara(image, method='gaussian', radius=5, sigma=2., image_2d=v)
cv2.imwrite('selfie-kfilt-gaus1.jpg', filt1 * 255)
cv2.imwrite('selfie-kfilt-gaus2.jpg', filt2 * 255)
Original image (source)
Filtered with Kuwahara on L (Lab)
Filtered with Kuwahara on V (HSV)
Project details
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 pykuwahara-0.4.0.tar.gz.
File metadata
- Download URL: pykuwahara-0.4.0.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55276a54e564b4c0be27291242a3e178819a5fe60ca3e67ed5a2eee843389a2e
|
|
| MD5 |
9c7b19eaa63a8323735220b2f481a911
|
|
| BLAKE2b-256 |
35a56b66f496edb9a9d209b5280f26d2e73872629b1ef4e7257d84d4f85b3071
|
File details
Details for the file pykuwahara-0.4.0-py3-none-any.whl.
File metadata
- Download URL: pykuwahara-0.4.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68d3b9732ea8c5114414068039f43672f6e8bced5fa3b437eb0e2dfe244dc965
|
|
| MD5 |
f6f78a302bb48ce3cf352fe5ae54734b
|
|
| BLAKE2b-256 |
d8dfc8d82125c0e01ccf3378a73d6609c03076a8fea9c395a48f0d28e9837e7f
|