Skip to course content
Free computer vision course

Computer Vision and Multimodal AI

Unit 03.01: Sharpening, and the noise it amplifies

Sharpening amplifies edges and noise together, because it cannot distinguish them.

Both are local intensity change

A sharpening kernel boosts the difference between a pixel and its neighbours.

The code measures the flat-area noise and the edge step before and after.

import cv2
import numpy as np

rng = np.random.default_rng(0)
clean = np.zeros((32, 32), dtype="uint8")
clean[:, 16:] = 200
noisy = np.clip(clean.astype(int) + rng.normal(0, 12, clean.shape), 0,
                255).astype("uint8")

kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], dtype="float32")
sharpened = cv2.filter2D(noisy, -1, kernel)

for label, img in [("noisy", noisy), ("sharpened", sharpened)]:
    flat = img[4:12, 2:10]
    edge = int(abs(int(img[16, 14]) - int(img[16, 18])))
    print(f"{label:10} flat-area std {flat.std():>5.1f}   edge step {edge:>3}")

# Sharpening amplified the edge and the noise together, because it cannot tell
# them apart -- both are local intensity change. Denoise first, then sharpen,
# or you are boosting exactly what you wanted to remove.

The edge got stronger and so did the noise in the flat regions. To the filter these are the same phenomenon - a pixel differing from its neighbours - and no kernel separates them.

Denoising before sharpening is the standard order for this reason. Sharpening first commits you to amplifying whatever noise was there.

The mistake this prevents

The mistake is sharpening to compensate for a blur applied earlier in the same pipeline. The blur removed information; sharpening cannot restore it and will amplify what remains, including the artefacts the blur introduced.

Takeaway

Sharpening boosts noise and edges equally. Denoise first, and never expect it to undo an earlier blur.