【问题标题】:Detect which image is sharper检测哪个图像更清晰
【发布时间】:2011-10-02 13:08:20
【问题描述】:

我正在寻找一种方法来检测两个(相似)图像中哪一个更清晰。

我认为这可能是使用某种衡量整体清晰度并生成分数(假设示例:image1 的清晰度得分为 9,image2 的清晰度得分为 7;因此 image1 更清晰)

我搜索了一些锐度检测/评分算法,但只找到了可以提高图像锐度的算法。

有没有人做过类似的事情,或者有任何有用的资源/线索?

我将在 web 应用程序的上下文中使用此功能,因此首选 PHP 或 C/C++。

【问题讨论】:

  • 它们是相同对象/距离的两张图像,但一张比另一张更清晰吗?
  • 有趣的论文:ieeexplore.ieee.org/xpl/…(使用特征值测量图像清晰度)
  • @gigantt,谢谢,会检查一下。在大多数情况下,我想图像会大部分相似。也许距离的微小变化可能会导致被摄体大小的微小变化,或者景深较窄,可能会导致不同部分处于对焦/失焦状态。

标签: image-processing detection scoring


【解决方案1】:

例如如this Matlab Central page所示,可以通过平均梯度幅度来估计锐度。

我在 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)

【讨论】:

  • 是的,清晰度越低意味着模糊度越高。
  • 这是否需要在灰度图像上进行,如matlab代码中那样?或者它也应该适用于彩色图像? (我假设array = list(img.getdata()),这是正确的吗?)
  • @faerubin,我的代码用于灰度。我现在已经扩展了 sn-p 来展示这一点。但是,类似的方法也适用于彩色图像数据。
【解决方案2】:

检查对比度传递函数 (CTF)

Here's 一个实现
Here's 一个解释

【讨论】:

  • 据我所知,论文和实现适用于电子显微镜。外推到普通摄影似乎并不简单。我投了反对票,因为我很想知道如何在这里使用 CTF,在您编辑并增强您的答案后,我将删除我的投票。谢谢!
  • 链接已损坏 :(
  • 您应该同时发布它们,而不是提供可能会更改的链接。
【解决方案3】:

简单实用的方法是使用边缘检测(更多边缘 == 更清晰的图像)。

使用 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 example(我猜用 C++ 重写应该会带来巨大的性能提升)。

【讨论】:

  • imagecolorat() 返回的最后一个字节包含蓝色分量。要考虑红色和绿色,请先使用过滤器imagefilter ($image, IMG_FILTER_GRAYSCALE);
  • imagefilter($image, IMG_FILTER_EDGEDETECT) 返回值大约为 127。如果图片中的对比度更高,则值与 本地 的值相差更大。尽管如此,平均值始终接近 127。修复:计算灰度值的方差。
【解决方案4】:

This paper 描述了一种使用 DWT 计算模糊因子的方法。看起来很直接,但不是检测清晰度,而是检测模糊。似乎它首先检测边缘(简单卷积),然后使用 DWT 对其进行累积和评分。

【讨论】:

    【解决方案5】:

    简单的方法是测量对比度——像素值差异最大的图像最清晰。例如,您可以计算像素值的方差(或标准差),并以产生较大数字的为准。这会寻找最大的整体对比度,但这可能不是您想要的 - 特别是,它倾向于支持具有最大景深的图片。

    根据您的需要,您可能更喜欢使用 FFT 之类的东西,以查看显示最高频率内容的内容。这使您可以偏爱在某些部分非常清晰(但在其他部分不太清晰)的图片,而不是具有更大景深的图片,因此更多的图像相当清晰,但最大锐度较低(这很常见,由于以较小的孔径进行衍射)。

    【讨论】:

    • 关于 FFT 方法,有趣的方法!你的意思是在 FFT 转换图像的某些部分比较图像的亮度吗?较高的频率会位于图像的中心还是边缘?
    • @ellockie:在 FFT 之后,您拥有的是描述图像的数据,但不再是实际图像。更高的频率取决于图像的内容,而不是图像中的位置(即,可以在任何地方——想法是它会发生在最清晰的部分)。
    • 那么在 FFT 变换图像中,你能说离中心更远的像素代表与更详细特征相关的更高频率吗?谢谢你的解释。
    猜你喜欢
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2015-04-27
    相关资源
    最近更新 更多