如何将Gabor滤镜应用于具有六边形采样的图像?

时间:2019-03-06 01:05:04

标签: python image-processing gabor-filter

在将正方形采样的图像转换为六边形采样的图像之后,我想使用Gabor滤波器作为插值方法。

我可以在六边形采样的图像中使用普通的Gabor滤波器实现吗?还是应该修改代码?如果是,那么我应该为六角形采样的图像修改Gabor函数的哪一部分?

我尝试实现该算法,但是我做对了。 这是用于Gabor过滤taken from GitHub的代码。

dist

1 个答案:

答案 0 :(得分:0)

假定六边形网格的普通数据结构,您可能可以对六边形像素图像应用2d滤镜,但是您需要创建一个在适当坐标处求值的滤镜。您会看到,二维过滤器只是通过对网格中xy坐标上的函数求值而生成的值的矩阵。因此,一个5x5的Gabor滤波器矩阵只是在如下所示的xy坐标处评估的Gabor函数:

enter image description here

像素是“等间距”的,因此我们可以简单地选择网格中每个点之间的距离,以x为1,以y为1,我们得到在 center 处评估的Gabor函数。每个像素。

但是,六边形像素不是这样排列的。六角形像素的中心排列如下:

enter image description here

因此,为了对此应用过滤器,我们需要在这些点上评估适当的功能。由于股票过滤器是在矩形网格上进行评估的,因此我们无法使用它们(尽管它们会产生看起来合理的东西)。

幸运的是,转换相对容易。如果我们假设两行之间的垂直距离为1,则坐标几乎仅为np.arange

import numpy as np
import matplotlib.pyplot as plt

ALTERNATE_ROW_SHIFT = 0+np.sqrt(3)/3 # every other row is "offset" by half a hexagon.  If the sides are len 2/3, the shift is root 3 over 3

def hex_grid(rect_grid):
    rect_grid = np.copy(rect_grid)
    rect_grid[0,:,1::2] += ALTERNATE_ROW_SHIFT
    return rect_grid

如果您有权访问创建过滤器的函数,通常会有一些逻辑可以创建一个矩形网格,然后在该网格上对该函数进行评估。将hex_grid函数放到后面的行中,以获取六角形间隔的坐标。

例如,the wikipedia page on Gabor filters具有用于创建Gabor过滤器的python实现,如下所示:

def gabor_fn(sigma, theta, Lambda, psi, gamma):
    sigma_x = sigma
    sigma_y = float(sigma) / gamma

    # Bounding box
    nstds = 3 # Number of standard deviation sigma
    xmax = max(abs(nstds * sigma_x * np.cos(theta)), abs(nstds * sigma_y * np.sin(theta)))
    xmax = np.ceil(max(1, xmax))
    ymax = max(abs(nstds * sigma_x * np.sin(theta)), abs(nstds * sigma_y * np.cos(theta)))
    ymax = np.ceil(max(1, ymax))
    xmin = -xmax
    ymin = -ymax

    (y,x) = np.meshgrid(np.arange(ymin, ymax + 1), np.arange(xmin, xmax + 1))

    # Rotation 
    x_theta = x * np.cos(theta) + y * np.sin(theta)
    y_theta = -x * np.sin(theta) + y * np.cos(theta)

    gb = np.exp(-.5 * (x_theta ** 2 / sigma_x ** 2 + y_theta ** 2 / sigma_y ** 2)) * np.cos(2 * np.pi / Lambda * x_theta + psi)
    return gb

请注意涉及np.meshgrid的行。这将创建一个间距为1的矩形网格,该网格将用于后续的行。我们可以简单地转换这些坐标以创建一个新的hex_gabor函数(请注意,这与gabor_fn代码具有95%的相同性):

def hex_gabor_fn(sigma, theta, Lambda, psi, gamma):
    sigma_x = sigma
    sigma_y = float(sigma) / gamma

    # Bounding box
    nstds = 3 # Number of standard deviation sigma
    xmax = max(abs(nstds * sigma_x * np.cos(theta)), abs(nstds * sigma_y * np.sin(theta)))
    xmax = np.ceil(max(1, xmax))
    ymax = max(abs(nstds * sigma_x * np.sin(theta)), abs(nstds * sigma_y * np.cos(theta)))
    ymax = np.ceil(max(1, ymax))
    xmin = -xmax
    ymin = -ymax

    yx = np.meshgrid(np.arange(ymin, ymax + 1), np.arange(xmin, xmax + 1))
    (y,x) = hex_grid(yx)

    # Rotation 
    x_theta = x * np.cos(theta) + y * np.sin(theta)
    y_theta = -x * np.sin(theta) + y * np.cos(theta)

    gb = np.exp(-.5 * (x_theta ** 2 / sigma_x ** 2 + y_theta ** 2 / sigma_y ** 2)) * np.cos(2 * np.pi / Lambda * x_theta + psi)
    return gb

if __name__ == "__main__":
    g = gabor_fn(4,np.pi/4,4,0,2)
    hg = hex_gabor_fn(4,np.pi/4,4,0,2)
    plt.imshow(g)
    plt.show()
    plt.imshow(hg)
    plt.show() 

您应该能够将生成的内核放入此行cv2.filter2D(img, cv2.CV_8UC3, g_kernel)