python图像纹理提取_python 实现 gabor 滤波器提取纹理特征 提取指静脉纹理特征 指静脉切割代码...

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 核函数的表达式:

复数表达式:

ab7653affab982b574eb7acc55df2e04.gif

可以拆解: 实部:

ab7653affab982b574eb7acc55df2e04.gif

虚部:

ab7653affab982b574eb7acc55df2e04.gif

其中:

ab7653affab982b574eb7acc55df2e04.gif

ab7653affab982b574eb7acc55df2e04.gif

参数介绍:

方向(θ): 这个参数指定了 Gabor 函数并行条纹的方向, 它的取值为 0 到 360 度

ab7653affab982b574eb7acc55df2e04.gif

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

ab7653affab982b574eb7acc55df2e04.gif

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

ab7653affab982b574eb7acc55df2e04.gif

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

ab7653affab982b574eb7acc55df2e04.gif

带宽(b):Gabor 滤波器的半响应空间频率带宽 b 和σ/ λ的比率有关, 其中σ表示 Gabor 函数的高斯因子的标准差, 如下:

ab7653affab982b574eb7acc55df2e04.gif

σ的值不能直接设置, 它仅随着带宽 b 变化. 带宽值必须是正实数, 通常为 1, 此时, 标准差和波长的关系为:σ= 0.56 λ. 带宽越小, 标准差越大, Gabor 形状越大, 可见平行兴奋和抑制区条纹数量越多.

好介绍完毕.

现在进入主题, 我们提取纹理特征.

提取纹理特征, 还有增强纹理特征, 很多时候我们都是要先提取 ROI 感兴趣区域来进行操作的. 很多图片上的其他空间其实对我们没有什么太大的作用, 还影响程序的运行速度. 则我们只拿 ROI 区域进行纹理提取.

先看看原来的指静脉图片:

ab7653affab982b574eb7acc55df2e04.gif

这图片区域很多, 一般我们只需要中间那部分指静脉纹理最多的 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()

好现在看看处理后的指静脉图片:

ab7653affab982b574eb7acc55df2e04.gif

看起来还不错吧, 预处理之后就可以 进行纹理特征提取放入文件进行模式匹配啊 进行指静脉识别啊. 有兴趣的就期待在下之后的博客.

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

你可能感兴趣的:(python图像纹理提取)