我正在寻找一种方法来检测两张相似图片的哪一张更加清晰。
我认为可以使用某种整体锐度的度量方式,并生成得分(假设例子:image1的锐度得分为9,image2的锐度得分为7,则image1更清晰)。
我已经搜索了一些关于锐度检测/评分算法的内容,但只找到了一些能够增强图像锐度的算法。
是否有人做过类似的事情,或者有任何有用的资源/线索?
我将在Web应用程序的上下文中使用此功能,因此首选PHP或C/C++。
我正在寻找一种方法来检测两张相似图片的哪一张更加清晰。
我认为可以使用某种整体锐度的度量方式,并生成得分(假设例子:image1的锐度得分为9,image2的锐度得分为7,则image1更清晰)。
我已经搜索了一些关于锐度检测/评分算法的内容,但只找到了一些能够增强图像锐度的算法。
是否有人做过类似的事情,或者有任何有用的资源/线索?
我将在Web应用程序的上下文中使用此功能,因此首选PHP或C/C++。
如在这个Matlab Central页面中所示,可以通过平均梯度幅值来估计清晰度。
我在Python中使用了以下代码:
from PIL import Image
import numpy as np
im = Image.open(filename).convert('L') # to grayscale
array = np.asarray(im, dtype=np.int32)
gy, gx = np.gradient(array)
gnorm = np.sqrt(gx**2 + gy**2)
sharpness = np.average(gnorm)
可以使用更简单的numpy.diff计算出类似的数字,而不是使用numpy.gradient。 需要调整结果数组的大小:
dx = np.diff(array)[1:,:] # remove the first row
dy = np.diff(array, axis=0)[:,1:] # remove the first column
dnorm = np.sqrt(dx**2 + dy**2)
sharpness = np.average(dnorm)
简单的方法是测量对比度-像素值之间差异最大的图像最为清晰。例如,可以计算像素值的方差(或标准偏差),较大的数值胜出。这种方法寻找整体对比度最大的图像,但可能不是您想要的--特别是,它倾向于偏好具有最大景深的图片。
根据您的需求,您可能更喜欢使用类似FFT的方法,以查看哪个显示了最高频率内容。这使您可以优先选择某些部分极其清晰的图片(但其他部分则不那么清晰)而不是具有更多景深的图片,因此更多的图像区域是相对清晰的,但最大清晰度较低(由于较小光圈的衍射通常会发生这种情况)。
一个简单实用的方法是使用边缘检测(边缘越多==图像更清晰)。
使用PHP GD快速而不失效率地实现。
function getBlurAmount($image) {
$size = getimagesize($image);
$image = imagecreatefromjpeg($image);
imagefilter($image, IMG_FILTER_EDGEDETECT);
$blur = 0;
for ($x = 0; $x < $size[0]; $x++) {
for ($y = 0; $y < $size[1]; $y++) {
$blur += imagecolorat($image, $x, $y) & 0xFF;
}
}
return $blur;
}
$e1 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Jonquil_flowers_at_f32.jpg/800px-Jonquil_flowers_at_f32.jpg');
$e2 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Jonquil_flowers_at_f5.jpg/800px-Jonquil_flowers_at_f5.jpg');
echo "Relative blur amount: first image " . $e1 / min($e1, $e2) . ", second image " . $e2 / min($e1, $e2);
(图像模糊较少则更清晰) 更高效的方法是在您的代码中检测边缘,使用Sobel算子。 PHP示例(我想重写为C ++应该会大大提高性能)。
imagecolorat()
返回的最后一个字节包含蓝色组件。如果要考虑红色和绿色,请在使用之前使用 imagefilter($image,IMG_FILTER_GRAYSCALE)
进行过滤处理。 - hermannkimagefilter($image, IMG_FILTER_EDGEDETECT)
返回大约为 127 的值。如果图片中存在更多对比度,则这些值与该值相比会更加不同。然而,平均值始终接近于 127。要解决此问题:计算灰度值的方差。 - hermannk