DEV Community

Cover image for Image blur detection using scipy
Tejas Patil
Tejas Patil

Posted on

Image blur detection using scipy

When you work with images — especially in real-time systems — one tiny issue can ruin your entire pipeline: blur.

A blurry image means unreliable results.
But how do you detect blur accurately without slowing everything down?

That’s exactly what I set out to solve — and after testing multiple approaches, I found that sometimes, you don’t need fancy methods.
Even simple ones can work surprisingly well if used right.

The Goal: Detect Blur Efficiently

In my project, I needed a blur detection method that could:

⚡ Work fast for real-time image capture

💻 Run on limited hardware (like Raspberry Pi)

🧩 Be lightweight and easy to integrate

Simple requirements — but meeting all three turned out to be a journey. 😅

⚙️ Attempt 1: Tenengrad (Using OpenCV)

I started with the Tenengrad method, a classic sharpness measure using Sobel gradients.

It’s accurate and mathematically solid — but there was a big catch:

💾 OpenCV’s footprint was heavy.

On resource-limited devices, the disk usage and installation size made it a deal-breaker.
So, I moved on.

🔍 Attempt 2: SciPy’s convolve2d

To keep things lightweight, I tried using SciPy’s convolve2d to apply Sobel filters manually.

It worked decently — small footprint, fast execution, and minimal dependencies.
But…

⚠️ Accuracy dropped for low-texture or unevenly lit images.
A few blurry images were being classified as “clear.”

⚡ Attempt 3: FFT-Based Blur Detection

Then came the FFT (Fast Fourier Transform) approach.

The idea is elegant — sharp images have more high-frequency content, while blurry ones don’t.

But in practice:

❌ Too slow
❌ Too complex for real-time use

FFT-based methods are great for research or offline analysis, but not for a live camera feed.

🤖 Attempt 4: PIQ (PyTorch Image Quality)

Next, I explored PIQ, a PyTorch-based library that measures perceptual quality — including blur.

It was extremely accurate, no doubt about that.

But…

⏳ Too slow on CPU
⚙️ Required CUDA for speed
🚫 Overkill for lightweight systems

So I had to drop it too.

🧩 The Winner: SciPy’s ndimage

After several trials, I circled back to something simple — scipy.ndimage.

It lets you compute Sobel gradients efficiently and measure how much variation exists in the gradient magnitudes — a direct indicator of image sharpness.

Here’s the magic in just a few lines 👇

#magnitude adjustment can be done based on your requirements
from scipy import ndimage
import numpy as np

def estimate_blur(image):
    gx = ndimage.sobel(image, axis=0)
    gy = ndimage.sobel(image, axis=1)
    magnitude = np.hypot(gx, gy)
    return magnitude.var()  # Higher variance = sharper image
Enter fullscreen mode Exit fullscreen mode

That’s it.
No heavy libraries, no CUDA setup — and it just works.

✅ Why It Worked Best

🪶 Lightweight — no OpenCV dependency

⚡ Fast — great for real-time use

🎯 Accurate enough for production

🔧 Easy to integrate anywhere

💬 Why Not Always Go Fancy?

Sometimes, we chase fancy methods because they sound more “AI-powered” or “modern.”
But in real-world systems, especially those running on edge devices, simplicity wins.

You don’t always need deep learning or complex transforms — sometimes a clean, optimized classical method can outperform heavy models when implemented smartly.

💡 Final Thoughts

Finding the “best” blur detection method isn’t about using the most advanced algorithm — it’s about what fits your use case and environment.

For me, scipy.ndimage struck the perfect balance between speed, accuracy, and simplicity.

🚀 What’s Next

I plan to enhance this further by adding:

Edge density analysis

Variance normalization

Adaptive thresholding

to make it more robust under challenging lighting or texture variations.

🧾 Summary

👉 Tenengrad (OpenCV) — dropped due to heavy footprint
👉 SciPy’s convolve2d — fast but less accurate
👉 FFT — too slow for real-time
👉 PIQ — accurate but heavy
✅ SciPy’s ndimage — perfect balance

💭 Final Takeaway

Sometimes, the simplest approach — done right — beats the most complex one.
In engineering, elegance lies in simplicity. ✨

Top comments (0)