Intelligent Haze Classification and Dehazing

This was my minor project in my 7th semester, during my Bachelor’s Degree. Most dehazing methods apply the same algorithm to every hazy image, whether it’s a light mist or a dense fog. Those are different problems, so I built a system that classifies how hazy an image is first, then routes it to a dehazer suited to that level.

Pipeline flowchart

A hazy image goes into a classifier, which labels it No Haze, Mild, or Dense. That label decides which dehazing network handles it. I built and trained the dehazer for the mild case; a dense-haze dehazer never got built.

The Haze Density Classifier

The classifier is a small CNN: three Conv2D and MaxPooling blocks, then Flatten, Dense, Dropout, and a softmax over the three classes.

The training data came from combining RESIDE, I-Haze, O-Haze, and NH-Haze, with the usual augmentations, rescaling, rotation, flips, zoom, brightness jitter. Trained with categorical cross-entropy. Validation accuracy went from 0.37 in the first epoch to 0.93 by the twentieth. The loss curves were noisy rather than smooth, which is normal for a dataset this size, but the trend held.

The same base image at increasing haze levels, classified as NoHaze at 100%, Mild at 71%, Dense at 55%. Confidence drops as the haze gets harder to place in one bucket, which is a real limitation and not something I’m glossing over.

The Dehazer

For the mild-haze dehazer, I implemented the architecture from Wu et al.’s Knowledge Transfer Dehazing Network, which placed top-3 in the NTIRE 2020 non-homogeneous dehazing challenge. I didn’t design this architecture, I implemented it and worked through the training details myself, since the paper doesn’t specify most of them.

KTDN architecture

It’s a teacher-student setup. The teacher trains only on clear images and learns a prior over what clean images look like, using Res2Net for feature extraction and PixelShuffle for upsampling. The student has the same architecture but trains on real hazy images, guided by its own reconstruction loss and by matching the teacher’s intermediate features. Both networks use channel attention and pixel attention blocks stacked together, which the paper credits for most of the quality gain.

The Teacher Network

The teacher was mostly trial and error. Plain L1 loss converged but gave blurry, washed-out images, so I added SSIM loss for structure and color consistency, then a VGG19 perceptual loss for texture and edges. Final weighting was L2 at 0.495, SSIM at 0.495, perceptual at 0.01, trained for 200 epochs. Validation loss went from 0.40 to 0.15.

The teacher’s reconstructions of clear images came out close to the originals, with some loss of fine detail and a slight color shift.

The Student Network

The student network is where this fell short. I added Laplacian loss for sharpness on top of L1 and the knowledge transfer loss, trained for 20 epochs, and the results tell a different story than the classifier’s.

The haze is removed and the structure comes through, but the color is mostly gone and there’s a heavy grain that wasn’t in the input. My best guesses: 20 epochs wasn’t enough given the teacher needed 200 for an easier task, the knowledge transfer loss was weighted too low at 0.01 to meaningfully pull the student toward the teacher’s feature space, and there was no color-consistency loss on the student side to catch the desaturation. I stopped short of isolating which of these actually mattered most.

I’m including the student’s results as they are, not just the classifier’s numbers, because that’s the accurate picture of where the project ended up.

Further Improvements

There’s clear room to build on this: longer training for the student, a color loss and proper Laplacian weighting, HazeSpace2M for more coverage, a pretrained encoder instead of Res2Net from scratch, and a dense-haze dehazer that never got built. If NIT Raipur carries this work forward, I hope what’s documented here, including where the student network fell short, is useful. The classifier is the part of this I’d stand behind without qualification.

This was my first time implementing a neural network for a domain-specific use case, and I learned a lot from it. The dehazer taught me how much work goes into turning an architecture on paper into a working implementation, from loss functions to training schedules.