C# 用 FFT 识别模糊图像

C# Identify blur image with FFT

我正在寻找一种方法来识别图像是否在 C# 中模糊。我看到了 this post 但我没有看到适用于我的案例的方法。

我找到 AForge.dll 将 FFT 应用于我的图像。我正在寻找一种简单的方法来确定图像是否模糊(我对数学不是很满意)。

这是我的代码:

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...

这应该可以解决问题。

calcBlurriness()的结果越小(接近于零),图像越清晰。

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();}
        }
    }
}

备注:

  • 如您所见,我使用了 .NET 包装器 OpenCVSharp(有些人使用 Emgucv - 它看起来更复杂但可能更高级)。
  • 我做了一些测试。此方法不适用于某些类型的图像。我观察到包含某种自然噪声的图像存在问题,这可以解释为模糊。
  • 这是我第一次尝试 OpenCV。所以,要谨慎。改编自此 sample.