python实现gabor滤波器提取纹理特征 提取指静脉纹理特征 指静脉切割代码
参考博客:https://blog.csdn.net/xue_wenyuan/article/details/51533953
https://blog.csdn.net/jinshengtao/article/details/17797641
傅里叶变换是一种信号处理中的有力工具,可以帮助我们将图像从空域转换到频域,并提取到空域上不易提取的特征。但是经过傅里叶变换后,
图像在不同位置的频度特征往往混合在一起,但是Gabor滤波器却可以抽取空间局部频度特征,是一种有效的纹理检测工具。
在图像处理中,Gabor函数是一个用于边缘提取的线性滤波器。Gabor滤波器的频率和方向表达同人类视觉系统类似。研究发现,Gabor滤波器十分适合纹理表达和分离。在空间域中,一个二维Gabor滤波器是一个由正弦平面波调制的高斯核函数。
gabor核函数的表达式:
复数表达式:
可以拆解:实部:
虚部:
其中:
和
参数介绍:
方向(θ):这个参数指定了Gabor函数并行条纹的方向,它的取值为0到360度

波长(λ):它的值以像素为单位指定,通常大于等于2.但不能大于输入图像尺寸的五分之一。

相位偏移(φ):它的取值范围为-180度到180度。其中,0he180度分别对应中心对称的center-on函数和center-off函数,而-90度和90度对应反对称函数。

长宽比(γ):空间纵横比,决定了Gabor函数形状(support,我翻译为形状)的椭圆率(ellipticity)。当γ= 1时,形状是圆的。当γ< 1时,形状随着平行条纹方向而拉长。通常该值为0.5

带宽(b):Gabor滤波器的半响应空间频率带宽b和σ/ λ的比率有关,其中σ表示Gabor函数的高斯因子的标准差,如下:
σ的值不能直接设置,它仅随着带宽b变化。带宽值必须是正实数,通常为1,此时,标准差和波长的关系为:σ= 0.56 λ。带宽越小,标准差越大,Gabor形状越大,可见平行兴奋和抑制区条纹数量越多。
好介绍完毕。
现在进入主题,我们提取纹理特征。
提取纹理特征,还有增强纹理特征,很多时候我们都是要先提取ROI感兴趣区域来进行操作的。很多图片上的其他空间其实对我们没有什么太大的作用,还影响程序的运行速度。则我们只拿ROI区域进行纹理提取。
先看看原来的指静脉图片:

这图片区域很多,一般我们只需要中间那部分指静脉纹理最多的ROI区域。
代码:
#!/usr/bin/python
#coding:utf-8
import numpy as np
import os
import cv2
def pathFile(path):
return os.getcwd() + '/' + path
def brightestColumn(img):
w, h = img.shape
r = range(h / 2, h - 1)
c = range(0, w - 1)
return img[c][:,r].sum(axis=0).argmax()
#构建GABOR滤波器
def build_filters():
""" returns a list of kernels in several orientations
"""
filters = []
ksize = 31 #gaborl尺度 这里是一个
for theta in np.arange(0, np.pi, np.pi / 4): #gaborl方向 0 45 90 135 角度尺度的不同会导致滤波后图像不同
params = {'ksize':(ksize, ksize), 'sigma':3.3, 'theta':theta, 'lambd':18.3,
'gamma':4.5, 'psi':0.89, 'ktype':cv2.CV_32F}
#gamma越大核函数图像越小,条纹数不变,sigma越大 条纹和图像都越大
#psi这里接近0度以白条纹为中心,180度时以黑条纹为中心
#theta代表条纹旋转角度
#lambd为波长 波长越大 条纹越大
kern = cv2.getGaborKernel(**params) #创建内核
kern /= 1.5*kern.sum()
filters.append((kern,params))
return filters
#滤波过程
def process(img, filters):
""" returns the img filtered by the filter list
"""
accum = np.zeros_like(img) #初始化img一样大小的矩阵
for kern,params in filters:
fimg = cv2.filter2D(img, cv2.CV_8UC3, kern) #2D滤波函数 kern为其滤波模板
np.maximum(accum, fimg, accum) #参数1与参数2逐位比较 取大者存入参数3 这里就是将纹理特征显化更加明显
return accum
#获取感兴趣区域的top 和 bottom值 用于切割显示图像
def getRoiHCut2(img, p0):
h, w = img.shape
maxTop = np.argmax(img[0: h / 2, 0]) #在一定区域遍历选取指静脉边缘 具体高宽结合图像
minTop = np.argmax(img[0: h / 2, w-1])
if(maxTop < 65):
maxBottom = np.argmax(img[(13 * h / 16): 40*h/48 , 0]) + 3 * h / 4
minBottom = np.argmax(img[(13 * h / 16): 40*h/48, w-1]) + 3 * h / 4
else:
maxBottom = np.argmax(img[(3 * h / 4): h , 0]) + 3 * h / 4
minBottom = np.argmax(img[(3 * h / 4): h, w-1]) + 3 * h / 4
maxTop = (2*maxTop + minTop) / 3
maxBottom = (maxBottom + 2*minBottom) / 3
return img[maxTop:maxBottom,:]
#获取感兴趣区域范围
def getRoi(img):
height, width = img.shape
heightDist = height / 4
w = img.copy()
w1 = w[heightDist:3 * heightDist,width / 4:]
p0 = brightestColumn(w1) + heightDist + height / 2 #将手指边缘的高度加上四分之三原始高度
pCol = w[:,p0:p0 + 1]
pColInv = pCol[::-1]
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) #构建一个有限对比适应性直方图均衡化器
w1_2 = clahe.apply(w[:, (p0 /20):(p0 + p0 / 2)]) #截取区域宽度大概是p0高度的一点五倍 apply是获取一个返回值 这里是为了方便参数的传递
w2 = getRoiHCut2(w1_2, p0)
res = cv2.resize(w2, (270, 150), interpolation=cv2.INTER_CUBIC)
return clahe.apply(res)
def logImg(img):
return img.astype(float) / 255 #将图像数据转为0-1存储
mDir=[]
imgs = []
dbDir = os.getcwd() + "/db100/"
people = os.listdir(dbDir)
people.sort()
for person in people:
personDir = dbDir + person + "/"
hands = os.listdir(personDir)
for hand in hands:
handDir = personDir + hand + "/"
mDir += [handDir]
mg = os.listdir(handDir)
mg.sort()
imgs = imgs + [handDir + s.split(".")[0] for s in mg if not s.split(".")[0] == "Thumbs"]
p0Imgs = [i.replace('db', 'gab_roi_db') for i in imgs] #p0Imgs是每个文件的路径,mDir是需要创建路径所有文件夹存放预处理后图片
mDir = [i.replace('db', 'gab_roi_db') for i in mDir]
#判断路径是否存在 不存在就创建路径
for path in mDir:
if not os.path.exists(path):
os.makedirs(path)
filters = build_filters()
for index, imgPath in enumerate(imgs):
img = cv2.imread(imgPath + ".bmp", 0)
res0 = process(getRoi(img), filters) #获取ROI进行直方图均衡化 切割后 在gabor滤波
cv2.imwrite(p0Imgs[index] + ".png", res0)
print index
cv2.waitKey(0)
cv2.destroyAllWindows()
好现在看看处理后的指静脉图片:

看起来还不错吧,预处理之后就可以 进行纹理特征提取放入文件进行模式匹配啊 进行指静脉识别啊。有兴趣的就期待在下之后的博客。
python实现gabor滤波器提取纹理特征 提取指静脉纹理特征 指静脉切割代码的更多相关文章
- Gabor滤波器学习
本文的目的是用C实现生成Gabor模版,并对图像卷积.并简单提一下,Gabor滤波器在纹理特征提取上的应用. 一.什么是Gabor函数(以下内容含部分翻译自维基百科) 在图像处理中,Gabor函数是一 ...
- Gabor变换、Gabor滤波器
D.Gabor 1946年提出 窗口Fourier变换,为了由信号的Fourier变换提取局部信息,引入了时间局部化的窗函数. 由于窗口Fourier变换只依赖于部分时间的信号,所以,现在窗口Four ...
- Gabor滤波器的理解
搬以前写的博客[2014-02-28 20:03] 关于Gabor滤波器是如何提取出特征点,这个过程真是煎熬.看各种文章,结合百度.文章内部的分析才有一点点明白. Gabor滤波器究竟是什么? 很 ...
- gabor滤波器
https://blog.csdn.net/u013709270/article/details/49642397 https://github.com/xuewenyuan/Gabor_Visual ...
- Kaggle "Microsoft Malware Classification Challenge"——就是沙箱恶意文件识别,有 Opcode n-gram特征 ASM文件图像纹理特征 还有基于图聚类方法
使用图聚类方法:Malware Classification using Graph Clustering 见 https://github.com/rahulp0491/Malware-Classi ...
- 图像算法五:【图像小波变换】多分辨率重构、Gabor滤波器、Haar小波
原 https://blog.csdn.net/alwaystry/article/details/52756051 图像算法五:[图像小波变换]多分辨率重构.Gabor滤波器.Haar小波 2018 ...
- Python基于共现提取《釜山行》人物关系
Python基于共现提取<釜山行>人物关系 一.课程介绍 1. 内容简介 <釜山行>是一部丧尸灾难片,其人物少.关系简单,非常适合我们学习文本处理.这个项目将介绍共现在关系中的 ...
- ARCGIS API for Python进行城市区域提取
ArcGIS API for Python主要用于Web端的扩展和开发,提供简单易用.功能强大的Python库,以及大数据分析能力,可轻松实现实时数据.栅格数据.空间数据等多源数据的接入和GIS分析 ...
- 【特征检測】BRIEF特征点描写叙述算法
简单介绍 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,BRIEF是对已检測到的特 ...
随机推荐
- Objc中为何某些类的属性要设置为copy而不是strong?
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 不知道大家是否注意,我们再使用一些第三方类的时候大多数情况下对 ...
- 海量数据处理算法(top K问题)
举例 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. 思路 首先把文件分开 针对每个文件hash遍历,统计每个词语的频率 使用堆进 ...
- 百度地图隐藏缩放控件比例尺Logo
对于百度地图最新版V3.7.3,以前的隐藏控件方法失效,可用以下方法隐藏: 1.隐藏缩放控件: mMapView.showZoomControls(false); 2.隐藏比例尺: mMapView. ...
- Linux常用网络命令整理
Linux上有一些非常常用的命令,来帮助我们监控网络状况. 1.Tcpdump命令 tcpdump可以将网络中传送的数据包的"头"完全截获下来提供分析.它支持针对网络层.协议.主机 ...
- (七十四)iOS8之前使socket可以后台运行的方法
对于使用socket通信的应用程序,常常希望App位于后台时仍然可以进行网络通信,这在iOS8和以后的版本是被默认允许的,socket可以直接在后台运行,而对于iOS8之前的版本就不行,需要进行两步设 ...
- UNIX网络编程——内网与外网间通信
QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服务器,只不过不是常用的那些,那个服务器是腾讯自行开发的!!! 一.登 ...
- 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137 转载请著名出处 本博客相关文档下载 : -- AR ...
- Eclpse 标准版,在联想一体机上报 eclipse failed to create the java virtual machine
环境:联想一体机 IdearCentre B320I, XP系统 32位操作系统 下载了最新的JDK和Eclipse标准版,安装之后,启动eclipse报错 这个错误,以前还真没有遇到过,网上搜了下 ...
- -Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable a
eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is ...
- Java枚举类"全方位"
作为一种长度固定,数据未定的一种存储数据集的数据类型,枚举类有如下方法可供参考. 普通类型的枚举类的创建 protected enum ColorEnum{ red,orange,yellow,gre ...