计算图像方差的理论是什么?

13

我正试图使用LaplacianFilter计算图像的模糊程度。

根据这篇文章:https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/,我需要计算输出图像的方差。问题在于,我不理解如何概念化地计算图像的方差。

每个像素对于每个颜色通道有4个值,因此我可以计算每个通道的方差,但是那样我会得到4个值,或者通过计算协方差矩阵得到16个值,但是按照OpenCV示例,他们只有一个数字。

计算完那个数字之后,他们只是玩弄阈值以进行二进制决策,即图像是否模糊。

PS. 我绝不是这个主题的专家,因此我的声明可能毫无意义。如果是,请友善地编辑问题。


1
他们只是通过调整阈值来做出二元决策。确实如此。无法声明图像是否聚焦。例如,正如您在此处计算的那样,方差取决于场景中有多少边缘。唯一能做的就是比较同一场景的不同焦深度的图像,并确定哪个最清晰(具有最高方差)。 - Cris Luengo
2个回答

18

模糊图像的边缘被平滑处理,因此方差小。


1. 如何计算方差。

这篇文章的核心函数是:

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

由于Opencv-Python使用numpy.ndarray来表示图像,因此我们查看numpy.var

Help on function var in module numpy.core.fromnumeric:

var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<class 'numpy._globals$
    Compute the variance along the specified axis.

    Returns the variance of the array elements, a measure of the spread of a distribution.
    The variance is computed for the flattened array by default, otherwise over the specified axis.

2. 用于图片

也就是说,计算的变量是在平坦化的拉普拉斯图像或者一维数组上进行的。

计算数组x的方差,公式为:

var = mean(abs(x - x.mean())**2)


例如:

>>> x = np.array([[1, 2], [3, 4]])
>>> x.var()
1.25
>>> np.mean(np.abs(x - x.mean())**2)
1.25

对于拉普拉斯图像,它是一个边缘图像。使用不同的r值制作具有GaussianBlur效果的图像,然后在它们上面执行laplacian filter,并计算变量:

enter image description here

模糊图像的边缘会被平滑处理,因此方差很小。


15
首先,如果你看过你提供的教程,它们将图像转换为灰度,这样它就只有1个通道和1个方差。您可以为每个通道执行此操作,并尝试使用更复杂的公式计算,或者仅使用所有数字的方差...但是我认为作者也将其转换为灰度,因为这是一种将信息融合在一起的好方法,而且作者提供的论文之一实际上说:

预期一个聚焦良好的图像在灰度级别上具有高变化。

教程的作者实际上用简单的方式解释了这一点。首先,想一想Laplacian滤波器的作用。它将显示定义良好的边缘,以下是使用他拥有的图片网格示例。(点击以查看更好的细节)

enter image description here

正如您所看到的,模糊的图像几乎没有任何边缘,而清晰的图像有很多响应。现在,如果你计算方差会发生什么。让我们想象白色是255,黑色是0的情况。如果一切都是黑色...那么方差很小(模糊图像的情况),但是如果它们的一半是白色,一半是黑色,那么方差就很大。

然而,正如作者已经提到的,这个阈值取决于领域,如果您拍摄了一张天空的照片,即使它是清晰的,它可能具有较低的方差,因为它相当相似,没有非常明确定义的边缘...

希望这回答了你的疑问 :)


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