【问题标题】:Is Laplacian of Gaussian for blob detection or for edge detection?高斯拉普拉斯算子是用于斑点检测还是边缘检测?
【发布时间】:2018-12-26 21:55:03
【问题描述】:

以下代码来自(被要求删除链接)。但我想知道它到底是如何工作的。如果这被认为是边缘检测或斑点检测,我很困惑,就像Wikipedia list the Laplacian of Gaussian (LoG) as blob detection

另外,有人可以解释并提供更深入的解释来解释为什么要计算绝对值以及focus_stack() 函数中发生了什么?

#   Compute the gradient map of the image
def doLap(image):

    # YOU SHOULD TUNE THESE VALUES TO SUIT YOUR NEEDS
    kernel_size = 5         # Size of the laplacian window
    blur_size = 5           # How big of a kernal to use for the gaussian blur
                            # Generally, keeping these two values the same or very close works well
                            # Also, odd numbers, please...

    blurred = cv2.GaussianBlur(image, (blur_size,blur_size), 0)
    return cv2.Laplacian(blurred, cv2.CV_64F, ksize=kernel_size)

#
#   This routine finds the points of best focus in all images and produces a merged result...
#
def focus_stack(unimages):
    images = align_images(unimages)

    print "Computing the laplacian of the blurred images"
    laps = []
    for i in range(len(images)):
        print "Lap {}".format(i)
        laps.append(doLap(cv2.cvtColor(images[i],cv2.COLOR_BGR2GRAY)))

    laps = np.asarray(laps)
    print "Shape of array of laplacians = {}".format(laps.shape)

    output = np.zeros(shape=images[0].shape, dtype=images[0].dtype)

    abs_laps = np.absolute(laps)
    maxima = abs_laps.max(axis=0)
    bool_mask = abs_laps == maxima
    mask = bool_mask.astype(np.uint8)
    for i in range(0,len(images)):
        output = cv2.bitwise_not(images[i],output, mask=mask[i])

    return 255-output

【问题讨论】:

    标签: python opencv image-processing computer-vision laplacianofgaussian


    【解决方案1】:

    hkchengrex's answer 相当完整,但我并不完全同意。也许我有点坚持正确的命名法。检测器是在被检测物体的位置产生强烈响应的物体。

    高斯拉普拉斯算子 (LoG) 不是边缘检测器,因为它在 (near*) 边缘处有零交叉。但它可以用来构建边缘检测器。如此构造的边缘检测器是Marr-Hildreth edge detector。因此,它经常被归类为边缘检测器。对我来说,它是一个线检测器

    拉普拉斯是二阶导数之和(Hessian 矩阵的迹)。用 LoG 卷积的图像与用高斯卷积的图像的拉普拉斯算子是一样的:

    img * [ d^2/dx^2 G(x,y) + d^2/dy^2 G(x,y) ] = d^2/dx^2 [ img * G(x,y) ] + d^2/dy^2 [ img * G(x,y) ]
    

    因此,LoG 在图像的极值处产生强烈的响应(二阶导数最大)。这发生在“斑点”的顶部,以及沿着线条的脊部。

    让我们用这个简单的测试图像:

    并将日志应用到它:

    这里,中灰色是值为 0 的像素。可以看出,它在细线和小点上具有强(负)响应。它还在较宽对象的边缘周围具有中等响应(边缘内部为负,外部为正);零交叉点靠近边缘的位置。

    我们可以对该图像进行阈值检测以检测细线和点:

    (对幅度设置阈值会产生相同的结果)。我们可以降低阈值以查看感兴趣的边缘周围发生中等响应:

    获得边缘需要的不仅仅是一个简单的阈值。相比之下,可以对梯度幅度(边缘位置的一阶导数很强)进行阈值化以获得边缘:

    梯度幅度对于检测线没有用,因为它检测的是沿线的两个边缘,而不是线本身。上面的梯度幅度是使用高斯导数计算的(Sobel 是另一种选择,但没有那么精确)。

    请注意,Canny edge detector 是基于梯度幅度的,它添加了非极大值抑制和滞后阈值处理,以使检测变得细而有意义。


    * 二阶导数在拐点处有一个零交叉点(可以作为边缘的真实位置)。然而,拉普拉斯算子是二阶导数之和。如果考虑梯度方向的二阶导数,它的零交叉点将很好地定位。但是现在在垂直方向(沿边缘)添加二阶导数。该二阶导数沿直边为零,沿凸弯曲边缘(例如圆的边缘)为负,沿凹弯曲边缘为正。因此,将这两个值相加将导致零交叉在弯曲边缘上移动,曲率越强,零交叉就越偏离其真实位置。

    【讨论】:

    • 非常感谢。我有一个简单的问题......你是说上面的代码构造了一个 Marr-Hildreth 边缘检测器吗?
    • @john:不,它不构造 Marr-Hildreth 边缘检测器。 hkcgengrex 已经回答了关于代码作用的部分问题,我觉得没有必要重复。您可能应该接受该答案。我的回答只是为了澄清“边缘检测器”的含义,并提供有关 LoG 的更多信息。基本上我只回答标题中的问题。 :)
    • 感谢克里斯的所有帮助。
    【解决方案2】:

    编辑:Cris Luengo 是对的。忽略边缘检测部分。


    高斯拉普拉斯算子(LoG)可用作边缘检测器和斑点检测器。我将跳过详细的数学和基本原理,我想你可以在书或一些网站上阅读它们hereherehere

    要了解为什么它可以同时使用,让我们看看它的情节和内核。

    如果您有一个半径为 3 且值 1 以内核为中心的斑点,并且背景的值为 0,您将获得非常强烈(负面)的响应。很清楚为什么如果半径设置得当它可以进行斑点检测。

    边缘检测呢?好吧,它不像 Sobel 算子,它为您提供梯度和对边缘的强烈响应。 Sobel 算子不会为您提供准确的边缘,因为梯度通常会在几个像素上上升和下降。您的边缘将是几个像素宽。为了使其定位更准确,我们可以在局部找到具有最大(或最小)梯度的像素。这意味着它的二阶导数(拉普拉斯算子)应该等于 0,或者在该点处有一个过零。

    您可以看到处理后的图像既有明带又有暗带。过零是边缘。要在内核中看到这一点,请尝试手动在内核上滑动一个完美的步进边缘以查看响应如何变化。

    对于你的第二个问题,我想绝对是试图找到浅色和深色斑点(浅色斑点,深色背景;深色斑点,浅色背景),因为它们分别给出强烈的负面和强烈的正面回应。然后它在每个像素位置找到所有图像的最大值。对于每个输出像素,它使用图像上具有最大响应的像素作为输出。我认为他的理由是具有强烈冲动(小斑点)的像素是焦点。

    他正在使用 bitwise_not 作为复制机制。它将掩码指定的一些像素设置为源图像的按位非。最后,您将拥有 output 由来自不同来源的像素组成,除了所有这些像素都没有按位进行。要恢复真实图像,只需再次“不”它们,如NOT(NOT(x)) = x255-xdoes exactly that。我认为copyTo 也可以,不知道他为什么选择其他方式。

    图片取自http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html

    【讨论】:

    • 我不是故意让你删掉一半的答案......除了你可以称之为“边缘检测器”的命名法之外,这一切技术上都是正确的。删除该部分后,我不再对投票感到矛盾。 :)
    • 非常感谢。我对代码有个疑问:为什么最后一行代码返回255-输出?
    • @hkchengrex 非常感谢。您能否解释一下我将如何使用 copyTo 功能?我在 [这里] (stackoverflow.com/questions/51448049/…) 就这个话题提出了另一个问题。
    猜你喜欢
    • 2014-03-29
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多