Gabor 滤波
2023-03-07 09:43:54 时间
Gabor 变换是一种短时加窗Fourier变换,本文记录相关内容。
简介
- Fourier 变换是一种信号处理的有力工具,可以将图像从空域转换到频域,并提取到空域上不易提取到的特征。但是Fourier变换缺乏时间和位置的局部信息。
- Gabor 变换是一种短时加窗Fourier变换(简单理解起来就是在特定时间窗内做Fourier变换),是短时傅里叶变换中窗函数取为高斯函数时的一种特殊情况。因此,Gabor滤波器可以在频域上不同尺度、不同方向上提取相关的特征。另外,Gabor函数与人眼的作用相仿,所以经常用作纹理识别上,并取得了较好的效果。
- 在二维空间中,使用一个三角函数(a)(如正弦函数)与一个高斯函数(b)叠加,我们得到了一个Gabor滤波器©。
Gabor 滤波
公式定义
- 复数表示
- 实部
- 虚部
- 其中
https://developer-public-1258344699.cos.ap-guangzhou.myqcloud.com/column/column/10335061/20230218-68017941.png
- 其余参数
参数 | 简介 | 含义 |
---|---|---|
$\lambda$ | 波长 | 表示正弦因子的波长,它的值以像素为单位制定,通常大于等于2,但不能大于输入图像尺寸的1/5. |
$\theta$ | 方向 | 表示法线到 Gabor 函数的平行条纹的方向 |
$\phi$ | 相位偏移 | 相位偏移 |
$\sigma$ | 标准差 | 高斯分布的标准差 |
$\gamma$ | 长宽比 | 空间纵横比,指定 Gabor 函数支持的椭圆度 |
提取图像特征
- 一组具有不同频率和方向的 Gabor 滤波器可能有助于从图像中提取有用的特征。
- 在离散域中,二维 Gabor 滤波器表示为:
https://developer-public-1258344699.cos.ap-guangzhou.myqcloud.com/column/column/10335061/20230218-09de0c8d.png
其中 B 和 C 是要确定的标准化因子。
- 二维 Gabor 滤波器在图像处理中有着广泛的应用,特别是在纹理分析和分割的特征提取方面。
- 参数说明
参数 | 含义 |
---|---|
$f$ | 定义在纹理中查找的频率。 |
$ \theta$ | 查找纹理的方向 |
$\sigma$ | 标准差,可以调整被分析图像区域的尺寸 |
应用示例
Python 实现
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Gabor 滤波器实现
# K_size:Gabor核大小 K_size x K_size
# Sigma : σ
# Gamma: γ
# Lambda:λ
# Psi : ψ
# angle: θ
defGabor_filter(K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=0):
# get half size
d = K_size // 2
# prepare kernel
gabor = np.zeros((K_size, K_size), dtype=np.float32)
# each value
for y inrange(K_size):
for x inrange(K_size):
# distance from center
px = x - d
py = y - d
# degree -> radian
theta = angle / 180. * np.pi
# get kernel x
_x = np.cos(theta) * px + np.sin(theta) * py
# get kernel y
_y = -np.sin(theta) * px + np.cos(theta) * py
# fill kernel
gabor[y, x] = np.exp(-(_x**2 + Gamma**2 * _y**2) / (2 * Sigma**2)) * np.cos(2*np.pi*_x/Lambda + Psi)
# kernel normalization
gabor /= np.sum(np.abs(gabor))
return gabor
# define each angle
As = [0, 45, 90, 135]
# prepare pyplot
plt.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0.2)
# each angle
for i, A inenumerate(As):
# get gabor kernel
gabor = Gabor_filter(K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=A)
# normalize to [0, 255]
out = gabor - np.min(gabor)
out /= np.max(out)
out *= 255
out = out.astype(np.uint8)
plt.subplot(1, 4, i+1)
plt.imshow(out, cmap='gray')
plt.axis('off')
plt.title("Angle "+str(A))
plt.savefig("out.png")
plt.show()
- 图像输出
OpenCV 实现
- 在 OpenCV 中实现了 Gabor 滤波
函数定义
- 官方文档
- 函数使用:
cv.getGaborKernel( ksize, sigma, theta, lambd, gamma[, psi[, ktype]] ) -> retval
- 参数含义:
参数 | 含义 |
---|---|
ksize | 返回的筛选器大小。 |
sigma | 高斯分布标准差。 |
theta | Gabor 函数法向平行条纹的方向。 |
lambd | 正弦因子波长。 |
gamma | 空间长宽比,表示椭圆形状。 |
psi | 相位偏移。 |
ktype | 滤波器系数的类型。它可以是 CV_32F 或 CV_64F。 |
- OpenCV 中
getGaborKernel
函数的代码实现如下:
cv::Mat cv::getGaborKernel( Size ksize, double sigma, double theta,
double lambd, double gamma, double psi, int ktype )
{
double sigma_x = sigma;
double sigma_y = sigma/gamma;
int nstds = 3;
int xmin, xmax, ymin, ymax;
double c = cos(theta), s = sin(theta);
if( ksize.width > 0 )
xmax = ksize.width/2;
else
xmax = cvRound(std::max(fabs(nstds*sigma_x*c), fabs(nstds*sigma_y*s)));
if( ksize.height > 0 )
ymax = ksize.height/2;
else
ymax = cvRound(std::max(fabs(nstds*sigma_x*s), fabs(nstds*sigma_y*c)));
xmin = -xmax;
ymin = -ymax;
CV_Assert( ktype == CV_32F || ktype == CV_64F );
Mat kernel(ymax - ymin + 1, xmax - xmin + 1, ktype);
double scale = 1;
double ex = -0.5/(sigma_x*sigma_x);
double ey = -0.5/(sigma_y*sigma_y);
double cscale = CV_PI*2/lambd;
for( int y = ymin; y <= ymax; y++ )
for( int x = xmin; x <= xmax; x++ )
{
double xr = x*c + y*s;
double yr = -x*s + y*c;
double v = scale*std::exp(ex*xr*xr + ey*yr*yr)*cos(cscale*xr + psi);
if( ktype == CV_32F )
kernel.at<float>(ymax - y, xmax - x) = (float)v;
else
kernel.at<double>(ymax - y, xmax - x) = v;
}
return kernel;
}
特征提取示例
import mtutils as mt
import cv2 as cv
retval = cv.getGaborKernel(ksize=(111,111), sigma=10, theta=60, lambd=10, gamma=1.2)
image1 = mt.cv_rgb_imread('test.jpg')
result = cv.filter2D(image1,-1,retval)
mt.PIS([image1, 'origin image'], [result, 'gabor image'])
- 输出示例
斑马线检测示例
- 测试图像
- 检测代码
需要安装库 mtutils
pip install mtutils
import mtutils as mt
import numpy as np
import cv2 as cv
image = mt.cv_rgb_imread('bmx.jpg', 1)
kernel_size = (5, 5)
sigma = 1
lambd = np.pi / 2
gamma = 0.5
psi = 0
theta_list = [0, np.pi * 0.25, np.pi * 0.5, np.pi * 0.75]
sum_result = np.zeros_like(image, dtype='float32')
kernel_list = list()
result_list = list()
for theta in theta_list:
kernel = cv.getGaborKernel(kernel_size, sigma, theta, lambd, gamma, psi)
kernel_list.append(kernel)
result = cv.filter2D(image, -1, kernel)
result_list.append(result)
sum_result += result
mt.PIS(*kernel_list, row_num=1)
mt.PIS([result_list[0], '0°'], [result_list[1], '45°'], [result_list[2], '90°'], [result_list[3], '135°'], [sum_result, 'fea_sum'], row_num=1, axis_off=True)
dst = cv.convertScaleAbs(sum_result, alpha=0.2, beta=0)
_, thr_res = cv.threshold(dst, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
mt.PIS(255 - thr_res)
pass
- Gabor 核
- 滤波结果
- 检测结果
参考资料
- https://docs.opencv.org/4.5.5/d4/d86/group__imgproc__filter.html#gae84c92d248183bd92fa713ce51cc3599
- https://www.jianshu.com/p/a6d6f344609f
- https://blog.csdn.net/jinshengtao/article/details/17797641
- https://zhuanlan.zhihu.com/p/584907623
- https://xuewenyuan.github.io/posts/2016/05/blog-post-1/
- https://en.wikipedia.org/wiki/Gabor_filter
- https://docs.opencv.org/4.5.5/d4/d86/group__imgproc__filter.html#gae84c92d248183bd92fa713ce51cc3599
- https://cloud.tencent.com/developer/article/1165871
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的