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...
A.Pissicat
  • 3,023
  • 4
  • 38
  • 93
  • How is your case different from the one in [the post you mentioned](https://stackoverflow.com/questions/7765810/is-there-a-way-to-detect-if-an-image-is-blurry)? 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? – SleuthEye Feb 12 '18 at 17:47
  • 1
    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. – Krythic Feb 12 '18 at 19:04
  • Possible duplicate of [Is there a way to detect if an image is blurry?](https://stackoverflow.com/questions/7765810/is-there-a-way-to-detect-if-an-image-is-blurry) – Zze Feb 13 '18 at 00:47

1 Answers1

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.
wp78de
  • 18,207
  • 7
  • 43
  • 71
  • 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. – Savage Aug 14 '20 at 12:49
  • Looks like it's OpenCVSharp4 by shimat? – Savage Aug 14 '20 at 12:55
  • 1
    @Savage 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`. – wp78de Aug 14 '20 at 16:43