实现log Gabor滤波器组
·
问题:实现log Gabor滤波器组
我正在阅读这篇论文"Self-Invertible 2D Log-Gabor Wavelets"它定义了 2D log gabor 滤波器,如下所示:


该论文还指出,滤波器仅覆盖频率空间的一侧,并表明在此图像中

在我尝试实现过滤器时,我得到的结果与论文中所说的不匹配。让我从我的实现开始,然后我会陈述问题。
执行:
- 我创建了一个包含滤波器的二维数组,并转换了每个索引,使频域的原点位于数组的中心,正 x 轴向右,正 y 轴向上。
number_scales u003d 5 # 比例分辨率
number_orientations u003d 9 # 方向分辨率
N u003d constantDim # 图像尺寸
def getLogGaborKernal(比例,角度,logfunu003dmath.log2,norm u003d True):
# 设置过滤器配置
center_scale u003d logfun(N) - 比例
center_angle u003d ((np.pi/number_orientations) * 角度) if (scale % 2) \
否则((np.pi/number_orientations)*(角度+0.5))
scale_bandwidth u003d 0.996 * math.sqrt(2/3)
角度带宽 u003d 0.996 * (1/math.sqrt(2)) * (np.pi/number_orientations)
# 保存过滤器的二维数组
内核 u003d np.zeros((N, N))
# 获取二维数组的中心,这样我们就可以移动原点
中间 u003d math.ceil((N/2)+0.1)-1
# 计算过滤器
对于范围内的 x(0,constantDim):
对于范围内的 y(0,constantDim):
# 得到原点在中心的变换后的 x 和 y
# 正 x 轴向右,正 y 轴向上
x_t, y_t u003d (x-中间),-(y-中间)
# 计算给定索引处的过滤器值
内核[y,x] u003d logGaborValue(x_t,y_t,center_scale,center_angle,
scale_bandwidth, angle_bandwidth,logfun)
# 归一化滤波器能量
如果规范:
内核 u003d 内核 / np.sum(内核**2)
返回内核
2.为了计算每个索引处的过滤器值,我们在对数极坐标空间进行另一个变换
def logGaborValue(x,y,center_scale,center_angle,scale_bandwidth,
角度带宽,logfun):
# 转换为极坐标
原始的,theta u003d getPolar(x,y)
# 如果我们在中心,在日志空间中返回 0
# 零未定义
如果原始 u003du003d 0:
返回 0
# 记录极坐标
原始u003d logfun(原始)
# 计算 (theta-center_theta),我们计算 cos(theta-center_theta)
# 和 sin(theta-center_theta) 然后使用 atan 得到所需的值,
# 这样我们就可以消除角距离环绕问题
复杂的,复杂的 u003d math.cos(theta), math.sin(theta)
ds u003d sintheta * math.cos(center_angle) - costheta * math.sin(center_angle)
dc u003d costheta * math.cos(center_angle) + sintheta * math.sin(center_angle)
dtheta u003d math.atan2(ds,dc)
# 最终值,将径向分量乘以角度分量
返回 math.exp(-0.5 * ((raw-center_scale) / scale_bandwidth)**2) * \
math.exp(-0.5 * (d'theta/角度带宽)**2)
问题:
- 角度: 论文指出,从 1->8 索引角度会产生良好的方向覆盖,但在我的实现中,从 1->n 的角度除了半个方向外不覆盖。即使是垂直方向也没有正确覆盖。这可以在此图中显示,其中包含比例为 3 的过滤器集和从 1->8 的方向:

- **覆盖范围:**从上面的过滤器可以看出,过滤器覆盖了空间的两侧,这不是纸上说的。这可以通过使用从 -4 -> 4 的 9 个方向更明确。下图包含一张图像中的所有过滤器,以显示它如何覆盖光谱的两侧(此图像是通过在每个位置取最大值创建的来自所有过滤器):

- Middle Column (orientation $\pi / 2$): 在第一个图中方向从 3 -> 8 可以看出过滤器在方向 $ \pi / 2$ 处消失。这是正常的吗?当我将所有过滤器(所有 5 个比例和 9 个方向)组合在一张图像中时,也可以看到这一点:

更新: 在空间域中添加滤波器的脉冲响应,如您所见,在 -4 和 4 方向上有明显的失真:

解答
经过大量代码分析,我发现我的实现是正确的,但是getPolar函数搞砸了,所以上面的代码应该可以正常工作。这是一个没有getPolar函数的新代码,如果有人正在寻找它:
number_scales = 5 # scale resolution
number_orientations = 8 # orientation resolution
N = 128 # image dimensions
def getFilter(f_0, theta_0):
# filter configuration
scale_bandwidth = 0.996 * math.sqrt(2/3)
angle_bandwidth = 0.996 * (1/math.sqrt(2)) * (np.pi/number_orientations)
# x,y grid
extent = np.arange(-N/2, N/2 + N%2)
x, y = np.meshgrid(extent,extent)
mid = int(N/2)
## orientation component ##
theta = np.arctan2(y,x)
center_angle = ((np.pi/number_orientations) * theta_0) if (f_0 % 2) \
else ((np.pi/number_orientations) * (theta_0+0.5))
# calculate (theta-center_theta), we calculate cos(theta-center_theta)
# and sin(theta-center_theta) then use atan to get the required value,
# this way we can eliminate the angular distance wrap around problem
costheta = np.cos(theta)
sintheta = np.sin(theta)
ds = sintheta * math.cos(center_angle) - costheta * math.sin(center_angle)
dc = costheta * math.cos(center_angle) + sintheta * math.sin(center_angle)
dtheta = np.arctan2(ds,dc)
orientation_component = np.exp(-0.5 * (dtheta/angle_bandwidth)**2)
## frequency componenet ##
# go to polar space
raw = np.sqrt(x**2+y**2)
# set origin to 1 as in the log space zero is not defined
raw[mid,mid] = 1
# go to log space
raw = np.log2(raw)
center_scale = math.log2(N) - f_0
draw = raw-center_scale
frequency_component = np.exp(-0.5 * (draw/ scale_bandwidth)**2)
# reset origin to zero (not needed as it is already 0?)
frequency_component[mid,mid] = 0
return frequency_component * orientation_component
更多推荐

所有评论(0)