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
importnumpyasnp
importos
importcv2
defpathFile(path):
returnos.getcwd()+'/'+path
defbrightestColumn(img):
w,h=img.shape
r=range(h/2,h-1)
c=range(0,w-1)
returnimg[c][:,r].sum(axis=0).argmax()
# 构建 GABOR 滤波器
defbuild_filters():
"""returns a list of kernels in several orientations"""
filters=[]
ksize=31#gaborl 尺度 这里是一个
forthetainnp.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))
returnfilters
# 滤波过程
defprocess(img,filters):
"""returns the img filtered by the filter list"""
accum=np.zeros_like(img)#初始化 img 一样大小的矩阵
forkern,paramsinfilters:
fimg=cv2.filter2D(img,cv2.CV_8UC3,kern)#2D 滤波函数 kern 为其滤波模板
np.maximum(accum,fimg,accum)#参数 1 与参数 2 逐位比较 取大者存入参数 3 这里就是将纹理特征显化更加明显
returnaccum
# 获取感兴趣区域的 top 和 bottom 值 用于切割显示图像
defgetRoiHCut2(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
returnimg[maxTop:maxBottom,:]
# 获取感兴趣区域范围
defgetRoi(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)returnclahe.apply(res)
deflogImg(img):
returnimg.astype(float)/255#将图像数据转为0-1存储
mDir=[]
imgs=[]
dbDir=os.getcwd()+"/db100/"
people=os.listdir(dbDir)
people.sort()
forpersoninpeople:
personDir=dbDir+person+"/"
hands=os.listdir(personDir)
forhandinhands:
handDir=personDir+hand+"/"
mDir+=[handDir]
mg=os.listdir(handDir)
mg.sort()
imgs=imgs+[handDir+s.split(".")[0]forsinmgifnots.split(".")[0]=="Thumbs"]
p0Imgs=[i.replace('db','gab_roi_db')foriinimgs]#p0Imgs 是每个文件的路径, mDir 是需要创建路径所有文件夹存放预处理后图片
mDir=[i.replace('db','gab_roi_db')foriinmDir]
# 判断路径是否存在 不存在就创建路径
forpathinmDir:
ifnotos.path.exists(path):
os.makedirs(path)
filters=build_filters()
forindex,imgPathinenumerate(imgs):
img=cv2.imread(imgPath+".bmp",0)
res0=process(getRoi(img),filters)#获取 ROI 进行直方图均衡化 切割后 在 gabor 滤波
cv2.imwrite(p0Imgs[index]+".png",res0)
printindex
cv2.waitKey(0)
cv2.destroyAllWindows()
好现在看看处理后的指静脉图片:
看起来还不错吧, 预处理之后就可以 进行纹理特征提取放入文件进行模式匹配啊 进行指静脉识别啊. 有兴趣的就期待在下之后的博客.
http://www.cnblogs.com/DOMLX/p/8989836.html 提取纹理特征
http://www.cnblogs.com/DOMLX/p/8672489.html 指静脉细化算法
http://www.cnblogs.com/DOMLX/p/8111507.html 指静脉切割过程
来源: https://www.cnblogs.com/DOMLX/p/8989836.html