Python OpenCV实现Log Gabor滤波器(由LGHD描述符扩展)_log-gabor-程序员宅基地

技术标签: python  图像配准  图像处理  模式识别  深度学习  opencv  

引言

笔者在研究红外图像与可见光图像配准时接触到了很多描述符,其中关于LGHD描述符的Log Gabor滤波器很有意思,与大家分享

LGHD(Log-Gabor Histogram Descriptor)

描述符的思想是基于高频分量分布的描述符对于不同的非线性强度变化具有鲁棒性。可以理解为虽然非线性强度差异可以影响图像,但是场景中所包含对象的形状的整体外观仍趋于保持恒定。Log-Gabor 滤波器是根据Gabor滤波器衍生而来,Gabor变换能达到时频局部化的目的,它能够在整体上提供信号的全部信息又能提供在任意局部时间内信号变化剧烈程度的信息。

Log-Gabor滤波器

Log-Gabor 滤波器的表达是从Gabor衍生而来的,相比于Gabor滤波器,它的传递函数是对数频率尺度下的高斯函数,始终没有直流分量,在图像处理时可以不受亮度的影响。
并经研究Log-Gabor函数更符合哺乳动物的视觉观察系统,有更优的纹理提取、目标检测效果。
Log-Gabor的传递函数为:
G ( ω ) = e − log ⁡ ( ω / ω 0 ) 2 / ( 2 ( log ⁡ ( k / ω 0 ) 2 ) ) G(\omega)=e^{-\log(\omega/\omega_0)^2/(2(\log(k/\omega_0)^2))} G(ω)=elog(ω/ω0)2/(2(log(k/ω0)2))
Log-Gabor函数并不能在空间域中得到表达式,滤波器的构造须在频域中。对图像来说,在空域的卷积等价于在频域的乘积,所以我们直接创建与图像大小相同的Log-Gabor滤波器,在频域中完成图像处理,之后再回到空域中进行统计。一个二维的Log-Gabor滤波器可以分解为径向滤波器和角度滤波器两部分,对应极坐标公式为:
Alan_Liang
完整的Log-Gabor滤波器由这两部分相乘得到:
在这里插入图片描述
其中r是经向坐标, θ \theta θ为角度坐标, f 0 , θ 0 f_0,\theta_0 f0,θ0分别为滤波器中心频率和方向角度,参数可 σ r , σ θ \sigma_r,\sigma_\theta σr,σθ分别用于决定滤波器的径向带宽和角度带宽。对提供波长的滤波器,频率由滤波器的波长设置,在不同尺度下,其转换公式为:
在这里插入图片描述
在这里我将6个方向4个尺度的Log-Gabor 滤波器做展示,滤波器与图像的大小相同,一般情况下将图像进行FFT变换后与滤波器对应位相乘,再转换至空域,就是滤波后的图像效果。

构造滤波器

import cv2
import numpy as np
import matplotlib.pyplot as plt


n_scales=4
n_angles=6
img = cv2.imread("img_path")
H,W,_ = ir_img.shape

def lowpassfilter(H, W, cutoff, n):
    if cutoff < 0 or cutoff > 0.5:
        raise ValueError('the cutoff frequency needs to be between 0 and 0.5')

    if not n == int(n) or n < 1.0:
        raise ValueError('n must be an integer >= 1')

    xrange = np.linspace(-0.5, 0.5, W)
    yrange = np.linspace(-0.5, 0.5, H)

    x, y = np.meshgrid(xrange, yrange)
    radius = np.sqrt(x ** 2 + y ** 2)
    radius = np.fft.ifftshift(radius)
    return 1.0 / (1.0 + (radius / cutoff) ** (2 * n))

xrange = np.linspace(-0.5, 0.5, W)
yrange = np.linspace(-0.5, 0.5, H)
x, y = np.meshgrid(xrange, yrange)
radius = np.sqrt(x ** 2 + y ** 2)
theta = np.arctan2(-y, x)

# numpy.fft模块中的fftshift函数可以将FFT输出中的直流分量移动到频谱的中央。ifftshift函数则是其逆操作
radius = np.fft.ifftshift(radius)
theta = np.fft.ifftshift(theta)

sintheta = np.sin(theta)
costheta = np.cos(theta)

lp_filter = lowpassfilter(H, W, 0.45, 15)
# lp_filter = np.fft.ifftshift(lp_filter)
log_gabor_filters = np.zeros((n_scales, H, W))

#  不同尺度
for sc in range(n_scales):
    wavelength = min_wavelength * multiplier ** sc
    log_gabor_filters[sc] = np.exp(
        (-(np.log(radius * wavelength + 1e-5)) ** 2) / (2 * np.log(sigma_onf + 1e-5) ** 2)) * lp_filter

spreads = np.zeros((n_angles, H, W))
#  不同方向
for o in range(n_angles):
    angle = o * np.pi / n_angles
    ds = sintheta * np.cos(angle) - costheta * np.sin(angle)
    dc = costheta * np.cos(angle) + sintheta * np.sin(angle)
    dtheta = abs(np.arctan2(ds, dc))
    dtheta = np.minimum(dtheta * n_angles * 0.5, np.pi)
    spreads[o] = (np.cos(dtheta) + 1) / 2
#  构造集合的filter
filter_bank = np.zeros((n_scales * n_angles, H, W))
for sc in range(n_scales):
    for o in range(n_angles):
        filter_bank[sc * n_angles + o] = log_gabor_filters[sc] * spreads[o]

#  可视化
for sc in range(n_scales):
    plt.figure(sc,figsize=(30,120))
    first = filter_bank[sc * n_angles] - np.min(filter_bank[sc * n_angles])
    first /= np.max(first)
    first *= 255
    shuiping = first
    for o in range(n_angles-1):
        out = filter_bank[sc * n_angles + o+1] - np.min(filter_bank[sc * n_angles + o+1])
        out /= np.max(out)
        out *= 255
        shuiping = np.hstack((shuiping,out))
        plt.imshow(shuiping,cmap="gray")

滤波器可视化

在这里插入图片描述

进行图像测试

原图
在这里插入图片描述

vi_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 图像的傅里叶变换
image_fft = cv2.dft(np.float32(vi_gray), flags=cv2.DFT_COMPLEX_OUTPUT)
eo = np.zeros((filter_bank.shape[0], filter_bank.shape[1], filter_bank.shape[2], 2))
for i, filter in enumerate(filter_bank):
    eo[i] = cv2.idft(np.multiply(np.expand_dims(filter, -1), image_fft))

for sc in range(n_scales):
    plt.figure(sc,figsize=(30,120))
    first = eo_magnitude[n_scales]
    first /= np.max(first)
    first *= 255
    shuiping = first
    for o in range(n_angles-1):
        out = eo_magnitude[sc * n_angles + o+1] - np.min(eo_magnitude[sc * n_angles + o+1])
        out /= np.max(out)
        out *= 255
        shuiping = np.hstack((shuiping,out))
        plt.imshow(shuiping,cmap="gray")

滤波后
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Find_name/article/details/120750375

智能推荐

(前端)工作总结 2_"class=\"widget-header"-程序员宅基地

文章浏览阅读6.2k次,点赞4次,收藏16次。erp系统所涉及到的主要框架 ace admin 地址:http://ace.jeka.by/右侧隐藏按钮.net 控件 控制一行显示4个,每个label属性display : inline-block 设置成固定宽度 80,外侧div设置min-width:140px 高度随label个数自动增加。注意:设置成table样式的话 checkbox 与 label文本产生高度差 不在同一个..._"class=\"widget-header"

[Opengl]OpenGL图形编程项目实战1-4章代码_opengl项目实战-程序员宅基地

文章浏览阅读4.3k次,点赞10次,收藏50次。目录第一章 计算机图形学概论第二章 图形变换第三章 图形建模绘制二维几何体绘制奥运五环运行环境:系统:macOSBigSur11.0.1macOS Big Sur 11.0.1macOSBigSur11.0.1IDE:Xcode Version12.2(12B45b)Xcode\ Version 12.2 (12B45b)Xcode Version12.2(12B45b)采用的OpenGL第三方库:GLUTGLUTGLUT第一章 计算机图形学概论调用OpenGL提供的茶壶、_opengl项目实战

python语法元素+温度转换实例_python实现温度转换(1) 输入输出的摄氏度采用大写字母c开头,温度可以是整数或小数-程序员宅基地

文章浏览阅读833次。一、程序的格式框架Python采用严格的“缩进”(即:tab键)来表示程序的格式框架,即表明程序的包含和层次关系。二、注释是程序编写过程中,程序员在代码中加入的一行或多行星系,用来对该段、该函数的说明,提高代码的可读性。注释一般采用英文说明,也可用中文说明。注释部分会被编译器忽略,不被执行。注释的表示方法:单行注释以为#开头,多行注释采用’’’(3个单引号)开头和结尾。注释主要的3个用..._python实现温度转换(1) 输入输出的摄氏度采用大写字母c开头,温度可以是整数或小数

python中选择结构_Python中选择结构通过什么语句实现_后端开发-程序员宅基地

文章浏览阅读207次。Python代码的单行注释使用什么符号_后端开发Python代码的单行注释使用井号“#”,井号表示单行注释的开始,跟在“#”号后面直到这行结束为止的代码都将被解释器忽略,使用方法是在Python程序中将井号放在需要注释的内容之前即可。 Python中选择结构通过什么语句实现Python中的选择结构语句是 if elif else。Python用缩进代替了Java/C/C++/C#中常用的大括号{}..._9.[判断题]语句:putchar('\n');表示输出一个换行符。

python用pip安装numpy错误_科学网-安装numpy-胡涛的博文-程序员宅基地

文章浏览阅读450次。下载numpy.1.11.2.zip安装包,上传到集群,使用python2.7来安装python setup.py install出现报错:SystemError: Cannot compile 'Python.h'. Perhaps you need to install python-dev|python-devel.安装python-devpip install python-devDEPR..._error: no matching distribution found for python-devel

计算混响时间的意义_混响是什么意思,混响时间计算公式汇总,混响器的-程序员宅基地

文章浏览阅读1.4k次。混响是什么意思,混响时间计算公式汇总,混响器的作用是什么音乐设备一波接着一波,层出不穷地出现在我们的生活当中,比如MP3、随身听、音响、功放等等,让我们有些目不暇接了,也正是他们的存在,混响是什么意思,混响时间计算公式汇总,混响器的作用是什么音乐设备一波接着一波,层出不穷地出现在我们的生活当中,比如MP3、随身听、音响、功放等等,让我们有些目不暇接了,也正是他们的存在,让我们的精神世界和娱乐生活变..._混响时间与回声消除

随便推点

关于baserecyclerviewadapterhelper同时设置emptyview和header_baserecyclerviewadapterhelper:4.0.0-beta02 显示empty-程序员宅基地

文章浏览阅读3k次。默认情况下无数据时只显示emptyview。在recyclerView.setAdapter(adapter)之前调用adapter.setHeaderAndEmpty(true);adapter.setHeaderFooterEmpty(true,true);_baserecyclerviewadapterhelper:4.0.0-beta02 显示emptyview

AppFuse搭建本地邮件服务器_fuse客户端服务器-程序员宅基地

文章浏览阅读1.3k次。邮件服务器选用apache-james-2.3.2,官网http://james.apache.org/下载解压即可;运行\james-2.3.2\bin\run.bat,出现如下界面:Text代码 D:\Program Files\james-2.3.2\bin>run.bat Using PHOENIX_HOME: D:\Program File_fuse客户端服务器

栈应用之简易计算器算法的原理及实现(C语言)_c语言计算器原理-程序员宅基地

文章浏览阅读8.5k次,点赞12次,收藏74次。1.后缀表达式a * b上面表达式称为中缀表达式,其特点是操作符位于中间位置(仅一个操作符)。a b *上面表达式称为后缀表达式,其特点是操作符位于后面位置(仅一个操作符)。计算器算法的原理是将中缀表达式转换为后缀表达式,然后进行计算。我们在下一章节对中缀转后缀进行介绍。表达式:6*(5+(2+3)*8+3)其后缀表达式为:6 5 2 3 +_c语言计算器原理

linux多路径键盘重启,linux多路径连接iScsi存储_重启自动连接-程序员宅基地

文章浏览阅读272次。如果不是开机启动,即3和5是off,需要改成开机启动#chkconfig iscsi --level 35 on#chkconfig iscsid --level 35 on4.启动iSCSI服务,查看服务状态# service iscsi start## service iscsi status5.修改配置文件# vim /etc/iscsi/iscsid.confnode.startup=au..._linux 取消 iscsi 自动重新连接

模拟ls -l命令简易代码demo_ls -l demo-程序员宅基地

文章浏览阅读773次。话不多说 上代码:/************************************************************************* > File Name: ls-l.c > Author: > Mail: > Created Time: Wed 08 Mar 2017 05:32:08 AM PST *********************_ls -l demo

云服务器使用入门_程序员怎么使用自己的云服务器-程序员宅基地

文章浏览阅读374次。云服务器使用入门学习目标背景介绍基本操作总结学习目标掌握云服务器使用的基本方法。背景介绍当前市场上对程序员的基本需求之一就是能够使用服务器进行开发。在绝大多数公司中,我们都会使用Centos系统(Linux发行版之一)进行开发,因为它是被验证的最稳定的企业级开发服务器。下面我们将学习一些简单的命令,来开启我们Centos学习之旅。基本操作假设你已经通过运维人员开通了服务器,并获得了root用户权限(在公司中,你可能得不到这么高的权限),需要在终端中输入这些命令。使用ssh命令登陆服务器:s_程序员怎么使用自己的云服务器

推荐文章

热门文章

相关标签