频域边缘检测
Edge Detection in Frequency Domain
如何应用滤波器来检测频域中的边缘?我已将离散余弦变换应用于输入图像。
我不知道如何应用过滤器来检测边缘。谁能帮忙检测一下边缘?
为此有多种方法,我要特别提到的一种方法是 concentration factor method 用于检测频谱信号中的边缘。
但是,这些方法通常用于连续频率信号,没有理由在图像上使用它。它比基于卷积核的方法慢,例如用于 Canny 边缘检测的 Sobel 滤波器,并且文献更专门用于 仅 给出基于频率的信息的领域,例如雷达或 MRI 的重建信号。
图像包含 局部 信息,例如特征(例如边缘)所在的位置。光谱表示提供 全局 信息,例如图像中某些图案重复的频率。从全局模式重建局部信息在某些领域是必要的,但当您已经拥有局部数据(即图像)时根本没有必要使用。换句话说,您基本上是通过先变换图像来丢弃信息。
无论哪种方式,要在频域中应用滤波器,您只需乘以傅立叶系数(变换图像的值)即可。例如,假设您对波数从 0 开始递增的向量中的信号进行傅立叶变换,即向量 [f0, f1, ..., fn-1]
,其中每个 fi
是第 i
个傅立叶系数。高通滤波器是一种让高频通过并滤除低频的滤波器。因此,如果您想象这个相同的矢量但现在相乘以抑制较低的频率,它可能看起来像 [f0/10000, f1/1000, f2/100, f3/10, f4]
。如果你简单地用这些傅里叶系数逆变换回图像space,你将抑制图像中的较低频率。
同样的想法适用于任何低通、带通、高通等滤波器。您只需将傅立叶系数乘以某个比例,或者取一些 window 的傅立叶系数并忽略或缩放其余部分。您可以尝试使用线性缩放、对数缩放或仅使用架子,然后查看图像中的差异。
例如在带有 Python 的 OpenCV 中,这段代码是最小的并且展示了这个想法。图片如下:
>>> import numpy as np
>>> import cv2
>>> img = np.zeros((8, 8), dtype=np.float32)
>>> img[2:6, 2:6] = 1
>>> img
array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)
所以它只是一张中间有白色方块的黑色图像。如果你想检测边缘,基本的基本方法是高通滤波器。所以你可以进行傅立叶变换或DCT,然后去除低频(大多数库计算DCT的方式,中心值是低频,越接近DCT图像边界的值越高频率---OpenCV也是如此,所以我们只需将DCT中心的值设置为零)
>>> dct_coeff = cv2.dct(img)
>>> dct_coeff[2:6, 2:6] = 0
剩下要做的就是进行逆变换和阈值以查看边缘位置:
>>> hp_img = cv2.idct(dct_coeff)
>>> hp_img > 0.75
array([[False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False],
[False, False, True, True, True, True, False, False],
[False, False, True, False, False, True, False, False],
[False, False, True, False, False, True, False, False],
[False, False, True, True, True, True, False, False],
[False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False]], dtype=bool)
现在,这是一种非常基本的方法,噪声会迅速扼杀高通滤波方法(因为噪声通常是高频的)。这就是您需要转向高级方法的时候,例如浓度因子。但即便如此,与 Canny/Sobel 边缘检测的强大功能和简单性相比,这种方法在图像上的使用并不是特别有用。
如何应用滤波器来检测频域中的边缘?我已将离散余弦变换应用于输入图像。
我不知道如何应用过滤器来检测边缘。谁能帮忙检测一下边缘?
为此有多种方法,我要特别提到的一种方法是 concentration factor method 用于检测频谱信号中的边缘。
但是,这些方法通常用于连续频率信号,没有理由在图像上使用它。它比基于卷积核的方法慢,例如用于 Canny 边缘检测的 Sobel 滤波器,并且文献更专门用于 仅 给出基于频率的信息的领域,例如雷达或 MRI 的重建信号。
图像包含 局部 信息,例如特征(例如边缘)所在的位置。光谱表示提供 全局 信息,例如图像中某些图案重复的频率。从全局模式重建局部信息在某些领域是必要的,但当您已经拥有局部数据(即图像)时根本没有必要使用。换句话说,您基本上是通过先变换图像来丢弃信息。
无论哪种方式,要在频域中应用滤波器,您只需乘以傅立叶系数(变换图像的值)即可。例如,假设您对波数从 0 开始递增的向量中的信号进行傅立叶变换,即向量 [f0, f1, ..., fn-1]
,其中每个 fi
是第 i
个傅立叶系数。高通滤波器是一种让高频通过并滤除低频的滤波器。因此,如果您想象这个相同的矢量但现在相乘以抑制较低的频率,它可能看起来像 [f0/10000, f1/1000, f2/100, f3/10, f4]
。如果你简单地用这些傅里叶系数逆变换回图像space,你将抑制图像中的较低频率。
同样的想法适用于任何低通、带通、高通等滤波器。您只需将傅立叶系数乘以某个比例,或者取一些 window 的傅立叶系数并忽略或缩放其余部分。您可以尝试使用线性缩放、对数缩放或仅使用架子,然后查看图像中的差异。
例如在带有 Python 的 OpenCV 中,这段代码是最小的并且展示了这个想法。图片如下:
>>> import numpy as np
>>> import cv2
>>> img = np.zeros((8, 8), dtype=np.float32)
>>> img[2:6, 2:6] = 1
>>> img
array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)
所以它只是一张中间有白色方块的黑色图像。如果你想检测边缘,基本的基本方法是高通滤波器。所以你可以进行傅立叶变换或DCT,然后去除低频(大多数库计算DCT的方式,中心值是低频,越接近DCT图像边界的值越高频率---OpenCV也是如此,所以我们只需将DCT中心的值设置为零)
>>> dct_coeff = cv2.dct(img)
>>> dct_coeff[2:6, 2:6] = 0
剩下要做的就是进行逆变换和阈值以查看边缘位置:
>>> hp_img = cv2.idct(dct_coeff)
>>> hp_img > 0.75
array([[False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False],
[False, False, True, True, True, True, False, False],
[False, False, True, False, False, True, False, False],
[False, False, True, False, False, True, False, False],
[False, False, True, True, True, True, False, False],
[False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False]], dtype=bool)
现在,这是一种非常基本的方法,噪声会迅速扼杀高通滤波方法(因为噪声通常是高频的)。这就是您需要转向高级方法的时候,例如浓度因子。但即便如此,与 Canny/Sobel 边缘检测的强大功能和简单性相比,这种方法在图像上的使用并不是特别有用。