E-RidNet (Grayscale) — Edge Attention + Residual CNN Image Denoiser

A model trained to remove noise from grayscale images. It is a modified version of the RidNet architecture: instead of recursive residual connections, discrete Residual Blocks are used, and an Edge Attention Module (EAM) is added before each residual block.

  • Parameter count: 297,281 (~1.1 MB)
  • Input: Single-channel image, normalized to the [0, 1] range, arbitrary H×W size
  • Output: Denoised image of the same size, in the [0, 1] range
  • Framework: TensorFlow / Keras 3
  • Task: Image-to-image (denoising)
  • Dataset: Oxford-IIIT Pet Dataset (a randomly selected subset)
  • Sample test result: PSNR 23.86 dB → 28.89 dB, SSIM 0.608 → 0.772

Model Description

The model consists of Edge Attention Module (EAM) → Residual Block → Edge Attention Module (EAM) → Residual Block, and finally a global skip connection from the input. It is fully convolutional (no pooling/downsampling), so it can be run on any image size other than the 128×128 used during training.

Each EAM extracts edge features with a convolution, scales them to [0,1] with sigmoid, and element-wise multiplies the resulting gate with the feature map to emphasize edge details. Each Residual Block consists of two convolution layers and a residual addition.

For architecture details and layer-by-layer verified Keras definition, see src/model.py in the main repository.

Usage

from huggingface_hub import hf_hub_download
import sys, numpy as np
from PIL import Image

# Download weights and architecture code
weights_path = hf_hub_download(repo_id="<your-username>/attention-residual-image-denoiser",
                                filename="weights/best_model_weights4.weights.h5")
model_py_path = hf_hub_download(repo_id="<your-username>/attention-residual-image-denoiser",
                                 filename="src/model.py")

sys.path.append(model_py_path.rsplit("/", 1)[0])
from model import load_pretrained

model = load_pretrained(weights_path=weights_path)

img = Image.open("noisy.png").convert("L")
x = (np.asarray(img, dtype=np.float32) / 255.0)[np.newaxis, ..., np.newaxis]
y = model.predict(x)[0, ..., 0]

Image.fromarray((y * 255).astype(np.uint8), mode="L").save("denoised.png")

Alternatively, you can load weights/final_model4.keras directly with tf.keras.models.load_model(..., compile=False) (for 128×128 inputs only).

Training Data and Evaluation

  • Training dataset: Oxford-IIIT Pet Dataset — a randomly selected subset of the dataset (to reduce computational cost).
  • Preprocessing: convert to grayscale → resize to 128×128 → add random amounts of noise → [0,1] normalization.
  • Noise type/severity: Gaussian, Salt & Pepper, Speckle, Poisson noises and Gaussian Blur — each added in random amounts to training samples (exact σ/ratio values are not specified in the report).
  • Loss function: HybridLoss — a weighted average of SSIM, PSNR, Blur Loss, Perceptual Loss, and Color Loss components; 17 different weight combinations were tried and the best was used.
  • Evaluation metrics (sample test image, final model): PSNR 23.86 dB → 28.89 dB, SSIM 0.608 → 0.772. These numbers are taken from a single sample image; a comprehensive test-set average is not shared in the report.
  • Training time / hardware: not specified in the report.

Limitations

  • Trained only for grayscale (single-channel) images.
  • final_model4.keras was saved with a fixed 128×128 input size; use the weights-only loading path (weights/best_model_weights4.weights.h5) for different sizes.
  • Training was performed on a limited number of animal (cat/dog) images; performance is not guaranteed on different image distributions (e.g., medical images, document scans).
  • A comprehensive test-set evaluation (average PSNR/SSIM, breakdown by noise type) is not included in this model card.

License

MIT

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support