2

I'm trying to tell if a given photo is blurry. I know that this is basically an impossible task, and that any metric will return undesirable results sometimes.

I'm wondering if there's a simple metric that at least tries to estimate blur that I can use though. Specifically, the task has a high tolerance for false positives. e.g. If I got something that eliminated 90% of blurry photos and 50% of non-blurry photos I would be very happy.

I'm trying to implement this in Java. I have an array of pixels (as ints). Please keep in mind I have a limited understanding of image processing techniques (fourier transforms, etc.), and I would love a very specific walkthrough of how to code a solution.

4

3 回答 3

2

一个非常简单的措施是应用 Sobel 滤波器并研究过滤后图像的整体能量。图像越模糊,边缘消失的越多,滤波图像的能量就越小。当然,当您尝试确定模糊与不模糊的阈值时,您会遇到这种方法的问题,但也许这个简单的方法会给您一个想法。

查看 wikipedia 中的 Sobel 过滤器,这里有一个代码片段来获取图像的边缘比率。您可以使用这些边缘比率来成对比较图像是否具有更多或更少的边缘。不过,请记住,这是一种简单的方法,a.lasram 的答案绝对是正确的。

    float[] sobelX = {
            -1, 0, 1,
            -2, 0, 2,
            -1, 0, 1,
    };
    BufferedImage image = ImageIO.read(new File("test.jpg"));
    ColorConvertOp grayScaleOp = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
    BufferedImage grayImage = grayScaleOp.filter(image, null);
    BufferedImageOp op = new ConvolveOp( new Kernel(3, 3, sobelX) );
    BufferedImage result = op.filter(grayImage, null);
    WritableRaster r = result.getRaster();
    int[] pixel = new int[r.getWidth()];
    double countEdgePixels = 0;
    for (int y = 0; y<r.getHeight();y++) {
        // System.out.println("y = " + y);
        r.getPixels(0, y, r.getWidth(),1, pixel);
        for (int i = 0; i < pixel.length; i++) {
            // create some stat out of the energy ...
            if (pixel[i] > 128) {
                countEdgePixels++;
            }
        }
    }
    System.out.printf("Edge pixel ratio = %4.4f\n", countEdgePixels/(double) (r.getWidth()*r.getHeight()));
    ImageIO.write(result, "png", new File("out.png"));
于 2013-07-11T13:03:27.430 回答
2

正如您所说,您不会找到通用指标。

还有不同类型的模糊:均匀,各向异性,运动模糊......

一般来说,模糊图像倾向于表现出低频。一个可能的描述符是 k 个最高频率的幅度之和。总和较低的图像可能整体模糊。

可以使用傅里叶谱(高频远离原点)或拉普拉斯金字塔(高频对应于第一个尺度)在 N*log(N) 时间内获得幅度。

小波变换是另一种可能的描述符

于 2013-07-11T01:50:19.453 回答
1

回复有点晚,但对于下一个会碰到这个问题的人来说是值得的。

我在 Google Scholars 中找到了几篇论文,这些论文讨论了将图片中所有边缘的总和与所有边缘的宽度相比较的平均值,如以下两篇文章所示:FirstSecond

于 2014-05-19T18:54:44.013 回答