【问题标题】:How can I create a custom band-pass filter?如何创建自定义带通滤波器?
【发布时间】:2016-10-12 16:01:33
【问题描述】:

this research paper,在第 4.1 节(预处理)中,给出了带通滤波器的方程:

在哪里,

现在,我已经实现了如下:

https://dotnetfiddle.net/ZhucE2

但是,这段代码什么也没产生。

【问题讨论】:

  • 滤波器是频域的,但Mat obj 通常将图像保存在非频域中。您必须获取图像的 2D fft,将图像与过滤器相乘,然后逆 2D fft 以将图像恢复为空间坐标。
  • 您需要更详细的信息吗?
  • 然后您可以直接使用过滤器函数计算一个二维数组,其中包含每个频率坐标组合的过滤器值。
  • 同意@Trilarion。这是在我的实现中完成的:for u in range(0, size[0]): for v in range(0, size[1]): kernel[u][v] = K.H_Function(Dh, Dv, u, v, centerX, centerY, theta, n)
  • @Adrian Dh 一个 Dv 设置频率,您要提取该频率。 Theta 设置方向。这背后有一些直觉。在文章的第 4.1 节中,他们使用过滤器来提取图像上的线条,这就是为什么内核也看起来像一条线,因此与图像的标量乘法将在一条线上的点处产生高响应。在空间域中 Dh 和 Dv 设置这条线的宽度(大宽度 - 较低频率)。并且内核的 theta 应该与图像上检测到的线的角度相匹配。

标签: image-processing filter


【解决方案1】:

您需要创建内核映像,然后将其与您的映像进行卷积。 fft 用于优化大图像的卷积。你可以使用 filter2D 函数让 opencv 为你做所有事情。

内核镜像:

图片来源:

应用卷积:

阈值:

请看下面的代码:

import cv2
import math
import numpy as np

class Kernel(object):
    def H_Function(self, Dh, Dv, u, v, centerX, centerY, theta, n):
        return 1 / (1 + 0.414 * math.sqrt(math.pow(self.U_Star(u, centerX, centerY, theta) / Dh + self.V_Star(v, centerX, centerY, theta) / Dv, 2 * n)))

    def U_Star(self, u, centerX, centerY, theta):
        return math.cos(theta) * (u + self.Tx(centerX, theta)) + math.sin(theta) * (u + self.Ty(centerY, theta))

    def V_Star(self, u, centerX, centerY, theta):
        return (-math.sin(theta)) * (u + self.Tx(centerX, theta)) + math.cos(theta) * (u + self.Ty(centerY, theta))

    def Tx(self, center, theta):
        return center * math.cos(theta)

    def Ty(self, center, theta):
        return center * math.sin(theta)

K = Kernel()

size = 40, 40
kernel = np.zeros(size, dtype=np.float)
Dh=2
Dv=2
centerX = -size[0] / 2
centerY = -size[1] / 2
theta=0.9
n=4

for u in range(0, size[0]):
    for v in range(0, size[1]):
        kernel[u][v] = K.H_Function(Dh, Dv, u, v, centerX, centerY, theta, n) 
kernelNorm = np.copy(kernel)
cv2.normalize(kernel, kernel, 1.0, 0, cv2.NORM_L1)
cv2.normalize(kernelNorm, kernelNorm, 0, 255, cv2.NORM_MINMAX)
cv2.imwrite("kernel.jpg", kernelNorm)

imgSrc = cv2.imread('src.jpg',0)

convolved = cv2.filter2D(imgSrc,-1,kernel)
cv2.normalize(convolved, convolved, 0, 255, cv2.NORM_MINMAX)
cv2.imwrite("conv.jpg", convolved)
th, thresholded = cv2.threshold(convolved, 100, 255, cv2.THRESH_BINARY)
cv2.imwrite("thresh.jpg", thresholded)

【讨论】:

  • 这个解决方案有什么问题?
  • @anonymous 所以你不关心过滤器的可视化或任何中间步骤?
  • @Adrian 如果你认为可视化有问题,你能解释一下吗?
  • @taarraas 我并不是说你的回答不好。我没有足够的 Python 经验来观察您的代码并确定其正确性。
  • @Adrian 你说的模拟形式是什么意思? PC不直接处理模拟形式的信号,它将模拟信号转换为数字形式进行处理。内核和输入图像都是数字的和离散的。
【解决方案2】:

实际上没有必要将过滤器存储在数组中。您可以对评估 FFT 的值的 u, v 分量执行双循环,计算每对的滤波器响应 H(u, v) 并将其乘以相应的数组元素。对修改后的数组进行逆变换后,得到过滤后的图像。

【讨论】:

  • @anonymous:对不起,我不是免费的编码服务。
  • 我想知道你有什么困扰。采用 FFT 是一个简单的函数调用。立即将数组元素乘以 H(u, v) 的求值。采用逆 FFT 也是一个函数调用。那又怎样?
猜你喜欢
  • 2014-12-30
  • 2015-07-10
  • 2018-06-14
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 2015-03-05
  • 2019-04-09
相关资源
最近更新 更多