日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

LBP特征学习(附python实现)

發布時間:2025/7/25 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LBP特征学习(附python实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
LBP特征學習(附python實現)

LBP的全稱是Local Binary Pattern即局部二值模式,是局部信息提取中的一種方法,它具有旋轉不變性和灰度不變性等顯著的優點。在人臉識別領域有很多案例,此外,局部特征的算法還有 SIFT HOG等等。

LBP就是一種局部信息,它反應的內容是每個像素與周圍像素的關系。舉最基本的LBP為例,它反應了像素與周圍8個點灰度值的關系,如下圖所示:


  如上圖所示,中間像素的灰度值為54,我們如下定義:當周圍像素的灰度值大于等于中間像素值時,則LBP的一位值為1,否則為零。由這個九宮格,我們就得到了8位二進制數,順時針取值,就得到了一個像素的LBP值,即11010011。那么我們如何表示這個二進值數呢,很簡單,我們將它轉化為十進制數即可,也就是211,即這一點的LBP值為211。就這樣對整個圖像進行LBP運算,就可以得到這幅圖像的LBP特征。也就是說,我們把一張像素為256*256的圖片進行LBP特征提取,我們就可以得到一個256*256的特征圖(最外面的一圈進行補0后在進行運算),但每個特征圖里的數值的范圍是多少呢? 0-256嗎 不是的,特征圖里的數值是由你定義的半徑 和鄰居數決定的 。比如上述的例子,他的半徑是只選了周圍一圈的8個,也就是 半徑為1,鄰居為 8 (一般來說,鄰居數為半徑的8倍) 。以此類推。 如果我們定義的是 半徑為2 ,鄰居為 2*8時 得到的特征圖的數值的二進制數長度就翻了一番,所以范圍是? 0-65535 。

  但是得到這些特征有什么作用呢?提取圖像特征的目標無非就是為了進行分類,我們把一幅灰度圖像轉化為了LBP特征圖像,從理論上講并沒有實現降維,也無法進行分類。

  這時就引入了直方圖統計,我們將LBP特征進行直方圖統計,也就是統計LBP特征0~255各占的比例,這樣就進行了數據的降維。之后就可以將一個向量輸入分類器中進行分類。可是由于只有256維特征,所以分類的效果并不好。這時我們就引入了圖像分塊處理的方法,也就是說將圖像分成若干的圖像塊,如,在人臉識別中,把臉分為7*7,5*5的區域,并對這49,25個小區域進行LBP處理,將每個小區域的直方圖進行串聯,就可以得到整個圖像的LBP直方圖。并對這個直方圖進行分類處理,這樣可以大大的增強分類的效果。但是分類數據維度也大大增加了,如果是7*7區域,數據維度為7*7*256=12544維。

????可以看出數據的維度還是比較大,所以需要進一步進行降維,這里就涉及了另外一個概念:Uniform LBP,即均勻模式LBP。這種降維感覺是用了電路中的方法,也就是將原來的256維灰度數據重新分類,統計其位移后的跳變次數,當跳變次數小于2次時就定義為一個Uniform LBP,比如00000000左移一位還是00000000,沒有跳變,即跳變次數為0;00001111左移一位為00011110,跳變次數為2;10100000左移一位為01000001跳變次數為3,它不是Uniform LBP。經過統計,Uniform LBP在整個的LBP特征中占85~90%,而Uniform LBP只有58個特征。所以我們將分類特征向量由256維降為58維。在實際應用中,其實是59維,因為加一維表示那些不是Uniform LBP的量。那么7*7的人臉區域在進行降維之后,有7*7*59=2891維。由此對LBP特征進行了降維。

所以,對LBP特征向量進行提取的步驟為:

1)首先將檢測窗口劃分為16*16的小區域(cell)

2)對于每個cell中的一個像素,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大于中心像素值,則該像素點的位置被標記為1,否則為0.這樣,3*3領域內的8個點經過比較可產生8位二進制數,即得到該窗口中心像素點的LBP值;

3)然后計算每個cell的直方圖,即每個數字出現的頻率,然后對該直方圖進行歸一化處理

4)最后將得到的每個cell的統計直方圖進行連接成一個特征向量,也就是整幅圖的LBP紋理特征向量

然后便可以用SVM或者其他機器學習算法進行分類了。

?

此外,LBP有許多的改進版本

1)圓形LBP算子

? ? ? ?基本的LBP算子的最大缺陷就是只覆蓋了一個固定半徑范圍內的小區域,這顯然不能滿足不同尺寸和頻率紋理的需要,為了適應不同尺度的紋理特征,并達到灰度和旋轉不變性的要求。改進后的LBP算子允許在半徑為R的圓形領域內有任意多個像素點,從而得到諸如半徑為R的圓形區域內含有p個采樣點的LBP算子(見LBP算子.jpg)

2)LBP旋轉不變模式

? ? 從LBP定義可以看出,LBP算子是灰度不變的,但卻不是旋轉不變的,圖像的旋轉就會得到不同的LBP值。為了得到旋轉不變性,即不斷旋轉圓形領域得到一系列初始定義的LBP值,取其最小值作為該領域的LBP值。(見旋轉不變的LBP示意.jpg)

3)LBP等價模式

? ? ? ?一個LBP算子可以產生不同的二進制模式,對于半徑為R的圓形區域內含有p個采樣點的LBP算子將會產生2的p次方中模式,顯然,隨著領域內采樣點數的增加,二進制模式的種類急劇增加。如此多的二值模式對于紋理的表達是不利的。如將LBP算子用于紋理分類或人臉識別時,常采用LBP模式的統計直方圖來表達圖像的信息,而較多的模式種類將使得數據量過大,且直方圖過于稀疏,因此,需要對原始的LBP模式進行降維,使得數據減少的情況下能最好的代表圖像的信息。

?

使用python進行LBP特征提取并進行SVM訓練

使用到 skimage sklearn 等等

代碼稍后寫好放上去。。。。

?

?

import numpy as np import cv2 import os from skimage import io, transform, color, measure, segmentation, morphology, feature from sklearn import svm, multiclass, model_selection import csv import matplotlib.pyplot as plt # from PIL import Imagepath = "G:\\Sample1\\" csvfile = path+"ground_truth.csv" print(csvfile) pic_path = [] label_1 = [] label_2 = []#把標簽轉換為 數字量 def label2number(label_list):label=np.zeros(len(label_list),)label_unique=np.unique(label_list)num=label_unique.shape[0]# label_list = np.array(label_list)for k in range(num):temp=label_unique[k]index=[i for i, v in enumerate(label_list) if v == temp]## print(temp)# index=label_list.find(temp)label[index]=kreturn label,label_unique# 填充空白區域 def imfill(im_th):# im_th 是0 1 整形二值圖# Copy the thresholded imapge.im_th = np.uint8(im_th)im_floodfill = im_th.copy()# Mask used to flood filling.# Notice the size needs to be 2 pixels than the image.h, w = im_th.shape[:2]# print('h '+str(h)+' w '+str(w))mask = np.zeros((h + 2, w + 2), np.uint8)# Floodfill from point (0, 0)cv2.floodFill(im_floodfill, mask, (0, 0), 1)# Invert floodfilled imageim_floodfill_inv = cv2.bitwise_not(im_floodfill)# Combine the two images to get the foreground.im_out = im_th | im_floodfill_invreturn im_out#打開csv文件 第0列是 圖片名稱 第1 2列是 兩種標簽 with open(csvfile, "r") as f:# with open(birth_weight_file, "w") as f:csvreader = csv.reader(f)csvheader = next(csvreader)print(csvheader)for row in csvreader:# print(len(row))pic_path.append(path+'Images\\'+row[0])label_1.append(row[1])label_2.append(row[2])# 圖片樣本進行預處理,進行裁剪,去除非必要部分 vidHeight = 660 vidWidth = 1120 # for i in range(0, len(pic_path)): Data=[] for i in range(0, 1000):if os.path.exists(pic_path[i]):pic_temp = io.imread(pic_path[i])pic_temp = pic_temp[300:(660+300), 80:(80+1120)]roi = color.rgb2gray(pic_temp)thresh = 140bw = (roi <= thresh/255) * 1 # 根據閾值進行分割# dst=np.uint8(dst)pic_temp2 = imfill(bw)cleared = pic_temp2.copy() # 復制segmentation.clear_border(cleared) # 清除與邊界相連的目標物label_image = measure.label(cleared) # 連通區域標記 connectivity=1 # 4連通區域標記# image_label_overlay = color.label2rgb(label_image) # 不同標記用不同顏色顯示# plt.imshow(image_label_overlay, interpolation='nearest')# plt.show()borders = np.logical_xor(bw, cleared) # 異或,去除背景label_image[borders] = -1Eccentricity = 1 # 離心率for region in measure.regionprops(label_image): # 循環得到每一個連通區域屬性集# 忽略小區域if region.area < 100000:continue# print('area is ' + str(region.area) + ' ecc is' + str(region.eccentricity))if Eccentricity > region.eccentricity:Eccentricity = region.eccentricityminr, minc, maxr, maxc = region.bbox # 繪制外包矩形# 判斷是否有符合條件的區域if 'minr' in vars():pic = pic_temp[minr:maxr, minc:maxc,:]pic = transform.resize(pic, [256,256,3])#print(lbp)# plt.imshow(pic)# plt.show()else:pic = transform.resize(pic_temp, [256, 256, 3])#提取LBP特征,每個圖像分成4塊進行提取pic1 = color.rgb2gray(pic)rows, cols = pic1.shaperadius = 2;n_points = radius * 8lbp_sum=[]for row in range(2):for col in range(2):#print(str((row * rows//2)) + ' : ' + str(((row+1) * rows//2 - 1)))pic1_block = pic1[(row * rows//2) : ((row+1) * rows//2 - 1) , (col * col//2) : ((col+1) * col//2 - 1)]lbp = feature.local_binary_pattern(pic1, n_points, radius, 'uniform')lbp2 = lbp.astype(np.int32)max_bins = int(lbp2.max() + 1)train_hist, _ = np.histogram(lbp2, normed=True, bins=max_bins, range=(0, max_bins))# print(train_hist.dtype)#print(train_hist)lbp_sum=lbp_sum + train_hist.tolist()#Data.append(lbp_sum)
#使用SVM進行訓練并計算測試準確率 label1, _ = label2number(label_1[0:1000]) X_train,X_test, y_train, y_test = model_selection.train_test_split(Data,label1,test_size=0.2, random_state=0) # train_data = Data[0:7] # train_label = label1[0:7] # test_data = Data[8:9] # test_label = label1[8:9] svr_rbf = svm.SVR(kernel='rbf', C=1e3, gamma=0.1); model = multiclass .OneVsRestClassifier(svr_rbf,-1) #.fit(train_data, train_label).score(test_data,test_label) clf = model.fit(X_train, y_train) sore=clf.score(X_test, y_test) print('acc'+str(sore))

  

?

?

?

?

?

?

?

?

?

?

?

參考文獻:?http://blog.sina.com.cn/s/blog_4bdbec750101ekuh.html

   ? ? ? https://1043693084-qq-com.iteye.com/blog/2245828

posted on 2019-04-20 22:21 hyb965149985 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/hyb965149985/p/10743022.html

總結

以上是生活随笔為你收集整理的LBP特征学习(附python实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。