高斯边缘检测器的拉普拉斯效应受掩模尺寸变化的影响

时间:2014-04-11 09:25:34

标签: python image-processing

对于一堂课,我写了Laplacian of Gaussian edge detector,其工作方式如下。

  1. 根据高斯与掩模大小的方差
  2. ,制作高斯掩模的拉普拉斯算子
  3. 将其与图像对照
  4. 以非常粗制滥造的方式找到过零点,这些是图像的边缘
  5. 如果您愿意,可以查看此程序的代码here,但最重要的部分是我创建高斯蒙版的位置,这取决于我为了您的方便而在此处复制的两个函数: / p>

    # Function for calculating the laplacian of the gaussian at a given point and with a given variance
    def l_o_g(x, y, sigma):
        # Formatted this way for readability
        nom = ( (y**2)+(x**2)-2*(sigma**2) )
        denom = ( (2*math.pi*(sigma**6) ))
        expo = math.exp( -((x**2)+(y**2))/(2*(sigma**2)) )
        return nom*expo/denom
    
    
    # Create the laplacian of the gaussian, given a sigma
    # Note the recommended size is 7 according to this website http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm 
    # Experimentally, I've found 6 to be much more reliable for images with clear edges and 4 to be better for images with a lot of little edges
    def create_log(sigma, size = 7):
        w = math.ceil(float(size)*float(sigma))
    
        # If the dimension is an even number, make it uneven
        if(w%2 == 0):
            print "even number detected, incrementing"
            w = w + 1
    
        # Now make the mask
        l_o_g_mask = []
    
        w_range = int(math.floor(w/2))
        print "Going from " + str(-w_range) + " to " + str(w_range)
        for i in range_inc(-w_range, w_range):
            for j in range_inc(-w_range, w_range):
                l_o_g_mask.append(l_o_g(i,j,sigma))
        l_o_g_mask = np.array(l_o_g_mask)
        l_o_g_mask = l_o_g_mask.reshape(w,w)
        return l_o_g_mask
    

    总而言之,它工作得相对较好,即使它非常慢,因为我don't know how to leverage Numpy。但是,每当我改变高斯蒙版的大小时,我检测到的边缘厚度都会发生巨大变化。

    这是运行的图像,其掩码大小相当于高斯的给定方差的4倍: 4 times the variance

    这是相同的图像运行,其掩码大小相当于方差的6倍: 6 times the variance

    我有点困惑,因为size参数应该改变的唯一内容是在开始将其与图像卷积之前,高斯蒙版的拉普拉斯算子的逼近的准确性。所以我跑了a test,我想要在不同尺寸参数的情况下看看我的面具看起来如何。

    这里的大小为4: 4_l_o_g

    这里尺寸为6: 6_l_o_g

    从零交叉(它们碰巧间隔四个像素)和它们的峰值看,函数的形状似乎是相同的。有没有更好的检查方法?

    有关为何可能发生此问题或如何进一步调查的任何建议均表示赞赏。

1 个答案:

答案 0 :(得分:1)

事实证明,关于增加掩模尺寸的效果的概念是错误的。增大尺寸实际上并没有提高近似的质量或功能的分辨率。为了解释,不要像高斯拉普拉斯算子那样使用复杂的二维函数,而是让事情回到一维,并假装我们接近函数f(x) = x^2

现在你计算函数的代码看起来像这样:

def derp(theta, size):
    w = math.ceil(float(size)*float(sigma))

    # If the dimension is an even number, make it uneven
    if(w%2 == 0):
        print "even number detected, incrementing"
        w = w + 1

    # Now make the mask
    x_mask = []

    w_range = int(math.floor(w/2))
    print "Going from " + str(-w_range) + " to " + str(w_range)
    for i in range_inc(-w_range, w_range):
        x_mask = a*i^2

如果你要增加"尺寸"对于这个函数,你不会提高分辨率,而是实际上增加了你所抓取的x值的范围。例如,对于3的大小,您正在评估-1, 0, 1,对于5的大小,您正在评估-2, -1, 0, 1, 2。请注意,这并不会增加像素之间的间距。当你谈到相同数量的像素之间的零交叉时,这就是你实际看到的。

因此,当用这个非常愚蠢的面具卷起时,你会得到截然不同的结果。但是,如果我们回到高斯的拉普拉斯算法呢?

嗯,高斯拉普拉斯的优秀特性就是你越远,你获得的零值就越多。因此,与我们愚蠢的x^2函数不同,您应该在一段时间后得到相同的结果。

现在,我认为您在测试用例中没有看到这一点的原因是因为它们的大小太小,因为您的程序太慢,您无法真正看到size=15size=20,但如果要实际运行这些案例,我认为你会发现图片没有那么大的变化。

这仍然无法回答你应该做的事情,为此,我们必须向专业人士寻求帮助。即,在Scipy(source here)中实现gaussian_filter

当你查看他们的源代码时,你要注意的第一件事是,在创建他们的面具时,他们基本上和你做同样的事情。它们总是使用整数步长,它们通过它的标准偏差来缩放掩码的大小。

至于为什么他们这样做,我无法回答,因为我没有那么深入的图像处理知识或Scipy。但是,这可能会在SO上提出一个很好的新问题。