欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Python實(shí)現(xiàn)圖像LBP特征提取的操作方法

 更新時(shí)間:2025年04月22日 11:29:12   作者:像個(gè)孩子_Ryan  
LBP特征叫做局部二值模式,常用于紋理特征提取,并在紋理分類中具有較強(qiáng)的區(qū)分能力,本文給大家介紹了如何使用Python實(shí)現(xiàn)圖像LBP特征提取的操作方法,需要的朋友可以參考下

一、LBP特征介紹

LBP特征叫做局部二值模式,常用于紋理特征提取,并在紋理分類中具有較強(qiáng)的區(qū)分能力。它主要是利用結(jié)構(gòu)法思想分析固定窗口特征,再利用統(tǒng)計(jì)法做整體的特征提取,是一種理論簡(jiǎn)單但功能強(qiáng)大的紋理分析算法。

LBP的基本思想:它利用圖像中的每一個(gè)點(diǎn)和鄰域中點(diǎn)的灰度值的差異構(gòu)成圖像的細(xì)節(jié)紋理,用其中心像素的灰度值作為閾值,與它的鄰域中的像素灰度值相比較得到一個(gè)_8bit的二進(jìn)制碼_來表達(dá)局部紋理特征。

二、LBP特征描述

原始的LBP算子定義為在3×3的窗口內(nèi),以窗口中心像素為閾值,將相鄰的8個(gè)像素的灰度值與其進(jìn)行比較,若周圍像素值大于中心像素值,則該像素點(diǎn)的位 置被標(biāo)記為1,否則為0。這樣,3×3鄰域內(nèi)的8個(gè)點(diǎn)經(jīng)比較可產(chǎn)生8位二進(jìn)制(通常轉(zhuǎn)換為十進(jìn)制數(shù)即LBP碼,共256種),即得到該窗口中心像素點(diǎn)的LBP 值,并用這個(gè)值來反映該區(qū)域的紋理信息。

對(duì)于一幅大小是W*H的圖像,因?yàn)檫吘壪袼責(zé)o法計(jì)算8位的LBP值,所以將LBP值轉(zhuǎn)換為灰度圖像時(shí),它的大小是(W-2)*(H-2).

三、一些改進(jìn)版本的LBP

1.圓形LBP算子

圓形LBP算子即采用以中心點(diǎn)為圓心的圓形鄰域代替上文中的正方形鄰域。鄰域尺寸可以由半徑R和采樣點(diǎn)P確定。

2.旋轉(zhuǎn)不變的LBP算子

上文中可以看出,LBP算子是灰度不變的,但卻_不是旋轉(zhuǎn)不變的,圖像的旋轉(zhuǎn)就會(huì)得到不同的LBP值。因此將LBP算子進(jìn)行了擴(kuò)展,提出了具有旋轉(zhuǎn)不變性的LBP算子,即不斷旋轉(zhuǎn)圓形鄰域得到一系列初始定義的LBP值,取其最小值作為該鄰域的LBP值_。

舉一個(gè)簡(jiǎn)單的例子,對(duì)于11110000來說,其旋轉(zhuǎn)后能夠得到11100001、10000111等值。這一個(gè)算子的旋轉(zhuǎn)不變的LBP值就是其旋轉(zhuǎn)后能得到的最小值00001111。

3.LBP等價(jià)模式

為了解決LBP模式過多的問題,提出了“等價(jià)模式”這一個(gè)概念。當(dāng)某個(gè)LBP所對(duì)應(yīng)的循環(huán)二進(jìn)制數(shù)從0到1或從1到0最多有兩次跳變時(shí),該LBP所對(duì)應(yīng)的二進(jìn)制就稱為一個(gè)等價(jià)模式類。如00000000(0次跳變),00000111(只含一次從0到1的跳變),10001111(先由1跳到0,再由0跳到1,共兩次跳變)都是等價(jià)模式類。

這里對(duì)“模式”進(jìn)行具體闡述:“模式”可以理解為L(zhǎng)BP特征值的范圍、種類等等。比如常用的3*3大小的正方形LBP算子的LBP模式就是256。引入這個(gè)“等價(jià)模式”主要是想要減少模式的數(shù)量,方便運(yùn)算。

在統(tǒng)計(jì)時(shí)可以將這些等價(jià)模式對(duì)應(yīng)的LBP的值按照大小進(jìn)行映射;將其他不等價(jià)的模式歸為一類。

比如,一種常用的操作就是將256中LBP算子中58種等價(jià)模式按照大小映射到0-57中,將其余的不屬于等價(jià)模式的值規(guī)定為58。比如0被映射為0,255(也是一個(gè)等價(jià)模式,0次跳變)就被映射為57。具體操作可以再下面的代碼中進(jìn)一步查看。當(dāng)然,讀者也可以根據(jù)需要自己定義其他的映射法則。

經(jīng)過這種等價(jià)操作,模式數(shù)量從2P種減少為 P(P-1)+2種。

四、提取LBP算子的步驟

  • 首先將檢測(cè)窗口劃分為16×16的小區(qū)域(cell)

  • 對(duì)于每個(gè)cell中的一個(gè)像素,將相鄰的8個(gè)像素的灰度值與其進(jìn)行比較,若周圍像素值大于中心像素值,則該像素點(diǎn)的位置被標(biāo)記為1,否則為0。這樣,3×3鄰域內(nèi)的8個(gè)點(diǎn)經(jīng)比較可產(chǎn)生8位二進(jìn)制數(shù),即得到該窗口中心像素點(diǎn)的LBP值;

  • 然后計(jì)算每個(gè)cell的直方圖,即每個(gè)數(shù)字(假定是十進(jìn)制數(shù)LBP值)出現(xiàn)的頻率;然后對(duì)該直方圖進(jìn)行歸一化處理。

  • 最后_將得到的每個(gè)cell的統(tǒng)計(jì)直方圖連接成為一個(gè)特征向量_,也就是整幅圖的LBP紋理特征向量;

  • 最后便可利用SVM或者其他機(jī)器學(xué)習(xí)算法進(jìn)行分類了。

五、提取效果

下圖展示的效果依次為原圖、圓形LBP算子提取結(jié)果、旋轉(zhuǎn)不變LBP結(jié)果和等價(jià)模式的提取結(jié)果。

六、代碼實(shí)現(xiàn)

對(duì)于初學(xué)者來說,手寫代碼實(shí)現(xiàn)提取特征效果能夠鍛煉代碼能力和加強(qiáng)對(duì)特征的理解,讀者可以參照下面的代碼進(jìn)行學(xué)習(xí)。

import cv2
import numpy as np
import matplotlib.pyplot as plt


class LBP():
    def __init__(self, img,cell_size):
        self.img = img #灰度圖
        self.height, self.width = img.shape[:2]
        self.cell_size = cell_size
    
    # 傳進(jìn)來一個(gè)int型8位整數(shù) 找到旋轉(zhuǎn)后最小的值
    def find_min(self,code):
        min = code
        for i in range(8):
            code = (code << 1) | (code >> 7)
            if code < min:
                min = code
        return min
            

    def lbp_circle(self):
        # 圓形LBP算子 這里寫成了P=8,R=1 實(shí)際上這個(gè)與矩形3*3的LBP算子是一樣的
        lbp = np.zeros((self.height, self.width), np.uint8) #統(tǒng)計(jì)的lbp是比原來少2行2列的,這里為了方便拆分成cell直接把四周的lbp的值置為0
        for i in range(1, self.height - 1):
            for j in range(1, self.width - 1):
                center = self.img[i, j]
                code = 0
                code |= (self.img[i - 1, j - 1] >= center) << 7
                code |= (self.img[i - 1, j] >= center) << 6
                code |= (self.img[i - 1, j + 1] >= center) << 5
                code |= (self.img[i, j + 1] >= center) << 4
                code |= (self.img[i + 1, j + 1] >= center) << 3
                code |= (self.img[i + 1, j] >= center) << 2
                code |= (self.img[i + 1, j - 1] >= center) << 1
                code |= (self.img[i, j - 1] >= center) << 0
                lbp[i, j] = code
        return lbp
    
    # 旋轉(zhuǎn)不變模式
    def lbp_uniform(self):
        lbp = self.lbp_circle()
        # 圓形LBP算子 這里寫成了P=8,R=1 實(shí)際上這個(gè)與矩形3*3的LBP算子是一樣的
        lbp_uniform= np.zeros((self.height, self.width), np.uint8) #統(tǒng)計(jì)的lbp是比原來少2行2列的,這里為了方便拆分成cell直接把四周的lbp的值置為0
        # 旋轉(zhuǎn)不變模式 找到旋轉(zhuǎn)中的最小值
        for i in range(1, self.height - 1):
            for j in range(1, self.width - 1):
                lbp_uniform[i,j] = self.find_min(lbp[i, j])
        return lbp_uniform
    
    # 等價(jià)模式 這里將等價(jià)的模式按照大小映射到0-57中,然后將不等價(jià)模式標(biāo)記為58
    def lbp_equivalent(self):
        # 定義等價(jià)模式的字典
        uniform_map = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 6: 5, 7: 6, 8: 7, 12: 8,14: 9, 15: 10, 16: 11, 24: 12, 28: 13, 30: 14, 31: 15, 32: 16, 48: 17,
                         56: 18, 60: 19, 62: 20, 63: 21, 64: 22, 96: 23, 112: 24,120: 25, 124: 26, 126: 27, 127: 28, 128: 29, 129: 30, 131: 31, 135: 32,143: 33,
                         159: 34, 191: 35, 192: 36, 193: 37, 195: 38, 199: 39, 207: 40,223: 41, 224: 42, 225: 43, 227: 44, 231: 45, 239: 46, 240: 47, 241: 48,
                         243: 49, 247: 50, 248: 51, 249: 52, 251: 53, 252: 54, 253: 55, 254: 56,255: 57}
        lbp_equivalent = np.zeros((self.height, self.width), np.uint8) #統(tǒng)計(jì)的lbp是比原來少2行2列的,這里為了方便拆分成cell直接把四周的lbp的值置為0
        lbp = self.lbp_circle()
        for i in range(1, self.height - 1):
            for j in range(1, self.width - 1):
                if lbp[i, j] in uniform_map:
                    # 按照字典序賦值
                    lbp_equivalent[i, j] = uniform_map[lbp[i, j]]
                else:
                    lbp_equivalent[i, j] = 58
        return lbp_equivalent
    
    # 統(tǒng)計(jì)每個(gè)cell的直方圖 并對(duì)其進(jìn)行歸一化 這里使用的是L2范數(shù)歸一化
    def lbp_histogram(self,lbp):
        bin_size = lbp.max() + 1 # 獲取直方圖的維數(shù)
        # 統(tǒng)計(jì)每個(gè)cell的直方圖
        cell_histogram = np.zeros((self.height // self.cell_size, self.width // self.cell_size, bin_size), np.float32) 
        for i in range(self.height // self.cell_size):
            for j in range(self.width // self.cell_size):
                cell = lbp[i * self.cell_size:(i + 1) * self.cell_size, j * self.cell_size:(j + 1) * self.cell_size]
                cell_histogram[i, j] = np.bincount(cell.flatten(), minlength=bin_size)
              # 對(duì)每個(gè)cell的直方圖進(jìn)行歸一化 這里使用的是L2范數(shù)歸一化
        for i in range(self.height // self.cell_size):
            for j in range(self.width // self.cell_size):
                cell_histogram[i, j] = cell_histogram[i, j] / np.linalg.norm(cell_histogram[i, j])
        return cell_histogram
   
    # 拼接每個(gè)cell,得到最后的LBP特征向量
    def lbp_feature(self,lbp):
        cell_histogram = self.lbp_histogram(lbp)
        # 拼接每個(gè)cell,得到最后的LBP特征向量 是一個(gè)一維向量
        lbp_feature = np.zeros((cell_histogram.shape[0] * cell_histogram.shape[1] * cell_histogram.shape[2]), np.float32)
        for i in range(cell_histogram.shape[0]):
            for j in range(cell_histogram.shape[1]):
                for k in range(cell_histogram.shape[2]):
                    lbp_feature[i * cell_histogram.shape[1] * cell_histogram.shape[2] + j * cell_histogram.shape[2] + k] = cell_histogram[i, j, k]
        return lbp_feature
        
if __name__ == '__main__':
    img = cv2.imread('1.png')
    # 灰度圖讀取
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    lbp = LBP(img,16) #這里設(shè)置cell大小為16*16
    lbp_circle = lbp.lbp_circle()
    lbp_uniform = lbp.lbp_uniform()
    lbp_equivalent = lbp.lbp_equivalent()
    print("圓形LBP特征向量:",lbp.lbp_feature(lbp_circle))  # 圓形LBP特征向量
    print("旋轉(zhuǎn)不變LBP特征向量:",lbp.lbp_feature(lbp_uniform))  # 旋轉(zhuǎn)不變LBP特征向量
    print("等價(jià)LBP特征向量:",lbp.lbp_feature(lbp_equivalent))  # 等價(jià)LBP特征向量

     # 顯示原圖和 lbp
    img = cv2.imread('1.png')
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 將 BGR 轉(zhuǎn)換為 RGB 以正確顯示
    plt.subplot(2, 2, 1)
    plt.imshow(img)
    plt.title('Original Image')
    plt.subplot(2, 2, 2)
    plt.imshow(lbp_circle, cmap='gray',vmin=0, vmax=255)
    plt.title('LBP Circle')
    plt.subplot(2, 2, 3)
    plt.imshow(lbp_uniform, cmap='gray',vmin=0, vmax=255)
    plt.title('LBP Uniform')
    plt.subplot(2, 2, 4)
    plt.imshow(lbp_equivalent, cmap='gray',vmin=0, vmax=255)
    plt.title('LBP Equivalent')

    # 保存圖像
    plt.savefig('1_lbp_result.png')

    plt.show()

到此這篇關(guān)于使用Python實(shí)現(xiàn)圖像LBP特征提取的操作方法的文章就介紹到這了,更多相關(guān)Python 圖像LBP提取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python中使用format函數(shù)的小結(jié)

    Python中使用format函數(shù)的小結(jié)

    在Python中,format()函數(shù)是一種用于格式化字符串的方法主要介紹了Python中使用format函數(shù)的小結(jié),本文就來介紹一下format()函數(shù)的使用示例,感興趣的可以了解一下
    2023-08-08
  • Django在pycharm下修改默認(rèn)啟動(dòng)端口的方法

    Django在pycharm下修改默認(rèn)啟動(dòng)端口的方法

    今天小編就為大家分享一篇Django在pycharm下修改默認(rèn)啟動(dòng)端口的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python pyecharts Line折線圖的具體實(shí)現(xiàn)

    Python pyecharts Line折線圖的具體實(shí)現(xiàn)

    折線圖在很多圖標(biāo)中都有使用,本文主要介紹了Python pyecharts Line折線圖的具體實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Django如何利用uwsgi和nginx修改代碼自動(dòng)重啟

    Django如何利用uwsgi和nginx修改代碼自動(dòng)重啟

    這篇文章主要介紹了Django如何利用uwsgi和nginx修改代碼自動(dòng)重啟問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Python切片工具pillow用法示例

    Python切片工具pillow用法示例

    這篇文章主要介紹了Python切片工具pillow用法,結(jié)合實(shí)例形式分析了Python中pillow的簡(jiǎn)單安裝與使用操作技巧,需要的朋友可以參考下
    2018-03-03
  • 使用python快速實(shí)現(xiàn)不同機(jī)器間文件夾共享方式

    使用python快速實(shí)現(xiàn)不同機(jī)器間文件夾共享方式

    今天小編就為大家分享一篇使用python快速實(shí)現(xiàn)不同機(jī)器間文件夾共享方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python字符串函數(shù)strip()原理及用法詳解

    Python字符串函數(shù)strip()原理及用法詳解

    這篇文章主要介紹了Python字符串函數(shù)strip()原理及用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • pytorch-神經(jīng)網(wǎng)絡(luò)擬合曲線實(shí)例

    pytorch-神經(jīng)網(wǎng)絡(luò)擬合曲線實(shí)例

    今天小編就為大家分享一篇pytorch-神經(jīng)網(wǎng)絡(luò)擬合曲線實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 利用PyQt5制作一個(gè)豆瓣電影信息查看器

    利用PyQt5制作一個(gè)豆瓣電影信息查看器

    這篇文章主要介紹了如何通過PyQt5制作一個(gè)查看器,可以查看豆瓣前100名電影的信息,當(dāng)然這個(gè)爬取信息比較簡(jiǎn)單。感興趣的小伙伴可以試一試
    2022-01-01
  • Python中Permission denied的解決方案

    Python中Permission denied的解決方案

    這篇文章主要介紹了Python中Permission denied的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評(píng)論