Built to order

Low-Light Image Denoising using DnCNN

A DnCNN-based denoiser that cleans noise from low-light smartphone photos, built on Zhang et al.'s residual-learning network (arXiv 1608.03981, TIP 2017). The trick: the network predicts the noise itself, which is then subtracted from the input. The Flask demo takes a grainy night photo, lets you set the noise level with a slider, and shows a side-by-side comparison. An evaluation notebook computes PSNR and SSIM on the BSD68 benchmark during the build; no scores are claimed in advance.

Low-Light Image Denoising using DnCNN demo screenshot
More project photos (2)

The problem

Every smartphone owner knows the problem: a photo taken in dim light comes out grainy, and the phone's built-in cleanup often smears fine detail away along with the noise. Classical filters like median or bilateral use fixed local rules — they cannot tell texture from grain, so they blur edges while removing noise. In 2017, Zhang et al. showed a cleaner way with DnCNN: instead of predicting the clean image directly, the network learns to predict the noise, which is then subtracted from the input. Residual learning is an easier problem — noise has simpler structure than natural images — and batch normalization plus a deep stack of small convolutions keeps training stable. One conditioned model covers a range of noise levels, exactly what real low-light photos need. This build implements DnCNN in PyTorch with a Flask demo: upload a noisy photo, set the noise level with a slider, and compare noisy and cleaned versions side by side. An evaluation notebook computes PSNR and SSIM on BSD68 during the build — a genuine, auditable experiment for the report.

How it works

Dataset & model:
Dataset names: BSD68 (68 natural grayscale images) and Set12 (12 images) — the standard denoising benchmarks used in the original paper. Source: the public Berkeley segmentation dataset family releases. Training uses clean natural images corrupted with synthetic Gaussian noise at several noise levels to form noisy/clean pairs. Task: image denoising (image-to-image regression). Classes: none — not a classification task.
Model: DnCNN — "Beyond a Gaussian Denoiser: Residual Learning of Deep CNN for Image Denoising" (Zhang et al., arXiv:1608.03981, TIP 2017). Deep stack of 3x3 convolutions with batch normalization and ReLU, conditioned on noise level; the network predicts the noise residual, which is subtracted from the input.
Input: a noisy low-light photo (grayscale or color, JPEG/PNG, any size via patch stitching). Prediction: the noise residual per patch. Output: the cleaned photo, shown side by side with the original and downloadable.
Evaluation metrics: PSNR and SSIM on BSD68, computed by the evaluation notebook during the build; no scores claimed in advance. The report discusses the gap between synthetic training noise and real smartphone noise explicitly.

Working:

  1. Dataset: clean natural images are corrupted with synthetic Gaussian noise at several noise levels to create noisy/clean training pairs; BSD68 and Set12 are reserved as evaluation benchmarks.
  2. Preprocessing: images are split into overlapping patches so arbitrary image sizes can be processed; patches are normalized before being fed to the network.
  3. Training phase: the DnCNN — a deep stack of 3x3 convolutions with batch normalization and ReLU — is trained to predict the noise residual for each patch, conditioned on the noise level; checkpoints are validated with PSNR on held-out data.
  4. Evaluation phase (offline): the evaluation notebook runs the build's own weights over BSD68 and logs PSNR and SSIM across noise levels — no scores claimed in advance.
  5. Inference phase (demo): an uploaded noisy photo is split into overlapping patches; each patch passes through the DnCNN, which outputs a predicted noise residual; the residual is subtracted from the input patch to give the clean estimate; patches are stitched back with overlap blending to avoid seams.
  6. Output: the noise-level slider selects the model conditioning matching the photo's grain (light, medium, heavy presets), and the cleaned result is shown side by side with the original and is downloadable.

Specifications:
Model | DnCNN residual CNN (Zhang et al., arXiv:1608.03981, TIP 2017)
Core idea | Residual learning: the network predicts the noise, which is subtracted from the input
Architecture | Deep stack of 3x3 convolutions with batch normalization and ReLU
Datasets | BSD68 (68 images) and Set12 (12 images) for evaluation
Input | Noisy low-light grayscale or color photos, any size via patch stitching
Control | Noise-level slider (light/medium/heavy presets) selecting model conditioning
Output | Cleaned photo shown side by side with the original, downloadable
Demo app | Flask with upload, noise-level slider, side-by-side view and download
Evaluation | PSNR/SSIM on BSD68 computed by the notebook during the build; no scores claimed in advance
Weights | Trained DnCNN weights shipped with the build

Project features

DnCNN Residual-Learning Denoiser [implemented] — Predicts the noise residual and subtracts it, rather than predicting the clean image directly — the architecture from Zhang et al.
Noise-Level Slider [implemented] — Match the denoiser to the photo's grain, with light, medium and heavy presets plus fine control.
Grayscale and Color Support [implemented] — Both are handled in the same demo, with color channels processed jointly to avoid hue shifts.
Side-by-Side Comparison View [implemented] — Noisy and denoised versions are shown together so the improvement is directly visible.
BSD68 Batch Test Mode [implemented] — Run the whole BSD68 set through the pipeline via the notebook for benchmark-style evaluation.
PSNR/SSIM Evaluation Notebook [implemented] — Computes both metrics across noise levels during the build.
Patch-Based Inference [implemented] — Overlapping patches with blend stitching handle arbitrary image sizes without seams.
Blind (Unknown-Noise) Denoising [future-scope] — Automatic noise-level estimation without the slider is documented as a possible extension, not included.

What is included

Complete source code: DnCNN model, training loop, patch inference, Flask demo app
Trained DnCNN weights
Training notebook and evaluation notebook (PSNR/SSIM on BSD68)
Project report PDF: denoising background, residual-learning derivation, evaluation procedure, error analysis (synthetic-vs-real noise gap)
PPT presentation for final review
Viva Q&A preparation document: residual learning, batch normalization, noise models, PSNR/SSIM
Setup guide: environment, dependencies, GPU/CPU guidance

Limitations & prerequisites

The model assumes roughly Gaussian noise; heavy JPEG compression artifacts or motion blur are different problems needing different methods.
An almost-black image has no signal to recover — denoising removes noise, it does not invent detail that was never captured.
High noise-level settings can over-smooth fine texture, trading grain for softness.
Real smartphone noise differs from the synthetic training noise, so real captures are the tougher test; the report discusses this gap explicitly.
This is an educational prototype, not a replacement for a camera's image pipeline.

Frequently Asked Questions

What is residual learning, and why does DnCNN use it?

Instead of learning the mapping from noisy image to clean image, the network learns to predict just the noise. Noise has simpler structure than natural images, so the residual mapping is easier to learn and trains faster and more stably.

How is this better than a median or bilateral filter?

Classical filters use fixed local rules and blur edges while removing noise. DnCNN learns image structure from data, so it separates noise from texture far more aggressively while preserving edges.

What do the BSD68 and Set12 datasets contain?

Standard denoising benchmarks: BSD68 has 68 natural grayscale images and Set12 has 12, covering textures, edges and smooth regions. The evaluation notebook runs the trained model over them during the build.

Does it work on color photos?

Yes — the demo handles color images alongside grayscale, processing channels jointly so color noise is removed without shifting hues.

Is this project suitable for a final-year project?

Yes — for B.E./B.Tech Computer Science, AI/ML and Electronics students. It covers residual learning, batch normalization, noise modeling, patch-based inference, and PSNR/SSIM evaluation with a side-by-side demo that examiners can test with their own photos.

Components & software requirements

Python 3.10
PyTorch (DnCNN residual network implementation)
OpenCV, NumPy, PIL (patch handling, stitching, image IO)
Matplotlib (PSNR/SSIM logging, comparison plots)
Flask (demo web application)
BSD68 and Set12 datasets for evaluation (download guidance included)
Trained DnCNN weights shipped with the build
A GPU is recommended for training (cloud-GPU guidance included); demo inference runs on CPU

Delivery information

Built-to-order. The DnCNN training run across noise levels (the pacing item), the PSNR/SSIM evaluation run on BSD68, and the full documentation kit (report, PPT, viva Q&A, setup guide) are prepared fresh for the buyer. The exact build schedule is confirmed at quotation.

Support terms
  • Setup guidance: environment, dependencies, dataset download, GPU/cloud-GPU options
  • Viva preparation: residual learning intuition, batch normalization's role, noise models, reading PSNR and SSIM curves, the synthetic-vs-real noise gap
  • Customization discussion: new noise presets, UI changes, retraining notes (feasibility confirmed before quoting)

Download abstract (PDF)

Related guides

All guides
Blueprint-style technical illustration of multiple decision trees voting together into one final predictionStudents with basic Python and pandas skills who want a reliable first classifier for ML coursework and tabular data projects.

Random Forests Explained: Why Decision Trees Vote Better Together

Decision trees are readable but overfit; random forests fix this by training hundreds of varied trees on bootstrapped data with random feature subsets, then letting them vote. This guide explains Gini impurity, bagging, out-of-bag validation and the four hyperparameters that matter, with a complete scikit-learn workflow, honest feature-importance practices, and the mistakes students keep making.

Read guide
Illustration of object tracking showing video frames with bounding boxes and persistent ID labels following people and vehicles, comparing motion prediction and appearance matching.B.E./B.Tech Computer Science and Electronics students building video analytics projects — people counting, vehicle tracking, sports analysis — who have detection working and need

Object Tracking: DeepSORT and ByteTrack Explained

Detection finds objects per frame; tracking keeps their identities across frames. This guide explains tracking-by-detection, Kalman motion models, DeepSORT's appearance embeddings vs ByteTrack's low-confidence box recovery, tracking metrics (HOTA, IDF1, ID switches), and the tuning parameters that determine real-world quality.

Read guide
Illustration of image segmentation showing U-Net's U-shaped encoder-decoder with skip connections producing pixel masks, alongside Mask R-CNN detecting instances with masks.B.E./B.Tech Computer Science and AI/ML students moving from image classification or detection to pixel-level understanding — medical imaging, defect detection, autonomous driving

Image Segmentation: U-Net and Mask R-CNN

When projects need pixel-level answers, segmentation delivers. This guide explains semantic vs instance vs panoptic segmentation, U-Net's encoder-decoder with skip connections, Mask R-CNN's parallel mask head, Dice and IoU evaluation, paired augmentation, and how to choose the right architecture for your data and question.

Read guide
Get a quotation