有没有一种算法或库可以检测图像中的运动模糊?

11

有没有一种算法可以模糊地返回图像是否存在运动模糊/相机抖动的true/false结果?

理想情况下,它应该特别适用于运动模糊,因为数据集中的许多图像可能具有模糊(Bokeh)背景。

C、Perl、Shell Utility或Python是首选的语言,但我真的很开放。

基于我的目前对数学/编程的了解,我认为我没有希望编写这样的算法,只能使用需要一些参数的算法...


如果可能的话,请标记一些答案为已接受。目前还不清楚它们是否适合您的需求。 - Tõnu Samuel
4个回答

4

离散小波变换是一种在图像模糊检测中非常有用的工具。这篇论文来自于卡内基梅隆大学计算机科学学院,介绍了如何使用DWT来检测和量化图像中的模糊程度。对于二元决策,您可以将模糊程度阈值设定为所需级别,高于该级别的部分即为模糊。


这很方便,但论文明确表示“它对散焦模糊和线性运动模糊都有效”,这意味着它在特定检测运动模糊方面并没有太大用处... - Josh Bleecher Snyder
1
@JoshBleecherSnyder,失焦模糊不具有方向性,而线性运动模糊则具有。您可以运行主成分分析来获取模糊特征边缘点方向向量的特征值,并评估主导方向的强度。如果超过一定阈值,则可以得出结论:该模糊是有方向性的,因此是线性运动模糊。 - luvieere

2
有多种方法可以实现这一点,也许在这里有一位图像大师有更好的答案。无论如何...
我的第一个想法是对图像进行频率分析(即:2D傅里叶变换)。然后为高频(即从一个像素到下一个像素的快速变化)定义阈值以获得真/假值。运动模糊会过滤掉高频。你的结果可能会有所不同,例如完全黑色的图片将没有高频,尽管它并没有模糊。根据使用的镜头和光圈,图像的某些部分可能因为处于背景中而模糊。我认为这里没有一种通用的解决方案。

这将如何区分Bokeh模糊和运动模糊? - Josh Bleecher Snyder

1

要检测模糊度,您可以使用拉普拉斯核将灰度图像卷积,并计算方差。聚焦的图像应具有高方差,而模糊的图像应具有较低的方差。以下是执行此操作的代码:

def is_blur(image) :
   """
   This function convolves a grayscale image with
   laplacian kernel and calculates its variance.
   """

   thresold = #Some value you need to decide

   #Laplacian kernel
   laplacian_kernel = np.array([[0,1,0],[1,-4,1],[0,1,0]])
   laplacian_kernel = tf.expand_dims(laplacian_kernel, -1)
   laplacian_kernel = tf.expand_dims(laplacian_kernel, -1)
   laplacian_kernel = tf.cast(laplacian_kernel, tf.float32)

   #Convolving image with laplacian kernel
   new_img = tf.nn.conv2d(image, laplacian_kernel, strides=[1, 1, 1, 1], 
                          padding="SAME")

   #Calculating variance
   img_var = tf.math.reduce_variance(new_img)

   if img_var < thresold :
      return True
   else :
      return False

该函数以灰度图像作为输入,应该是一个4维张量,因为tf.nn.conv2d接受一个4维张量。以下是加载图像的代码:

image_string = tf.io.read_file(ImagePath)
#decoding image
image = tf.image.decode_png(image_string, channels=3)
#Converting image to grayscale
image = tf.image.rgb_to_grayscale(image)
# This will convert to float values in [0, 1]
image = tf.image.convert_image_dtype(image, tf.float32)
#Reshaping image since conv2d accepts a 4-d tensor.
image = tf.reshape(image, shape=[1, image.shape[0], image.shape[1], 1])

阈值应该设置得非常小心。如果设置得太低,它可能会将模糊的图像声明为聚焦的,如果设置得太高,则会将聚焦的图像误分类为模糊的。更好的方法是计算每个图像的模糊程度,然后通过绘制分布图来决定。希望这有所帮助 :)

0

你也可以使用Richardson-Lucy算法。它主要用于盲反卷积,但是由于你知道需要去除的是运动模糊,所以RL算法应该需要较少的迭代次数来计算可行的重建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接