我正在寻找一种“非常”简单的方法来检查图像位图是否模糊。我不需要精确和复杂的算法,涉及fft,小波等。即使它不准确也只是一个非常简单的想法。
我曾考虑计算像素(x,y)和像素(x + 1,y)之间的平均欧几里德距离,考虑它们的RGB分量,然后使用阈值,但它的工作非常糟糕。还有其他想法吗?
答案 0 :(得分:14)
不要计算相邻像素之间的平均值差异。
即使照片完全对焦,它仍然可以包含大面积的均匀颜色,例如天空。这些将降低平均差异并掩盖您感兴趣的细节。您真正想要找到的是最大差异值。
另外,为了加快速度,我不打算在图像中检查每个像素。你应该通过检查相隔10个像素的水平和垂直线网格来获得合理的结果。
以下是使用来自Wikimedia Commons(Bokeh_Ipomea.jpg)的图像的PHP GD图形功能的一些测试结果。 Sharpness
值只是最大像素差值的百分比为255(我只查看绿色通道;您应该首先转换为灰度)。下面的数字表示处理图像所需的时间。
如果你想要它们,这里是我使用的源图像:
该算法存在一个问题,即它依赖于具有相当高对比度的图像以及清晰的聚焦边缘。可以通过找到最大像素差( maxdiff ),并在以该位置为中心的小区域(范围)中查找像素值的整体范围来改进。然后计算清晰度如下:
清晰度 =( maxdiff /(偏移 + 范围))*(1.0 + 偏移 / 255)* 100%
其中 offset 是一个减少非常小边缘影响的参数,因此背景噪声不会显着影响结果。 (我使用了15的值。)
这会产生相当好的效果。任何锐度低于40%的东西都可能不在焦点之内。以下是一些示例(最大像素差异的位置和9×9局部搜索区域也显示供参考):
但结果仍不完美。本质上模糊的主体总是会导致锐度值低:
Bokeh效果可以从点光源产生锐边,即使它们完全失焦也是如此:
您评论说您希望能够拒绝用户提交的失焦照片。由于这种技术并不完美,我建议你改为通知用户图像是否模糊而不是完全拒绝它。
答案 1 :(得分:3)
我认为,从哲学上讲,所有自然图像都是模糊的......模糊程度和数量,取决于您的应用程序。一般而言,可以以各种方式测量图像的模糊度或清晰度。作为第一个简单的尝试,我会检查图像的能量,定义为平方像素值的归一化总和:
1 2 E = --- Σ I, where I the image and N the number of pixels (defined for grayscale) N
首先,您可以应用拉普拉斯高斯(LoG)滤波器来检测图像的“高能”区域,然后检查能量。模糊的图像应该显示出相当低的能量。
使用典型的灰度lena图像查看MATLAB中的示例:
这是原始图片
这是模糊的图像,模糊高斯噪声
这是原始的LoG图片
这是模糊的一个的LoG图像
如果你只计算两张LoG图像的能量,你会得到:
E = 1265 E = 88 or bl
这是一个巨大的差异......
然后你只需选择一个阈值来判断哪种能量对你的应用有好处......
答案 2 :(得分:1)
计算相邻像素的平均L1距离:
N1=1/(2*N_pixel) * sum( abs(p(x,y)-p(x-1,y)) + abs(p(x,y)-p(x,y-1)) )
然后是平均L2距离:
N2= 1/(2*N_pixel) * sum( (p(x,y)-p(x-1,y))^2 + (p(x,y)-p(x,y-1))^2 )
然后,比率N2 /(N1 * N1)是模糊度的量度。这适用于灰度图像,对于颜色,您可以分别为每个通道执行此操作。