- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
以下代码来自(被要求删除链接)。但我想知道它到底是如何工作的。如果这被认为是边缘检测或 Blob 检测,我很困惑,因为 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
最佳答案
hkchengrex's answer比较完整,但我不完全同意。也许我有点坚持正确的命名法。检测器是在待检测物体的位置产生强烈响应的东西。
高斯拉普拉斯算子 (LoG) 不是边缘检测器,因为它在(near*)边缘有零交叉。但它可以用来构建边缘检测器。如此构建的边缘检测器是 Marr-Hildreth edge detector .因此,它经常被归类为边缘检测器。对我来说,它是一个线检测器。
拉普拉斯是二阶导数之和(海森矩阵的迹)。用 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 在图像的极值处(二阶导数最大的地方)产生强烈的响应。这发生在“ Blob ”的峰顶,以及沿着线条的脊线。
让我们使用这个简单的测试图像:
并将 LoG 应用于它:
这里,中灰色是值为 0 的像素。可以看出,它沿细线和小点具有强烈(负)响应。它还在较宽物体的边缘周围有中等响应(边缘内为负,边缘外为正);零交叉点靠近边缘。
我们可以对这张图片设置阈值来检测细线和点:
(阈值幅度产生相同的结果)。我们可以降低阈值以查看中等响应发生在感兴趣的边缘周围:
获得边缘需要的不仅仅是一个简单的阈值。相反,可以对梯度大小(一阶导数在边缘位置很强)进行阈值处理以获得边缘:
梯度幅值对于检测线没有用,因为它检测沿线的两个边缘,而不是线本身。上面的梯度大小是使用高斯导数计算的(Sobel 是另一种选择,但不够精确)。
请注意 Canny edge detector基于梯度大小,它添加了非最大抑制和滞后阈值,使检测变得薄而有意义。
* 二阶导数在拐点处有一个零交叉点(可以作为边缘的真实位置)。然而,拉普拉斯算子是二阶导数的总和。如果您考虑梯度方向上的二阶导数,它的零交叉将被很好地定位。但是现在在垂直方向(沿着边缘)添加二阶导数。该二阶导数沿直线为零,沿凸曲线边缘(例如圆的边缘)为负,沿凹曲线边缘为正。因此,将这两个值相加将导致过零点在弯曲边缘上移动,曲率越大,过零点偏离其真实位置的幅度就越大。
关于python - 高斯拉普拉斯算子是用于 Blob 检测还是用于边缘检测?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51411156/
我对Mikolajczyk等人介绍的Harris-Laplacian-Detector有疑问。使用哈里斯(Harris),您可以搜索每个特定刻度内的“拐角”最大值,然后使用拉普拉斯算子(Laplaci
我是一名优秀的程序员,十分优秀!