LBP人脸识别

第三种算法称之为LBP算法,这个算法的思路与PCA和Fisher有很大不同,他是考虑局部特征算子,并不是全局考虑。

这种算法定义了一种LBP特征,这种特征与我们经常见到的Haar特征、HoG特征没有啥太大不同,都是特征算子,只是算法不同。因此,我们按照理解特征算子一类的算法去理解LBP就可以了。

注意,LBP对关照不敏感,为什么?因为LBP算子是一种相对性质的数量关系,相比于PCA或者Fsiher,直接使用灰度值去参与运算,LBP更能反映出的是一种变化趋势。

最后一次当个搬运工

http://blog.csdn.NET/feirose/article/details/39552977,LBP算子写的不算太清楚,但是整个算法的完整流程讲明白了,而且最后如何判定的直方图交叉核和卡方检验都有说明。

http://blog.csdn.Net/pi9nc/article/details/18623971,这个博客的LBP算子说得很好,而且有OpenCV的例程。

注意,这里的样本图像组织形式与前面两个算法又有不同,因为他不需要把图像变成列向量,因此图像矩阵不需要做什么处理就可以加入列表备用了。

代码如下:

[python]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #encoding=utf-8  
  2. import numpy as np  
  3. import os  
  4. import cv2  
  5.   
  6. class LBP(object):  
  7.     def __init__(self,threshold,dsize,blockNum):  
  8.         self.dsize = dsize # 统一尺寸大小  
  9.         self.blockNum = blockNum # 分割块数目  
  10.         self.threshold = threshold # 阈值,暂未使用  
  11.   
  12.     def loadImg(self,fileName,dsize):  
  13.         ''''' 
  14.         载入图像,灰度化处理,统一尺寸,直方图均衡化 
  15.         :param fileName: 图像文件名 
  16.         :param dsize: 统一尺寸大小。元组形式 
  17.         :return: 图像矩阵 
  18.         '''  
  19.         img = cv2.imread(fileName)  
  20.         retImg = cv2.resize(img,dsize)  
  21.         retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY)  
  22.         retImg = cv2.equalizeHist(retImg)  
  23.         # cv2.imshow('img',retImg)  
  24.         # cv2.waitKey()  
  25.         return retImg  
  26.   
  27.     def loadImagesList(self,dirName):  
  28.         ''''' 
  29.         加载图像矩阵列表 
  30.         :param dirName:文件夹路径 
  31.         :return: 包含最原始的图像矩阵的列表和标签矩阵 
  32.         '''  
  33.         imgList = []  
  34.         label = []  
  35.         for parent,dirnames,filenames in os.walk(dirName):  
  36.             # print parent  
  37.             # print dirnames  
  38.             # print filenames  
  39.             for dirname in dirnames:  
  40.                 for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname):  
  41.                     for filename in subFilenames:  
  42.                         img = self.loadImg(subParent+'/'+filename,self.dsize)  
  43.                         imgList.append(img) # 原始图像矩阵不做任何处理,直接加入列表  
  44.                         label.append(subParent+'/'+filename)  
  45.         return imgList,label  
  46.   
  47.   
  48.     def getHopCounter(self,num):  
  49.         ''''' 
  50.         计算二进制序列是否只变化两次 
  51.         :param num: 数字 
  52.         :return: 01变化次数 
  53.         '''  
  54.         binNum = bin(num)  
  55.         binStr = str(binNum)[2:]  
  56.         n = len(binStr)  
  57.         if n < 8:  
  58.             binStr = "0"*(8-n)+binStr  
  59.         n = len(binStr)  
  60.         counter = 0  
  61.         for i in range(n):  
  62.             if i != n-1:  
  63.                 if binStr[i+1] != binStr[i]:  
  64.                     counter += 1  
  65.             else:  
  66.                 if binStr[0] != binStr[i]:  
  67.                     counter += 1  
  68.         return counter  
  69.   
  70.     def createTable(self):  
  71.         ''''' 
  72.         生成均匀对应字典 
  73.         :return: 均匀LBP特征对应字典 
  74.         '''  
  75.         self.table = {}  
  76.         temp = 1  
  77.         print type(temp)  
  78.         for i in range(256):  
  79.             if self.getHopCounter(i) <= 2:  
  80.                 self.table[i] = temp  
  81.                 temp += 1  
  82.             else:  
  83.                 self.table[i] = 0  
  84.         return self.table  
  85.   
  86.     def getLBPfeature(self,img):  
  87.         ''''' 
  88.         计算LBP特征 
  89.         :param img:图像矩阵 
  90.         :return: LBP特征图 
  91.         '''  
  92.         m = img.shape[0];n = img.shape[1]  
  93.         neighbor = [0]*8  
  94.         featureMap = np.mat(np.zeros((m,n)))  
  95.         for y in xrange(1,m-1):  
  96.             for x in xrange(1,n-1):  
  97.                 neighbor[0] = img[y-1,x-1]  
  98.                 neighbor[1] = img[y-1,x]  
  99.                 neighbor[2] = img[y-1,x+1]  
  100.                 neighbor[3] = img[y,x+1]  
  101.                 neighbor[4] = img[y+1,x+1]  
  102.                 neighbor[5] = img[y+1,x]  
  103.                 neighbor[6] = img[y+1,x-1]  
  104.                 neighbor[7] = img[y,x-1]  
  105.                 center = img[y,x]  
  106.                 temp = 0  
  107.                 for k in range(8):  
  108.                     temp += (neighbor[k] >= center)*(1<<k)  
  109.                 featureMap[y,x] = self.table[temp]  
  110.         featureMap = featureMap.astype('uint8'# 数据类型转换为无符号8位型,如不转换则默认为float64位,影响最终效果  
  111.         return featureMap  
  112.   
  113.     def calcHist(self,roi):  
  114.         ''''' 
  115.         计算直方图 
  116.         :param roi:图像区域 
  117.         :return: 直方图矩阵 
  118.         '''  
  119.         hist = cv2.calcHist([roi],[0],None,[59],[0,256]) # 第四个参数是直方图的横坐标数目,经过均匀化降维后这里一共有59种像素  
  120.         return hist  
  121.   
  122.     def compare(self,sampleImg,testImg):  
  123.         ''''' 
  124.         比较函数,这里使用的是欧氏距离排序,也可以使用KNN,在此处更改 
  125.         :param sampleImg: 样本图像矩阵 
  126.         :param testImg: 测试图像矩阵 
  127.         :return: k2值 
  128.         '''  
  129.         testImg = cv2.resize(testImg,self.dsize)  
  130.         testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY)  
  131.         testFeatureMap = self.getLBPfeature(testImg)  
  132.         sampleFeatureMap = self.getLBPfeature(sampleImg)  
  133.         # 计算步长,分割整个图像为小块  
  134.         ystep = self.dsize[0]/self.blockNum  
  135.         xstep = self.dsize[1]/self.blockNum  
  136.         k2 = 0  
  137.         for y in xrange(0,self.dsize[0],ystep):  
  138.             for x in xrange(0,self.dsize[1],xstep):  
  139.                 testroi = testFeatureMap[y:y+ystep,x:x+xstep]  
  140.                 sampleroi =sampleFeatureMap[y:y+ystep,x:x+xstep]  
  141.                 testHist = self.calcHist(testroi)  
  142.                 sampleHist = self.calcHist(sampleroi)  
  143.                 k2 += np.sum((sampleHist-testHist)**2)/np.sum((sampleHist+testHist))  
  144.         print 'k2的值为',k2  
  145.         return k2  
  146.   
  147.     def predict(self,dirName,testImgName):  
  148.         ''''' 
  149.         预测函数 
  150.         :param dirName:样本图像文件夹路径 
  151.         :param testImgName: 测试图像文件名 
  152.         :return: 最相近图像名称 
  153.         '''  
  154.         table = self.createTable()  
  155.         testImg = cv2.imread(testImgName)  
  156.         imgList,label = self.loadImagesList(dirName)  
  157.         k2List = []  
  158.         for img in imgList:  
  159.             k2 = self.compare(img,testImg)  
  160.             k2List.append(k2)  
  161.         order = np.argsort(k2List)  
  162.         return label[order[0]]  
  163.   
  164. if __name__ == "__main__":  
  165.   
  166.     lbp = LBP(20,(50,50),5)  
  167.     ans = lbp.predict('d:/face','d:/face_test/9.bmp')  
  168.     print ans  
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值