C# Identify blur image with FFT [closed]
Asked Answered
M

1

6

I'm looking for a way to identify if an image is blur in C#. I saw this post but I did not see the way to apply to my case.

I found the AForge.dll to apply the FFT to my Image. I'm looking for a simple way to determine if image is blurred or not (I'm not very confortable with mathematics).

There is my code :

Bitmap  Picture;

// I'm working with images sized between 130x130 and 150x150
Bitmap tmp = new Bitmap(pictureFile);

// Crop to be 128x128
Bitmap cropped = cropBitmap(tmp, 128, 128);
using (MemoryStream ms = new MemoryStream())
{
    cropped.Save(ms, ImageFormat.Gif);
    ms.Position = 0;
    // Save in grayscale
    Picture = new Bitmap(ms);
}

// Create the ComplexImage with AForge.dll
ComplexImage output = ComplexImage.FromBitmap(Picture);
// Apply FFT
output.ForwardFourierTransform();
Bitmap result = output.ToBitmap();

// to be continued...
Myer answered 12/2, 2018 at 16:47 Comment(3)
How is your case different from the one in the post you mentioned? Are you simply having trouble translating the opencv, Mathematica and Matlab based solutions to C#? If that's the case, where did you get stuck (have you tried e.g. an openCV .net wrapper)? Otherwise, care to elaborate on the difference for your case?Bighead
Considering blurring algorithms use an average from surrounding pixels, you should be able to detect this average being applied across the entire image in the form of a uniform RGB distribution.Barbitone
Possible duplicate of Is there a way to detect if an image is blurry?Guayaquil
L
8

This should do the trick.

The smaller (closer to zero) the result of calcBlurriness(), the sharper the image.

using OpenCvSharp;    
namespace BlurDetectSO {
    class Program
    {

        static float calcBlurriness(Mat src)
        {
            Mat Gx = new Mat();
            Mat Gy = new Mat();
            Cv2.Sobel(src, Gx, MatType.CV_32F, 1, 0);
            Cv2.Sobel(src, Gy, MatType.CV_32F, 0, 1);
            double normGx = Cv2.Norm(Gx);
            double normGy = Cv2.Norm(Gy);
            double sumSq = normGx * normGx + normGy * normGy;
            return (float)(1.0 / (sumSq / (src.Size().Height * src.Size().Width) + 1e-6));
        }

        static void Main(string[] args)
        {
            Mat src = Cv2.ImRead("lenna.png", ImreadModes.GrayScale);
            Mat dst = new Mat();

            var blurIndex = calcBlurriness(src);

            //test: find edges...
            //Cv2.Canny(src, dst, 50, 200);
            //using (new Window("src image", src))
            //using (new Window("dst image", dst))
            //{Cv2.WaitKey();}
        }
    }
}

Notes:

  • As you can see, I used the .NET wrapper OpenCVSharp (some use Emgucv instead - it looked more complicated but is perhaps more advanced).
  • I made a few tests. This method does not work very well with some types of images. I observed problems with images that contain some sort of natural noise, that can be interpreted as a blur.
  • This is my first OpenCV endeavor. So, be cautious. Adapted from this sample.
Landseer answered 12/2, 2018 at 19:1 Comment(3)
I fetched OpenCVSharp from Nuget, but the class names don't correspond to your example. Perhaps you can share which Nuget package you were using? There seem to be several ports.Dibrin
Looks like it's OpenCVSharp4 by shimat?Dibrin
@Dibrin Puh, that was in 2018, luckily, I still had the sample on my laptop. I used the package OpenCvSharp3-AnyCPU.3.3.1.20171117.nupkg by shimat. The only change I noticed was the property ImreadModes.GrayScale was renamed to Grayscale.Landseer

© 2022 - 2024 — McMap. All rights reserved.