Python中的滑动Gabor滤波器

3 投票
2 回答
4678 浏览
提问于 2025-04-18 10:37

这段内容是关于如何使用gabor滤波器处理图像的一个例子,来自skimage库。计算一个图像的gabor滤波器其实很简单:

import numpy as np

from scipy import ndimage as nd

from skimage import data
from skimage.util import img_as_float
from skimage.filter import gabor_kernel

brick = img_as_float(data.load('brick.png'))

kernel = np.real(gabor_kernel(0.15, theta = 0.5 * np.pi,sigma_x=5, sigma_y=5))

filtered = nd.convolve(brick, kernel, mode='reflect')

mean = filtered.mean()
variance = filtered.var()

这里的“brick”只是一个numpy数组。假设我有一个5000*5000的numpy数组。我想做的是生成两个新的5000*5000的numpy数组,这两个数组中的每个像素值分别是以该像素为中心的15*15窗口内gabor滤波器的平均值和方差。

有没有人能帮我实现这个目标呢?

补充说明

我为什么会被投反对票呢?无论如何,为了更清楚,我展示了如何在单个图像上计算gabor滤波器的例子。我只是想在一个非常大的图像的小方块子集上计算gabor滤波器(所以需要滑动窗口)。

2 个回答

2

如果你只是想计算一张图片的滑动平均值(也就是用一个全是1的方形滤波器进行卷积),那么快速的方法是:

# fsize is the filter size in pixels
# integrate in the X direction
r_sum = numpy.sum(img[:, :fsize], axis=1)
r_diff =  img[:, fsize:] - img[:, :-fsize]
r_int = numpy.cumsum(numpy.hstack((r_sum.reshape(-1,1), r_diff)), axis=1)

# integrate in the Y direction
c_sum = numpy.sum(r_img[:fsize, :], axis=0)
c_diff = r_img[fsize:, :] - r_img[:-fsize, :]
c_int = numpy.cumsum(numpy.vstack((c_sum, c_diff)), axis=0)

# now we have an array of sums, average can be obtained by division
avg_img = c_int / (f_size * f_size)

这个方法会返回一张比原图小1个像素的图片,所以你需要自己处理边缘效果。其实最边上的像素本来就不太好,但如果你需要填充边缘,选择合适的填充方式就得靠你自己了。这个算法是获取平均值的最快方式(计算量最少),特别是比numpy.convolve要快很多。

在计算方差时也可以用类似的技巧,如果同时对图片和它的平方进行上面的平均处理。那么:

npts = fsize * fsize
variance = (rolling_sum(img**2) - rolling_sum(img)/npts) / npts

这里的rolling_sum就是一个滑动求和(也就是上面算法的结果,只不过没有最后的除法)。所以,计算滑动方差只需要两个滑动求和(图片和它的平方)就可以了。

(警告:上面的代码没有经过测试,只是用来说明这个想法。)

2

我不知道有没有标准的方法可以做到这一点,但你可以自己直接实现。

在卷积运算中,每个像素的值是经过移位的Gabor滤波器的值和图像像素值相乘后再相加的结果。也就是说,卷积中的每个像素基本上就是一个平均值,只不过有一个常数的归一化因子,所以filtered基本上就是你的平均值。

方差就稍微复杂一些,因为它是平方和的结果,当然你需要先计算平方,然后再计算总和。不过,你可以通过先对图像和滤波器进行平方处理来轻松实现这一点,也就是说:

N = kernel.shape[0]*kernel.shape[1]
mean = nd.convolve(brick, kernel, mode='reflect')/N
var = nd.convolve(brick*brick, kernel*kernel, mode='reflect')/N - mean*mean

撰写回答