├── .gitattributes ├── .gitignore ├── README.md ├── get_LBP_from_Image.py ├── get_resolve_map.py └── get_uniform_map.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | 56 | # ========================= 57 | # Operating System Files 58 | # ========================= 59 | 60 | # OSX 61 | # ========================= 62 | 63 | .DS_Store 64 | .AppleDouble 65 | .LSOverride 66 | 67 | # Thumbnails 68 | ._* 69 | 70 | # Files that might appear on external disk 71 | .Spotlight-V100 72 | .Trashes 73 | 74 | # Directories potentially created on remote AFP share 75 | .AppleDB 76 | .AppleDesktop 77 | Network Trash Folder 78 | Temporary Items 79 | .apdisk 80 | 81 | # Windows 82 | # ========================= 83 | 84 | # Windows image file caches 85 | Thumbs.db 86 | ehthumbs.db 87 | 88 | # Folder config file 89 | Desktop.ini 90 | 91 | # Recycle Bin used on file shares 92 | $RECYCLE.BIN/ 93 | 94 | # Windows Installer files 95 | *.cab 96 | *.msi 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LBP 2 | 获取图像的LBP特征:对图像的原始LBP模式、等价LBP模式、旋转不变LBP模式,以及等价旋转不变LBP模式的LBP特征进行提取以及显示。 3 | 4 | get_LBP_from_Image.py 主要文件 获取图像的LBP特征 5 | 6 | get_resolve_map.py和get_uniform_map.py主要是做降维后新的像素值的映射。已经将求出的结果写入了get_LBP_from_Image.py中,这两个主要是帮助理解算法降维后新的像素值怎么得到的。 7 | -------------------------------------------------------------------------------- /get_LBP_from_Image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # get_LBP_from_Image.py 3 | # 2015-7-7 4 | # github: https://github.com/michael92ht 5 | #__author__ = 'huangtao' 6 | 7 | # import the necessary packages 8 | import numpy as np 9 | import cv2 10 | from PIL import Image 11 | from pylab import* 12 | 13 | class LBP: 14 | def __init__(self): 15 | #revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典 16 | self.revolve_map={0:0,1:1,3:2,5:3,7:4,9:5,11:6,13:7,15:8,17:9,19:10,21:11,23:12, 17 | 25:13,27:14,29:15,31:16,37:17,39:18,43:19,45:20,47:21,51:22,53:23,55:24, 18 | 59:25,61:26,63:27,85:28,87:29,91:30,95:31,111:32,119:33,127:34,255:35} 19 | #uniform_map为等价模式的58种特征值从小到大进行序列化编号得到的字典 20 | self.uniform_map={0:0,1:1,2:2,3:3,4:4,6:5,7:6,8:7,12:8, 21 | 14:9,15:10,16:11,24:12,28:13,30:14,31:15,32:16, 22 | 48:17,56:18,60:19,62:20,63:21,64:22,96:23,112:24, 23 | 120:25,124:26,126:27,127:28,128:29,129:30,131:31,135:32, 24 | 143:33,159:34,191:35,192:36,193:37,195:38,199:39,207:40, 25 | 223:41,224:42,225:43,227:44,231:45,239:46,240:47,241:48, 26 | 243:49,247:50,248:51,249:52,251:53,252:54,253:55,254:56, 27 | 255:57} 28 | 29 | 30 | #将图像载入,并转化为灰度图,获取图像灰度图的像素信息 31 | def describe(self,image): 32 | image_array=np.array(Image.open(image).convert('L')) 33 | return image_array 34 | 35 | #图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较 36 | #比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列 37 | def calute_basic_lbp(self,image_array,i,j): 38 | sum=[] 39 | if image_array[i-1,j-1]>image_array[i,j]: 40 | sum.append(1) 41 | else: 42 | sum.append(0) 43 | if image_array[i-1,j]>image_array[i,j]: 44 | sum.append(1) 45 | else: 46 | sum.append(0) 47 | if image_array[i-1,j+1]>image_array[i,j]: 48 | sum.append(1) 49 | else: 50 | sum.append(0) 51 | if image_array[i,j-1]>image_array[i,j]: 52 | sum.append(1) 53 | else: 54 | sum.append(0) 55 | if image_array[i,j+1]>image_array[i,j]: 56 | sum.append(1) 57 | else: 58 | sum.append(0) 59 | if image_array[i+1,j-1]>image_array[i,j]: 60 | sum.append(1) 61 | else: 62 | sum.append(0) 63 | if image_array[i+1,j]>image_array[i,j]: 64 | sum.append(1) 65 | else: 66 | sum.append(0) 67 | if image_array[i+1,j+1]>image_array[i,j]: 68 | sum.append(1) 69 | else: 70 | sum.append(0) 71 | return sum 72 | 73 | #获取二进制序列进行不断环形旋转得到新的二进制序列的最小十进制值 74 | def get_min_for_revolve(self,arr): 75 | values=[] 76 | circle=arr 77 | circle.extend(arr) 78 | for i in range(0,8): 79 | j=0 80 | sum=0 81 | bit_num=0 82 | while j<8: 83 | sum+=circle[i+j]<255: 136 | k=k-255 137 | xor=basic_array[i,j]^k 138 | num=self.calc_sum(xor) 139 | if num<=2: 140 | uniform_array[i,j]=self.uniform_map[basic_array[i,j]] 141 | else: 142 | uniform_array[i,j]=58 143 | return uniform_array 144 | 145 | #获取图像的LBP旋转不变等价模式特征 146 | def lbp_revolve_uniform(self,image_array): 147 | uniform_revolve_array=np.zeros(image_array.shape, np.uint8) 148 | basic_array=self.lbp_basic(image_array) 149 | width=image_array.shape[0] 150 | height=image_array.shape[1] 151 | for i in range(1,width-1): 152 | for j in range(1,height-1): 153 | k= basic_array[i,j]<<1 154 | if k>255: 155 | k=k-255 156 | xor=basic_array[i,j]^k 157 | num=self.calc_sum(xor) 158 | if num<=2: 159 | uniform_revolve_array[i,j]=self.calc_sum(basic_array[i,j]) 160 | else: 161 | uniform_revolve_array[i,j]=9 162 | return uniform_revolve_array 163 | 164 | #绘制指定维数和范围的图像灰度归一化统计直方图 165 | def show_hist(self,img_array,im_bins,im_range): 166 | hist = cv2.calcHist([img_array],[0],None,im_bins,im_range) 167 | hist = cv2.normalize(hist).flatten() 168 | plt.plot(hist,color = 'r') 169 | plt.xlim(im_range) 170 | plt.show() 171 | 172 | #绘制图像原始LBP特征的归一化统计直方图 173 | def show_basic_hist(self,img_array): 174 | self.show_hist(img_array,[256],[0,256]) 175 | 176 | #绘制图像旋转不变LBP特征的归一化统计直方图 177 | def show_revolve_hist(self,img_array): 178 | self.show_hist(img_array,[36],[0,36]) 179 | 180 | #绘制图像等价模式LBP特征的归一化统计直方图 181 | def show_uniform_hist(self,img_array): 182 | self.show_hist(img_array,[60],[0,60]) 183 | 184 | #绘制图像旋转不变等价模式LBP特征的归一化统计直方图 185 | def show_revolve_uniform_hist(self,img_array): 186 | self.show_hist(img_array,[10],[0,10]) 187 | 188 | #显示图像 189 | def show_image(self,image_array): 190 | cv2.imshow('Image',image_array) 191 | cv2.waitKey(0) 192 | 193 | if __name__ == '__main__': 194 | image = r"d:\cv\603.jpg"; 195 | lbp=LBP() 196 | image_array=lbp.describe(image) 197 | 198 | #获取图像原始LBP特征,并显示其统计直方图与特征图像 199 | #basic_array=lbp.lbp_basic(image_array) 200 | #lbp.show_basic_hist(basic_array) 201 | #lbp.show_image(basic_array) 202 | 203 | #获取图像旋转不变LBP特征,并显示其统计直方图与特征图像 204 | #revolve_array=lbp.lbp_revolve(image_array) 205 | #lbp.show_revolve_hist(revolve_array) 206 | #lbp.show_image(revolve_array) 207 | 208 | #获取图像等价模式LBP特征,并显示其统计直方图与特征图像 209 | #uniform_array=lbp.lbp_uniform(image_array) 210 | #lbp.show_uniform_hist(uniform_array) 211 | #lbp.show_image(uniform_array) 212 | 213 | 214 | #获取图像等价模式LBP特征,并显示其统计直方图与特征图像 215 | #resolve_uniform_array=lbp.lbp_revolve_uniform(image_array) 216 | #lbp.show_revolve_uniform_hist(resolve_uniform_array) 217 | #lbp.show_image(resolve_uniform_array) 218 | -------------------------------------------------------------------------------- /get_resolve_map.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # get_resolve_map.py 3 | # 2015-7-7 4 | # github: https://github.com/michael92ht 5 | #__author__ = 'huangtao' 6 | 7 | #求为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典 8 | 9 | import string 10 | 11 | #对一个二进制表示旋转一周取最小值 12 | def get_min_for_revolve(arr,values): 13 | h=[] 14 | circle=arr 15 | circle.extend(arr) 16 | for i in range(0,8): 17 | j=0 18 | sum=0 19 | bit_num=0 20 | while j<8: 21 | sum+=circle[i+j]<1): #构造二进制表示的列表 36 | arr.append(string.atoi(b[j])) 37 | j-=1 38 | for s in range(0,8-len(arr)): 39 | arr.append(0) 40 | get_min_for_revolve(arr,values) 41 | 42 | values.sort() #构造字典 43 | map={} 44 | num=0 45 | f=open(r"d:/cv/test.txt",'w') 46 | for v in values: 47 | if not map.has_key(v): 48 | map[v]=num 49 | num+=1 50 | f.write(str(v)+':'+str(map[v])+',') 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /get_uniform_map.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # get_uniform_map.py 3 | # 2015-7-7 4 | # github: https://github.com/michael92ht 5 | #__author__ = 'huangtao' 6 | 7 | #求等价模式的58种特征值从小到大进行序列化编号得到的字典 8 | 9 | #求其二进制表示旋转一周的8个值 10 | def circle(arr,values): 11 | for i in range(0,8): 12 | b=0 13 | sum=0 14 | for j in range(i,8): 15 | sum+=arr[j]<