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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像特征提取之LBP特征

發(fā)布時(shí)間:2023/12/31 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像特征提取之LBP特征 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文站點(diǎn):https://senitco.github.io/2017/06/12/image-feature-lbp/

??局部二值模式(Local Binary Patter, LBP)是一種用來描述圖像局部紋理特征的算子,LBP特征具有灰度不變性和旋轉(zhuǎn)不變性等顯著優(yōu)點(diǎn),它將圖像中的各個(gè)像素與其鄰域像素值進(jìn)行比較,將結(jié)果保存為二進(jìn)制數(shù),并將得到的二進(jìn)制比特串作為中心像素的編碼值,也就是LBP特征值。LBP提供了一種衡量像素間鄰域關(guān)系的特征模式,因此可以有效地提取圖像的局部特征,而且由于其計(jì)算簡(jiǎn)單,可用于基于紋理分類的實(shí)時(shí)應(yīng)用場(chǎng)景,例如目標(biāo)檢測(cè)、人臉識(shí)別等。

原始LBP特征

??原始的LBP算子定義于圖像中3×3的鄰域窗口,取窗口內(nèi)中心像素的灰度值作為閾值,將8鄰域像素的灰度值與其進(jìn)行比較,若鄰域像素值大于中心像素值,則比較結(jié)果取值為1,否則為0。這樣鄰域內(nèi)的8個(gè)像素點(diǎn)經(jīng)過比較后可得到8位二進(jìn)制數(shù),將其按順序依次排列即可得到中心像素的LBP值。LBP特征值反映了中心像素和其鄰域的紋理信息。LBP的取值一共有28=256種,和一幅普通的灰度圖像類似,因此可將LBP特征以灰度圖的形式表達(dá)出來。由于LBP特征考慮的是紋理信息,而不包含顏色信息,因此彩色圖需轉(zhuǎn)換為灰度圖。原始LBP特征的提取過程如下圖所示:


公式定義如下:

LBP(xc,yc)=ΣP?1p=02ps(ip?ic)
其中 (xc,yc)代表鄰域窗口內(nèi)的中心像素,其像素值為 ic ip為鄰域內(nèi)其他像素值,s(x)是符號(hào)函數(shù)。
原始LBP特征的實(shí)現(xiàn)代碼(OpenCV)如下:

template <typename _tp> void getOriginLBPFeature(InputArray _src,OutputArray _dst) {Mat src = _src.getMat();_dst.create(src.rows-2,src.cols-2,CV_8UC1);Mat dst = _dst.getMat();dst.setTo(0);for(int i=1;i<src.rows-1;i++){for(int j=1;j<src.cols-1;j++){_tp center = src.at<_tp>(i,j);unsigned char lbpCode = 0;lbpCode |= (src.at<_tp>(i-1,j-1) > center) << 7;lbpCode |= (src.at<_tp>(i-1,j ) > center) << 6;lbpCode |= (src.at<_tp>(i-1,j+1) > center) << 5;lbpCode |= (src.at<_tp>(i ,j+1) > center) << 4;lbpCode |= (src.at<_tp>(i+1,j+1) > center) << 3;lbpCode |= (src.at<_tp>(i+1,j ) > center) << 2;lbpCode |= (src.at<_tp>(i+1,j-1) > center) << 1;lbpCode |= (src.at<_tp>(i ,j-1) > center) << 0;dst.at<uchar>(i-1,j-1) = lbpCode;}} }

圓形LBP特征(Circular LBP or Extended LBP)

??原始LBP特征考慮的是固定半徑范圍內(nèi)的鄰域像素,不能滿足不同尺寸和頻率紋理的需求,當(dāng)圖像的尺寸發(fā)生變化時(shí),LBP特征將不能正確編碼局部鄰域的紋理信息。為了適應(yīng)不同尺寸的紋理特征,Ojala等人對(duì)LBP算子
進(jìn)行了改進(jìn),將3×3鄰域窗口擴(kuò)展到任意鄰域,并用圓形鄰域代替了正方形鄰域,改進(jìn)后的LBP算子允許在半徑為R的鄰域內(nèi)有任意多個(gè)像素點(diǎn),從而得到在半徑為R的區(qū)域內(nèi)含有P個(gè)采樣點(diǎn)的LBP算子。


采樣點(diǎn)的坐標(biāo)可通過以下公式計(jì)算:

xp=xc+Rcos(2πp/P)
yp=yc+Rsin(2πp/P)
其中 (xc,yc)為中心像素點(diǎn), (xp,yp),pP為鄰域內(nèi)某個(gè)采樣點(diǎn),通過上次可以計(jì)算任意個(gè)采樣點(diǎn)的坐標(biāo),但是得到的坐標(biāo)值未必為整數(shù),因此可通過雙線性插值的方法來得到該采樣點(diǎn)的像素值:
f(x,y)=[1?xx][f(0,0)?f(1,0)f(0,1)f(1,1)][1?y?y]

圓形LBP特征的實(shí)現(xiàn)代碼如下:

//圓形LBP特征計(jì)算,這種方法適于理解,但在效率上存在問題,聲明時(shí)默認(rèn)neighbors=8 template <typename _tp> void getCircularLBPFeature(InputArray _src,OutputArray _dst,int radius,int neighbors) {Mat src = _src.getMat();//LBP特征圖像的行數(shù)和列數(shù)的計(jì)算要準(zhǔn)確_dst.create(src.rows-2*radius,src.cols-2*radius,CV_8UC1);Mat dst = _dst.getMat();dst.setTo(0);//循環(huán)處理每個(gè)像素for(int i=radius;i<src.rows-radius;i++){for(int j=radius;j<src.cols-radius;j++){//獲得中心像素點(diǎn)的灰度值_tp center = src.at<_tp>(i,j);unsigned char lbpCode = 0;for(int k=0;k<neighbors;k++){//根據(jù)公式計(jì)算第k個(gè)采樣點(diǎn)的坐標(biāo),這個(gè)地方可以優(yōu)化,不必每次都進(jìn)行計(jì)算radius*cos,radius*sinfloat x = i + static_cast<float>(radius * \cos(2.0 * CV_PI * k / neighbors));float y = j - static_cast<float>(radius * \sin(2.0 * CV_PI * k / neighbors));//根據(jù)取整結(jié)果進(jìn)行雙線性插值,得到第k個(gè)采樣點(diǎn)的灰度值//1.分別對(duì)x,y進(jìn)行上下取整int x1 = static_cast<int>(floor(x));int x2 = static_cast<int>(ceil(x));int y1 = static_cast<int>(floor(y));int y2 = static_cast<int>(ceil(y));//2.計(jì)算四個(gè)點(diǎn)(x1,y1),(x1,y2),(x2,y1),(x2,y2)的權(quán)重//下面的權(quán)重計(jì)算方式有個(gè)問題,如果四個(gè)點(diǎn)都相等,則權(quán)重全為0,計(jì)算出來的插值為0//float w1 = (x2-x)*(y2-y); //(x1,y1)//float w2 = (x2-x)*(y-y1); //(x1,y2)//float w3 = (x-x1)*(y2-y); //(x2,y1)//float w4 = (x-x1)*(y-y1); //(x2,y2)//將坐標(biāo)映射到0-1之間float tx = x - x1;float ty = y - y1;//根據(jù)0-1之間的x,y的權(quán)重計(jì)算公式計(jì)算權(quán)重float w1 = (1-tx) * (1-ty);float w2 = tx * (1-ty);float w3 = (1-tx) * ty;float w4 = tx * ty;//3.根據(jù)雙線性插值公式計(jì)算第k個(gè)采樣點(diǎn)的灰度值float neighbor = src.at<_tp>(x1,y1) * w1 + src.at<_tp>(x1,y2) *w2 \+ src.at<_tp>(x2,y1) * w3 +src.at<_tp>(x2,y2) *w4;//通過比較獲得LBP值,并按順序排列起來lbpCode |= (neighbor>center) <<(neighbors-k-1);}dst.at<uchar>(i-radius,j-radius) = lbpCode;}} }

圓形LBP特征的效率優(yōu)化版本:

//圓形LBP特征計(jì)算,效率優(yōu)化版本,聲明時(shí)默認(rèn)neighbors=8 template <typename _tp> void getCircularLBPFeatureOptimization(InputArray _src,OutputArray _dst,int radius,int neighbors) {Mat src = _src.getMat();//LBP特征圖像的行數(shù)和列數(shù)的計(jì)算要準(zhǔn)確_dst.create(src.rows-2*radius,src.cols-2*radius,CV_8UC1);Mat dst = _dst.getMat();dst.setTo(0);for(int k=0;k<neighbors;k++){//計(jì)算采樣點(diǎn)對(duì)于中心點(diǎn)坐標(biāo)的偏移量rx,ryfloat rx = static_cast<float>(radius * cos(2.0 * CV_PI * k / neighbors));float ry = -static_cast<float>(radius * sin(2.0 * CV_PI * k / neighbors));//為雙線性插值做準(zhǔn)備//對(duì)采樣點(diǎn)偏移量分別進(jìn)行上下取整int x1 = static_cast<int>(floor(rx));int x2 = static_cast<int>(ceil(rx));int y1 = static_cast<int>(floor(ry));int y2 = static_cast<int>(ceil(ry));//將坐標(biāo)偏移量映射到0-1之間float tx = rx - x1;float ty = ry - y1;//根據(jù)0-1之間的x,y的權(quán)重計(jì)算公式計(jì)算權(quán)重,權(quán)重與坐標(biāo)具體位置無關(guān),與坐標(biāo)間的差值有關(guān)float w1 = (1-tx) * (1-ty);float w2 = tx * (1-ty);float w3 = (1-tx) * ty;float w4 = tx * ty;//循環(huán)處理每個(gè)像素for(int i=radius;i<src.rows-radius;i++){for(int j=radius;j<src.cols-radius;j++){//獲得中心像素點(diǎn)的灰度值_tp center = src.at<_tp>(i,j);//根據(jù)雙線性插值公式計(jì)算第k個(gè)采樣點(diǎn)的灰度值float neighbor = src.at<_tp>(i+x1,j+y1) * w1 + src.at<_tp>(i+x1,j+y2) *w2 \+ src.at<_tp>(i+x2,j+y1) * w3 +src.at<_tp>(i+x2,j+y2) *w4;//LBP特征圖像的每個(gè)鄰居的LBP值累加,累加通過與操作完成,對(duì)應(yīng)的LBP值通過移位取得dst.at<uchar>(i-radius,j-radius) |= (neighbor>center) <<(neighbors-k-1);}}} }

旋轉(zhuǎn)不變LBP特征(Rotation Invariant LBP)

??無論是原始LBP算子還是圓形LBP算子,都只是灰度不變的,而不是旋轉(zhuǎn)不變的,旋轉(zhuǎn)圖像會(huì)得到不同的LBP特征值。相關(guān)研究人員又提出了一種具有旋轉(zhuǎn)不變性的LBP算子,即不斷旋轉(zhuǎn)圓形鄰域的采樣點(diǎn),或者以不同的鄰域像素作為起始點(diǎn),順時(shí)針遍歷所有采樣點(diǎn),得到一系列編碼值(P個(gè)),取其中最小的作為該鄰域中心像素的LBP值。旋轉(zhuǎn)不變LBP算子的示意圖如下:


旋轉(zhuǎn)不變LBP特征的實(shí)現(xiàn)代碼如下:

//旋轉(zhuǎn)不變圓形LBP特征計(jì)算,聲明時(shí)默認(rèn)neighbors=8 template <typename _tp> void getRotationInvariantLBPFeature(InputArray _src,OutputArray _dst,int radius,int neighbors) {Mat src = _src.getMat();//LBP特征圖像的行數(shù)和列數(shù)的計(jì)算要準(zhǔn)確_dst.create(src.rows-2*radius,src.cols-2*radius,CV_8UC1);Mat dst = _dst.getMat();dst.setTo(0);for(int k=0;k<neighbors;k++){//計(jì)算采樣點(diǎn)對(duì)于中心點(diǎn)坐標(biāo)的偏移量rx,ryfloat rx = static_cast<float>(radius * cos(2.0 * CV_PI * k / neighbors));float ry = -static_cast<float>(radius * sin(2.0 * CV_PI * k / neighbors));//為雙線性插值做準(zhǔn)備//對(duì)采樣點(diǎn)偏移量分別進(jìn)行上下取整int x1 = static_cast<int>(floor(rx));int x2 = static_cast<int>(ceil(rx));int y1 = static_cast<int>(floor(ry));int y2 = static_cast<int>(ceil(ry));//將坐標(biāo)偏移量映射到0-1之間float tx = rx - x1;float ty = ry - y1;//根據(jù)0-1之間的x,y的權(quán)重計(jì)算公式計(jì)算權(quán)重,權(quán)重與坐標(biāo)具體位置無關(guān),與坐標(biāo)間的差值有關(guān)float w1 = (1-tx) * (1-ty);float w2 = tx * (1-ty);float w3 = (1-tx) * ty;float w4 = tx * ty;//循環(huán)處理每個(gè)像素for(int i=radius;i<src.rows-radius;i++){for(int j=radius;j<src.cols-radius;j++){//獲得中心像素點(diǎn)的灰度值_tp center = src.at<_tp>(i,j);//根據(jù)雙線性插值公式計(jì)算第k個(gè)采樣點(diǎn)的灰度值float neighbor = src.at<_tp>(i+x1,j+y1) * w1 + src.at<_tp>(i+x1,j+y2) *w2 \+ src.at<_tp>(i+x2,j+y1) * w3 +src.at<_tp>(i+x2,j+y2) *w4;//LBP特征圖像的每個(gè)鄰居的LBP值累加,累加通過與操作完成,對(duì)應(yīng)的LBP值通過移位取得dst.at<uchar>(i-radius,j-radius) |= (neighbor>center) <<(neighbors-k-1);}}}//進(jìn)行旋轉(zhuǎn)不變處理for(int i=0;i<dst.rows;i++){for(int j=0;j<dst.cols;j++){unsigned char currentValue = dst.at<uchar>(i,j);unsigned char minValue = currentValue;for(int k=1;k<neighbors;k++) //循環(huán)左移{unsigned char temp = (currentValue>>(neighbors-k)) | (currentValue<<k);if(temp < minValue){minValue = temp;}}dst.at<uchar>(i,j) = minValue;}} }

LBP等價(jià)模式(Uniform LBP)

??對(duì)于一個(gè)半徑為R的圓形區(qū)域,包含有P個(gè)鄰域采樣點(diǎn),則LBP算子可能產(chǎn)生2P種模式。隨著鄰域內(nèi)采樣點(diǎn)數(shù)的增加,LBP值的取值數(shù)量呈指數(shù)級(jí)增長(zhǎng)。例如5×5鄰域內(nèi)20個(gè)采樣點(diǎn),則對(duì)應(yīng)有220中模式,過多的二進(jìn)制模式不利于紋理信息的提取、分類、識(shí)別。例如,將LBP特征用于紋理分類或人臉識(shí)別時(shí),一般采用LBP特征的統(tǒng)計(jì)直方圖來表達(dá)圖像的信息,而較多的模式種類將使得數(shù)據(jù)量過大,且直方圖過于稀疏。因此,需要對(duì)原始的LBP特征進(jìn)行降維,使得數(shù)據(jù)量減少的情況下能最好地表達(dá)圖像的信息。
??為了解決二進(jìn)制模式過多的問題,提高統(tǒng)計(jì)性,Ojala提出了一種“等價(jià)模式”(Uniform Pattern)來對(duì)LBP特征的模式種類進(jìn)行降維。Ojala認(rèn)為,在實(shí)際圖像中,絕大數(shù)LBP模式最多只包含兩次從0到1或者從1到0的跳變,“等價(jià)模式”定義為:當(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次跳變),11000011(2次跳變)都是等價(jià)模式類。除等價(jià)模式類以外的模式都?xì)w為另一類,稱為混合模式類,例如10010111(共4次跳變)。通過改進(jìn),二進(jìn)制模式的種類大大減少,由原來的2P中降為P(P?1)+2+1種,其中P(P?1)為2次跳變的模式數(shù),2為0次跳變(全”0”或全”1”)的模式數(shù),1為混合模式的數(shù)量,由于是循環(huán)二進(jìn)制數(shù),因此’0’、’1’跳變次數(shù)不可能為奇數(shù)次。對(duì)于3×3鄰域內(nèi)8個(gè)采樣點(diǎn)來說,二進(jìn)制模式由原始的256種變?yōu)?9種。這使得特征向量的維數(shù)大大減少,并且可以減少高頻噪聲帶來的影響。實(shí)驗(yàn)表明,一般情況下,等價(jià)模式的數(shù)目占全部模式的90%以上,可以有效對(duì)數(shù)據(jù)進(jìn)行降維。下圖為58種等價(jià)模式類:


在具體實(shí)現(xiàn)中,等價(jià)模式類按值遞增從1開始編碼,混合模式類編碼為0,因此得到的LBP特征圖整體偏暗。LBP等價(jià)模式的實(shí)現(xiàn)代碼如下:

//等價(jià)模式LBP特征計(jì)算 template <typename _tp> void getUniformPatternLBPFeature(InputArray _src,OutputArray _dst,int radius,int neighbors) {Mat src = _src.getMat();//LBP特征圖像的行數(shù)和列數(shù)的計(jì)算要準(zhǔn)確_dst.create(src.rows-2*radius,src.cols-2*radius,CV_8UC1);Mat dst = _dst.getMat();dst.setTo(0);//LBP特征值對(duì)應(yīng)圖像灰度編碼表,直接默認(rèn)采樣點(diǎn)為8位uchar temp = 1;uchar table[256] = {0};for(int i=0;i<256;i++){if(getHopTimes(i)<3){table[i] = temp;temp++;}}//是否進(jìn)行UniformPattern編碼的標(biāo)志bool flag = false;//計(jì)算LBP特征圖for(int k=0;k<neighbors;k++){if(k==neighbors-1){flag = true;}//計(jì)算采樣點(diǎn)對(duì)于中心點(diǎn)坐標(biāo)的偏移量rx,ryfloat rx = static_cast<float>(radius * cos(2.0 * CV_PI * k / neighbors));float ry = -static_cast<float>(radius * sin(2.0 * CV_PI * k / neighbors));//為雙線性插值做準(zhǔn)備//對(duì)采樣點(diǎn)偏移量分別進(jìn)行上下取整int x1 = static_cast<int>(floor(rx));int x2 = static_cast<int>(ceil(rx));int y1 = static_cast<int>(floor(ry));int y2 = static_cast<int>(ceil(ry));//將坐標(biāo)偏移量映射到0-1之間float tx = rx - x1;float ty = ry - y1;//根據(jù)0-1之間的x,y的權(quán)重計(jì)算公式計(jì)算權(quán)重,權(quán)重與坐標(biāo)具體位置無關(guān),與坐標(biāo)間的差值有關(guān)float w1 = (1-tx) * (1-ty);float w2 = tx * (1-ty);float w3 = (1-tx) * ty;float w4 = tx * ty;//循環(huán)處理每個(gè)像素for(int i=radius;i<src.rows-radius;i++){for(int j=radius;j<src.cols-radius;j++){//獲得中心像素點(diǎn)的灰度值_tp center = src.at<_tp>(i,j);//根據(jù)雙線性插值公式計(jì)算第k個(gè)采樣點(diǎn)的灰度值float neighbor = src.at<_tp>(i+x1,j+y1) * w1 + src.at<_tp>(i+x1,j+y2) *w2 \+ src.at<_tp>(i+x2,j+y1) * w3 +src.at<_tp>(i+x2,j+y2) *w4;//LBP特征圖像的每個(gè)鄰居的LBP值累加,累加通過與操作完成,對(duì)應(yīng)的LBP值通過移位取得dst.at<uchar>(i-radius,j-radius) |= (neighbor>center) <<(neighbors-k-1);//進(jìn)行LBP特征的UniformPattern編碼if(flag){dst.at<uchar>(i-radius,j-radius) = table[dst.at<uchar>(i-radius,j-radius)];}}}} }//計(jì)算跳變次數(shù) int getHopTimes(int n) {int count = 0;bitset<8> binaryCode = n;for(int i=0;i<8;i++){if(binaryCode[i] != binaryCode[(i+1)%8]){count++;}}return count; }

此外,旋轉(zhuǎn)不變的Uniform LBP算子的等價(jià)模式類的數(shù)目為P+1個(gè),對(duì)于8個(gè)采樣點(diǎn),基于等價(jià)模式的旋轉(zhuǎn)不變LBP模式只有9個(gè)輸出,該模式對(duì)于上圖的Uniform LBP,每一行都是旋轉(zhuǎn)不變的,對(duì)應(yīng)同一個(gè)編碼值。

多尺度LBP(Multiscale Block LBP)

??基本LBP算子獲取的是單個(gè)像素和其鄰域像素間的紋理信息,屬于微觀特征。中科院的研究人員針對(duì)此提出了一種多尺度的LBP算子,將圖像分為一個(gè)個(gè)塊(block),再將每個(gè)塊分為一個(gè)個(gè)的小連通區(qū)域(cell),類似于HOG特征,cell內(nèi)的灰度平均值或者和值作為當(dāng)前cell的灰度閾值,與鄰域cell進(jìn)行比較得到LBP值,生成的特征即為MB-LBP,block大小為3×3,cell大小為1,就是原始的LBP特征。下圖所示block為9×9,cell為3×3


MB-LBP特征的實(shí)現(xiàn)代碼如下:

//MB-LBP特征的計(jì)算 void getMultiScaleBlockLBPFeature(InputArray _src,OutputArray _dst,int scale) {Mat src = _src.getMat();Mat dst = _dst.getMat();//定義并計(jì)算積分圖像int cellSize = scale / 3;int offset = cellSize / 2;Mat cellImage(src.rows-2*offset,src.cols-2*offset,CV_8UC1);for(int i=offset;i<src.rows-offset;i++){for(int j=offset;j<src.cols-offset;j++){int temp = 0;for(int m=-offset;m<offset+1;m++){for(int n=-offset;n<offset+1;n++){temp += src.at<uchar>(i+n,j+m);}}temp /= (cellSize*cellSize);cellImage.at<uchar>(i-cellSize/2,j-cellSize/2) = uchar(temp); }}getOriginLBPFeature<uchar>(cellImage,dst); }

多尺度模式下同樣用到了降維,論文中是直接采樣統(tǒng)計(jì)的方法對(duì)不同尺度的LBP算子的模式進(jìn)行統(tǒng)計(jì),選取占比例較高的模式,而不是利用跳變規(guī)則。具體來說,就是將得到的MB-LBP特征計(jì)算統(tǒng)計(jì)直方圖,通過對(duì)bin中的數(shù)值進(jìn)行排序以及權(quán)衡,將排序在前N(63)位的特征值看作是等價(jià)模式類,其余的為混合模式類,總共為N+1類,論文中稱之為(SEMB-LBP, Statistically Effective MB-LBP)。
SEMB-LBP的實(shí)現(xiàn)代碼如下:

//求SEMB-LBP void SEMB_LBPFeature(InputArray _src,OutputArray _dst,int scale) {Mat dst=_dst.getMat();Mat MB_LBPImage;getMultiScaleBlockLBPFeature(_src,MB_LBPImage,scale);//imshow("dst",dst);Mat histMat;int histSize = 256;float range[] = {float(0),float(255)};const float* ranges = {range};//計(jì)算LBP特征值0-255的直方圖calcHist(&MB_LBPImage,1,0,Mat(),histMat,1,&histSize,&ranges,true,false);histMat.reshape(1,1);vector<float> histVector(histMat.rows*histMat.cols);uchar table[256];memset(table,64,256);if(histMat.isContinuous()){//histVector = (int *)(histMat.data);//將直方圖histMat變?yōu)関ector向量histVectorhistVector.assign((float*)histMat.datastart,(float*)histMat.dataend);vector<float> histVectorCopy(histVector);//對(duì)histVector進(jìn)行排序,即對(duì)LBP特征值的數(shù)量進(jìn)行排序,降序排列sort(histVector.begin(),histVector.end(),greater<float>());for(int i=0;i<63;i++){for(int j=0;j<histVectorCopy.size();j++){if(histVectorCopy[j]==histVector[i]){//得到類似于Uniform的編碼表table[j]=i;}}}}dst = MB_LBPImage;//根據(jù)編碼表得到SEMB-LBPfor(int i=0;i<dst.rows;i++){for(int j=0;j<dst.cols;j++){dst.at<uchar>(i,j) = table[dst.at<uchar>(i,j)];}} }

圖像的LBP特征向量(Local Binary Patterns Histograms)

??對(duì)圖像中的每個(gè)像素求取LBP特征值可得到圖像的LBP特征圖譜,但一般不直接將LBP圖譜作為特征向量用于分類識(shí)別,而是類似于HOG特征,采用LBP特征的統(tǒng)計(jì)直方圖作為特征向量。將LBP特征圖譜劃分為若干個(gè)子連通區(qū)域,并提取每個(gè)局部塊的直方圖,然后將這些直方圖一次連接在一起形成LBP特征的統(tǒng)計(jì)直方圖(LBPH),即可用于分類識(shí)別的LBP特征向量。
LBP特征向量的具體計(jì)算過程如下:
- 按照上述算法計(jì)算圖像的LBP特征圖譜
- 將LBP特征圖譜分塊,例如分成8×8=64個(gè)區(qū)域
- 計(jì)算每個(gè)子區(qū)域中LBP特征值的統(tǒng)計(jì)直方圖,并進(jìn)行歸一化,直方圖大小為1×numPatterns
- 將所有區(qū)域的統(tǒng)計(jì)直方圖按空間順序依次連接,得到整幅圖像的LBP特征向量,大小為1×(numPatterns×64)
- 從足夠數(shù)量的樣本中提取LBP特征,并利用機(jī)器學(xué)習(xí)的方法進(jìn)行訓(xùn)練得到模型,用于分類和識(shí)別等領(lǐng)域。

??對(duì)于LBP特征向量的維度,鄰域采樣點(diǎn)為8個(gè),如果是原始的LBP特征,其模式數(shù)量為256,特征維數(shù)為64×256=16384;如果是Uniform LBP特征,其模式數(shù)量為59,特征維數(shù)為64×59=3776,使用等價(jià)模式特征,可以有效進(jìn)行數(shù)據(jù)降維,而對(duì)模型性能卻無較大影響。
LBP特征向量的實(shí)現(xiàn)代碼如下:

//計(jì)算LBP特征圖像的直方圖LBPH Mat getLBPH(InputArray _src,int numPatterns,int grid_x,int grid_y,bool normed) {Mat src = _src.getMat();int width = src.cols / grid_x;int height = src.rows / grid_y;//定義LBPH的行和列,grid_x*grid_y表示將圖像分割成這么些塊,numPatterns表示LBP值的模式種類Mat result = Mat::zeros(grid_x * grid_y,numPatterns,CV_32FC1);if(src.empty()){return result.reshape(1,1);}int resultRowIndex = 0;//對(duì)圖像進(jìn)行分割,分割成grid_x*grid_y塊,grid_x,grid_y默認(rèn)為8for(int i=0;i<grid_x;i++){for(int j=0;j<grid_y;j++){//圖像分塊Mat src_cell = Mat(src,Range(i*height,(i+1)*height),Range(j*width,(j+1)*width));//計(jì)算直方圖Mat hist_cell = getLocalRegionLBPH(src_cell,0,(numPattern-1),true);//將直方圖放到result中Mat rowResult = result.row(resultRowIndex);hist_cell.reshape(1,1).convertTo(rowResult,CV_32FC1);resultRowIndex++;}}return result.reshape(1,1); }//計(jì)算一個(gè)LBP特征圖像塊的直方圖 Mat getLocalRegionLBPH(const Mat& src,int minValue,int maxValue,bool normed) {//定義存儲(chǔ)直方圖的矩陣Mat result;//計(jì)算得到直方圖bin的數(shù)目,直方圖數(shù)組的大小int histSize = maxValue - minValue + 1;//定義直方圖每一維的bin的變化范圍float range[] = { static_cast<float>(minValue),static_cast<float>(maxValue + 1) };//定義直方圖所有bin的變化范圍const float* ranges = { range };//計(jì)算直方圖,src是要計(jì)算直方圖的圖像,1是要計(jì)算直方圖的圖像數(shù)目,0是計(jì)算直方圖所用的圖像的通道序號(hào),從0索引//Mat()是要用的掩模,result為輸出的直方圖,1為輸出的直方圖的維度,histSize直方圖在每一維的變化范圍//ranges,所有直方圖的變化范圍(起點(diǎn)和終點(diǎn))calcHist(&src,1,0,Mat(),result,1,&histSize,&ranges,true,false);//歸一化if(normed){result /= (int)src.total();}//結(jié)果表示成只有1行的矩陣return result.reshape(1,1); }

??除了以上幾種比較經(jīng)典的LBP特征外,還有諸多變種,如TLBP(中心像素與周圍所有像素比較,而不是根據(jù)采樣點(diǎn)的數(shù)目),DLBP(編碼4鄰域的灰度變化,每個(gè)方向上用兩個(gè)比特編碼),MLBP(將中心像素值替換為采樣點(diǎn)像素的平均值),VLBP,RGB-LBP等。

LBP特征的應(yīng)用

目標(biāo)檢測(cè)

??人臉檢測(cè)中比較典型的模型是Haar特征 + AdaBoost分類器,目前OpenCV也支持LBP + AdaBoost和HOG + AdaBoost的方法進(jìn)行目標(biāo)檢測(cè),而且LBP特征的訓(xùn)練速度較快,適用于實(shí)時(shí)檢測(cè)場(chǎng)景。

人臉識(shí)別

??人臉識(shí)別中LBP特征向量主要是用于直方圖的比較,通過距離度量的方式(例如方差)找到訓(xùn)練數(shù)據(jù)中與輸入圖像距離最小的特征向量,將其對(duì)應(yīng)的類別作為識(shí)別結(jié)果輸出。

reference

  • Paper: Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns
  • Paper: Multiresolution Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns
  • Paper: Face Recognition with Local Binary Patterns
  • Paper: Learning Multi-scale Block Local Binary Patterns for Face Recognition
  • http://www.voidcn.com/blog/quincuntial/article/p-4988349.html
  • http://blog.csdn.net/zouxy09/article/details/7929531
  • http://blog.jasonding.top/2014/11/04/Machine%20Learning/%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89%E3%80%91LBP%E7%BA%B9%E7%90%86%E7%89%B9%E5%BE%81/
  • http://blog.csdn.net/liulina603/article/details/8291105

總結(jié)

以上是生活随笔為你收集整理的图像特征提取之LBP特征的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。