2

我想检测图像的模糊程度,可能它可以称为“模糊扩展”。我为此找到了一篇有用的论文:

http://www.cs.cmu.edu/~htong/pdf/ICME04_tong.pdf

我使用 OpenCV 并实现了本文的所有步骤,但结果与本文的结果不同。

有人可以给我任何关于检测“模糊扩展”的建议吗?

4

3 回答 3

6

您可以使用下一个算法检测模糊图像:

  1. 将图像转换为灰度格式。
  2. 计算灰度图像的最大绝对二阶导数(对于每个点):

    d[x,y] = max(abs(2*d[x,y] - d[x,y+1] -d[x,y-1]), abs(2*d[x,y] - d[x+1,y] -d[x-1,y]));
    
  3. 计算这个估计图像的直方图(最大绝对二阶导数)。

  4. 找到该直方图的上分位数 (0,999)。

  5. 如果该值小于阈值(大约为图像动态范围的 25%),则图像模糊。

  6. 如果要估计模糊值,请执行步骤 2-5 以缩小图像。

您可以自己编写这些算法,也可以使用Simd 库实现中的一种(免责声明:我是作者)。

  • Simd::BgrToGraySimd::BgraToGray(对于第 1 步)。
  • Simd::AbsSecondDerivativeHistogram(用于步骤 2-5)。
  • Simd::ReduceGray2x2(对于第 6 步)。
于 2013-10-18T12:41:22.347 回答
2

Ermlg的答案看起来接近最佳,但我以这种方式以代码方式实现了它。

低于 100 的分数给了我一些模糊的图像。

# applying fast fourier transform to fin d the blur images , taken threshold to be 100 but it can vary

import cv2

def variance_of_laplacian(frame_path):
    # compute the Laplacian of the image and then return the focus
    # measure, which is simply the variance of the Laplacian
    image = cv2.imread(frame_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    return cv2.Laplacian(gray, cv2.CV_64F).var()

方法来源来自阿德里安·罗斯布鲁克

于 2018-12-17T08:46:25.360 回答
1

这里需要注意的重要一点是,图像可能有一些模糊区域和一些清晰区域。例如,如果图像包含人像摄影,则前景中的图像清晰而背景模糊。在运动摄影中,对焦的对象很清晰,背景通常有运动模糊。检测图像中这种空间变化模糊的一种方法是在图像中的每个位置运行频域分析。解决该主题的论文之一是"Spatially-Varying Blur Detection Based on Multiscale Fused and Sorted Transform Coefficients of Gradient Magnitudes" (cvpr2017).

  • 作者查看了每个像素的多分辨率 DCT 系数。这些 DCT 系数分为频段,其中仅选择高频系数。
  • 然后将 DCT 系数融合在一起并排序以形成multiscale-fused and sorted high-frequency transform coefficients
  • 选择这些系数的子集。所选系数的数量是特定于应用程序的可调参数。
  • 然后通过最大池块发送选定的系数子集,以保留所有尺度内的最高激活。这将模糊贴图作为输出,然后通过后处理步骤发送以优化贴图。

此模糊图可用于量化图像各个区域的清晰度。为了得到一个单一的全局度量来量化整个图像的模糊度,可以使用这个模糊图的均值或者这个模糊图的直方图

以下是有关算法执行方式的一些示例结果: 在此处输入图像描述

图像中的锐利区域在 blur_map 中具有高强度,而模糊区域具有低强度。

该项目的 github 链接是:https ://github.com/Utkarsh-Deshmukh/Spatially-Varying-Blur-Detection-python

该算法的python实现可以在pypi上找到,可以很容易地安装,如下所示:

pip install blur_detector

生成模糊图的示例代码片段如下:

import blur_detector
import cv2
if __name__ == '__main__':
    img = cv2.imread('image_name', 0)
    blur_map = blur_detector.detectBlur(img, downsampling_factor=4, num_scales=4, scale_start=2, num_iterations_RF_filter=3)

    cv2.imshow('ori_img', img)
    cv2.imshow('blur_map', blur_map)
    cv2.waitKey(0)
于 2021-05-26T21:02:00.013 回答