PyFADE
PyFADE is an unofficial Python implementation of FADE (Fog Aware Density Evaluator).
The implementation is designed to closely match the MATLAB results, while providing higher efficiency and stronger plug-and-play compatibility with existing experimental code.
⚙️ Installation
Install from PyPI:
pip install fade-python
The published distribution name is fade-python, while the import package and
CLI command remain pyfade.
Install from a local checkout:
git clone https://github.com/cnyvfang/PyFADE.git
cd PyFADE
# Option 1:
pip install . # standard install
# Option 2:
pip install -e ".[dev]" # editable install for development
# Option 3:
pip install ".[tensor]" # with PyTorch input support
The base install already includes the current runtime dependencies used by the
latest implementation, including numba and turbojpeg.
🔨 Usage
from pyfade import fade
Accepted inputs
- Image path:
.jpg,.jpeg,.png,.bmp,.tif,.tiff - Folder path: a flat, non-recursive directory of supported image files
.npypath: loaded and processed as a NumPy array- NumPy arrays:
(H, W, 3),(3, H, W),(B, H, W, 3), or(B, 3, H, W) - PyTorch tensors:
(H, W, 3),(3, H, W),(B, H, W, 3), or(B, 3, H, W)
Input conventions
uint8inputs are interpreted as0..255images- Floating-point inputs in
[0, 1]are treated as normalized images and scaled to0..255 - Other floating-point inputs are treated as already being in
0..255 - Tensor inputs are copied to CPU and processed through the same MATLAB-aligned NumPy path
Return values
- Single image input:
float, or(score, density_map)whenreturn_map=True - Batch array/tensor input:
scoreswith shape(B,), or(scores, density_maps)whenreturn_map=True - Folder input:
FolderResultwithscores, optionaldensity_maps, andmean_score,min_score,max_score
Density maps always follow MATLAB-style patch trimming, so their shape is based
on the trimmed (H // 8, W // 8) patch grid.
Examples
Single image path:
score = fade("/path/to/image.png")
score, density_map = fade("/path/to/image.png", return_map=True)
Folder path:
result = fade("/path/to/folder", workers=4, progress=True)
print(result.mean_score)
print(result.scores["example.png"])
NumPy array:
import numpy as np
image = np.zeros((256, 256, 3), dtype=np.uint8)
score = fade(image)
np.save("sample.npy", image)
score_from_npy = fade("sample.npy")
batch = np.random.randint(0, 256, size=(8, 3, 256, 256), dtype=np.uint8)
scores, density_maps = fade(batch, workers=4, progress=True, return_map=True)
PyTorch tensor:
import torch
batch = torch.randint(0, 256, (8, 3, 256, 256), dtype=torch.uint8)
scores = fade(batch, workers=4, progress=True)
normalized = batch.to(torch.float32) / 255.0
scores, density_maps = fade(normalized, workers=4, progress=True, return_map=True)
🚀 Parallelism and Progress
workerscontrols image-level concurrencyprogress=Trueenables atqdmprogress bar for folder and batch evaluation
Example:
result = fade("/path/to/folder", workers=8, progress=True)
scores = fade(batch_tensor, workers=4, progress=True)
👨💻 CLI
PyFADE installs a pyfade command and is imported with import pyfade:
pyfade /path/to/image.png
pyfade /path/to/folder --workers 4 --progress
pyfade /path/to/array.npy --workers 4
pyfade /path/to/image.png --return-map
📖 Reference
To use PyFADE to validate your methods, please cite the original FADE paper.
@article{choi2015referenceless,
title={Referenceless prediction of perceptual fog density and perceptual image defogging},
author={Choi, Lark Kwon and You, Jaehee and Bovik, Alan Conrad},
journal={IEEE Transactions on Image Processing},
volume={24},
number={11},
pages={3888--3901},
year={2015},
publisher={IEEE}
}
If this port is useful in your work, we also hope you will consider citing our related dehazing work.
@article{fang2024real,
title={Real-world image dehazing with coherence-based pseudo labeling and cooperative unfolding network},
author={Fang, Chengyu and He, Chunming and Xiao, Fengyang and Zhang, Yulun and Tang, Longxiang and Zhang, Yuelin and Li, Kai and Li, Xiu},
journal={Advances in Neural Information Processing Systems},
volume={37},
pages={97859--97883},
year={2024}
}
📈 Benchmark and Precision Summary
| Runtime | Workers | Total Time (s) | Throughput (img/s) | Runtime | Workers | Total Time (s) | Throughput (img/s) |
|---|---|---|---|---|---|---|---|
| MATLAB | 1 | 809.04 | 5.3909 | Ours | 1 | 393.47 | 10.9844 |
| MATLAB | 4 | 286.69 | 15.5351 | Ours | 4 | 142.04 | 30.4283 |
| MATLAB | 8 | 216.34 | 20.7242 | Ours | 8 | 111.89 | 38.6282 |
| Dataset | Runtime | Mean Score | Runtime | Mean Score | Mean Diff | Max Diff |
|---|---|---|---|---|---|---|
| RTTS Hazy Images | MATLAB | 2.514381896977223 | Ours | 2.514345050406552 | -3.685e-05 | 4.163e-03 |
| RTTS PRISM Dehazed | MATLAB | 0.470454676887910 | Ours | 0.470454676888912 | 1.002e-12 | 1.346e-08 |
| Mini-ImageNet Testset | MATLAB | 0.484498390241121 | Ours | 0.484496958259041 | -1.432e-06 | 2.358e-03 |
🔍 MATLAB Version vs. Current PyFADE
- Both versions implement the same FADE algorithm and use the same original reference models.
- MATLAB relies on built-in operators such as
rgb2gray,rgb2hsv,fspecial,imfilter,im2col,entropy,nanvar/std, andmrdivide. - PyFADE reproduces those semantics explicitly, including patch order, border handling, convolution alignment, variance rules, and entropy behavior.
- PyFADE provides a broader interface surface than the original MATLAB function: it supports folder paths, image paths,
.npyfiles, NumPy arrays, and tensor-like inputs. - PyFADE also preserves higher-precision image I/O paths such as 16-bit PNG input and normalized float array/tensor input.
- Relative to the original MATLAB code, the current package adds:
- image-level multi-threaded execution
- vectorized rank-1 update for model-distance computation
- cached MSCN and CE kernels
- faster 1D convolution path for
1xNandNx1kernels - vectorized packed-
bincountentropy evaluation numba-accelerated hotspots for HSV conversion, entropy, and variance- faster JPEG decoding through
turbojpeg
- The precision difference is maintained at the level of floating-point noise.
- On the original paired
RTTSworkload benchmark in this repository, the current PyFADE implementation is faster than MATLAB at1,4, and8image-level workers.
Metadata
Release files for fade-python 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fade_python-1.0.0.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fade_python-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.7 kB
Release files / fade_python-1.0.0.tar.gz
| Download URL | fade_python-1.0.0.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80beeded901958c7a40cfb90ac40ebcbd17d73808b362558617ee6c6df558e34
|
|
BLAKE2b-256 checksum How to use checksums |
e88144957ffa80f2cef669dab2cd57296a91b2f22b2e4d7c995471f4a86c96dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / fade_python-1.0.0-py3-none-any.whl
| Download URL | fade_python-1.0.0-py3-none-any.whl |
|---|---|
| Size | 21.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92f0fac813ec23073e79be879525f2373068c806cd5a0f13821e688d8ce667b3
|
|
BLAKE2b-256 checksum How to use checksums |
1055811f70abf8fad1b4e3ad44747fd6602006f6d45638e75e71e2067b03f093
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|