日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > 【計(jì)算機(jī)視覺】OpenCV人臉識別facerec源碼分析2――LBPH概述

【計(jì)算機(jī)視覺】OpenCV人臉識別facerec源碼分析2――LBPH概述

來源:程序員人生   發(fā)布時(shí)間:2015-04-07 08:14:58 閱讀次數(shù):9410次

人臉辨認(rèn)

從OpenCV2.4開始,加入了新的類FaceRecognizer,我們可使用它便捷地進(jìn)行人臉辨認(rèn)實(shí)驗(yàn)。其源代碼可以在OpenCV中的opencvmodulescontribdocfacerecsrc下找到。
目前支持的算法有:

Eigenfaces特點(diǎn)臉createEigenFaceRecognizer()
Fisherfaces createFisherFaceRecognizer()
Local Binary Patterns Histograms局部2值直方圖 createLBPHFaceRecognizer()

自動(dòng)人臉辨認(rèn)就是如何從1幅圖象中提取成心義的特點(diǎn),把它們放入1種有用的表示方式,然后對他們進(jìn)行1些分類。
特點(diǎn)臉方法描寫了1個(gè)全面的方法來辨認(rèn)人臉:臉部圖象是1個(gè)點(diǎn),這個(gè)點(diǎn)是從高維圖象空間找到它在低維空間的表示,這樣分類變得很簡單。低維子空間低維是使用主元分析(Principal Component Analysis,PCA)找到的,它可以找具有最大方差的那個(gè)軸。雖然這樣的轉(zhuǎn)換是從最好重建角度斟酌的,但是他沒有把標(biāo)簽問題斟酌進(jìn)去。想象1個(gè)情況,如果變化是基于外部來源,比如光照。軸的最大方差不1定包括任何有鑒別性的信息,因此此時(shí)的分類是不可能的。因此,1個(gè)使用線性鑒別(Linear Discriminant Analysis,LDA)的特定類投影方法被提出來解決人臉辨認(rèn)問題。其中1個(gè)基本的想法就是,使類內(nèi)方差最小的同時(shí),使類外方差最大。
最近幾年來,各種局部特點(diǎn)提取方法出現(xiàn)。為了不輸入的圖象的高維數(shù)據(jù),僅僅使用的局部特點(diǎn)描寫圖象的方法被提出,提取的特點(diǎn)(很有希望的)對局部遮擋、光照變化、小樣本等情況更強(qiáng)健。有關(guān)局部特點(diǎn)提取的方法有蓋伯小波(Gabor Waelets),離散傅立葉變換(Discrete Cosinus Transform,DCT),局部2值模式(Local Binary Patterns,LBP)。使用甚么方法來提取時(shí)域空間的局部特點(diǎn)照舊是1個(gè)開放性的研究問題,由于空間信息是潛伏有用的信息。

局部2值模式直方圖Local Binary Patterns Histograms

由于Eigenfaces和Fisherfaces兩種方法當(dāng)引入新的人臉數(shù)據(jù)時(shí)需要重新進(jìn)行訓(xùn)練,所以這里我側(cè)重介紹LBP特點(diǎn)的有關(guān)內(nèi)容。

Eigenfaces和Fisherfaces使用整體方法來進(jìn)行人臉辨認(rèn)[gm:直接使用所有的像素]。你把你的數(shù)據(jù)當(dāng)作圖象空間的高維向量。我們都知道高維數(shù)據(jù)是糟的,所以1個(gè)低維子空間被肯定,對信息保存可能很好。Eigenfaces是最大化總的散度,這樣可能致使,當(dāng)方差由外部條件產(chǎn)生時(shí),最大方差的主成份不合適用來分類。所以為使用1些鑒別分析,我們使用了LDA方法來優(yōu)化。Fisherfaces方法可以很好的運(yùn)作,最少在我們假定的模型的有限情況下。
現(xiàn)實(shí)生活是不完善的。你沒法保證在你的圖象中光照條件是完善的,或說1個(gè)人的10張照片。所以,如果每人僅僅只有1張照片呢?我們的子空間的協(xié)方差估計(jì)方法可能完全毛病,所以辨認(rèn)也可能毛病。
1些研究專注于圖象局部特點(diǎn)的提取。主張是我們不把全部圖象看成1個(gè)高維向量,僅僅用局部特點(diǎn)來描寫1個(gè)物體。通過這類方式提取特點(diǎn),你將取得1個(gè)低維隱式。1個(gè)好主張!但是你很快發(fā)現(xiàn)這類圖象表示方法不單單遭受光照變化。你想一想圖象中的尺度變化、形變、旋轉(zhuǎn)―我們的局部表示方式最少對這些情況比較穩(wěn)健。正如SIFT,LBP方法在2D紋理分析及第足輕重。LBP的基本思想是對圖象的像素和它局部周圍像素進(jìn)行對照后的結(jié)果進(jìn)行求和。把這個(gè)像素作為中心,對相鄰像素進(jìn)行閾值比較。如果中心像素的亮度大于等于他的相鄰像素,把他標(biāo)記為1,否則標(biāo)記為0。你會用2進(jìn)制數(shù)字來表示每一個(gè)像素,比如11001111。因此,由于周圍相鄰8個(gè)像素,你終究可能獲得2^8個(gè)可能組合,被稱為局部2值模式,有時(shí)被稱為LBP碼。第1個(gè)在文獻(xiàn)中描寫的LBP算籽實(shí)際使用的是3*3的鄰域。

算法描寫

1個(gè)更加正式的LBP操作可以被定義為:

其中(xc,yc)是中心像素,亮度是ic;而in是相鄰像素的亮度。s是1個(gè)符號函數(shù)。
這類描寫方法使得你可以很好的捕捉到圖象中的細(xì)節(jié)。實(shí)際上,研究者們可以用它在紋理分類上得到最早進(jìn)的水平。正如剛才描寫的方法被提出后,固定的近鄰區(qū)域?qū)Τ叨茸兓木幋a失效。所以,使用1個(gè)變量的擴(kuò)大方法是使用可變半徑的圓對近鄰像素進(jìn)行編碼,這樣可以捕捉到以下的近鄰:

對1個(gè)給定的點(diǎn)(xc,yc),他的近鄰點(diǎn)(xp,yp),p∈P可以由以下計(jì)算:

其中,R是圓的半徑,而P是樣本點(diǎn)的個(gè)數(shù)。

這個(gè)操作是對原始LBP算子的擴(kuò)大,所以有時(shí)被稱為擴(kuò)大LBP(又稱為圓形LBP)。如果1個(gè)在圓上的點(diǎn)不在圖象坐標(biāo)上,我們使用他的內(nèi)插點(diǎn)。計(jì)算機(jī)科學(xué)有1堆聰明的插值方法,而OpenCV使用雙線性插值。

LBP算子,對灰度的單調(diào)變化很穩(wěn)健。我們可以看得手工改變后的圖象的LBP圖象。

那末剩下來的就是如何合并空間信息用于人臉辨認(rèn)模型。對LBP圖象成m個(gè)塊,每一個(gè)塊提取直方圖。通過連接局部特直方圖(而不是合并)然后就可以得到空間增強(qiáng)的特點(diǎn)向量。這些直方圖被稱為局部2值模式直方圖。

源碼分析

LBPH類聲明

class LBPH : public FaceRecognizer { private: int _grid_x; int _grid_y; int _radius; int _neighbors; double _threshold; vector<Mat> _histograms; Mat _labels; // Computes a LBPH model with images in src and // corresponding labels in labels, possibly preserving // old model data. void train(InputArrayOfArrays src, InputArray labels, bool preserveData); public: using FaceRecognizer::save; using FaceRecognizer::load; // Initializes this LBPH Model. The current implementation is rather fixed // as it uses the Extended Local Binary Patterns per default. // // radius, neighbors are used in the local binary patterns creation. // grid_x, grid_y control the grid size of the spatial histograms. LBPH(int radius_=1, int neighbors_=8, int gridx=8, int gridy=8, double threshold = DBL_MAX) : _grid_x(gridx), _grid_y(gridy), _radius(radius_), _neighbors(neighbors_), _threshold(threshold) {} // Initializes and computes this LBPH Model. The current implementation is // rather fixed as it uses the Extended Local Binary Patterns per default. // // (radius=1), (neighbors=8) are used in the local binary patterns creation. // (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms. LBPH(InputArrayOfArrays src, InputArray labels, int radius_=1, int neighbors_=8, int gridx=8, int gridy=8, double threshold = DBL_MAX) : _grid_x(gridx), _grid_y(gridy), _radius(radius_), _neighbors(neighbors_), _threshold(threshold) { train(src, labels); } ~LBPH() { } // Computes a LBPH model with images in src and // corresponding labels in labels. void train(InputArrayOfArrays src, InputArray labels); // Updates this LBPH model with images in src and // corresponding labels in labels. void update(InputArrayOfArrays src, InputArray labels); // Predicts the label of a query image in src. int predict(InputArray src) const; // Predicts the label and confidence for a given sample. void predict(InputArray _src, int &label, double &dist) const; // See FaceRecognizer::load. void load(const FileStorage& fs); // See FaceRecognizer::save. void save(FileStorage& fs) const; // Getter functions. int neighbors() const { return _neighbors; } int radius() const { return _radius; } int grid_x() const { return _grid_x; } int grid_y() const { return _grid_y; } AlgorithmInfo* info() const; };

構(gòu)建LBPH實(shí)例

//聲明 Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold=DBL_MAX); //定義 Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors, int grid_x, int grid_y, double threshold) { return new LBPH(radius, neighbors, grid_x, grid_y, threshold); }

參數(shù)說明:
* radius :該參數(shù)用于構(gòu)建圓LBP特點(diǎn)。
* neighbors :該參數(shù)是構(gòu)建圓LBP特點(diǎn)所需要的近鄰像素的個(gè)數(shù),經(jīng)常使用是8個(gè)采樣點(diǎn)。采樣點(diǎn)越多,計(jì)算代價(jià)越大。
* grid_x : 該參數(shù)是水平方向上劃分的格子塊個(gè)數(shù),常規(guī)是8個(gè)。區(qū)塊越多,終究構(gòu)建結(jié)果的特點(diǎn)向量的維度越高。
* grid_y : 該參數(shù)是垂直方向上劃分的格子塊個(gè)數(shù),常規(guī)是8個(gè)。
* threshold : 該閾值用于預(yù)測。如果最近鄰的距離大于該閾值,預(yù)測的方法返回⑴。

LBPH的訓(xùn)練進(jìn)程

下面給出了LBPH訓(xùn)練函數(shù)train的源碼,再進(jìn)行分析。

void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels, bool preserveData) { if(_in_src.kind() != _InputArray::STD_VECTOR_MAT && _in_src.kind() != _InputArray::STD_VECTOR_VECTOR) { string error_message = "The images are expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >)."; CV_Error(CV_StsBadArg, error_message); } if(_in_src.total() == 0) { string error_message = format("Empty training data was given. You'll need more than one sample to learn a model."); CV_Error(CV_StsUnsupportedFormat, error_message); } else if(_in_labels.getMat().type() != CV_32SC1) { string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _in_labels.type()); CV_Error(CV_StsUnsupportedFormat, error_message); } // get the vector of matrices vector<Mat> src; _in_src.getMatVector(src); // get the label matrix Mat labels = _in_labels.getMat(); // check if data is well- aligned if(labels.total() != src.size()) { string error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", src.size(), _labels.total()); CV_Error(CV_StsBadArg, error_message); } // if this model should be trained without preserving old data, delete old model data if(!preserveData) { _labels.release(); _histograms.clear(); } // append labels to _labels matrix for(size_t labelIdx = 0; labelIdx < labels.total(); labelIdx++) { _labels.push_back(labels.at<int>((int)labelIdx)); } // store the spatial histograms of the original data for(size_t sampleIdx = 0; sampleIdx < src.size(); sampleIdx++) { // calculate lbp image Mat lbp_image = elbp(src[sampleIdx], _radius, _neighbors); // get spatial histogram from this lbp image Mat p = spatial_histogram( lbp_image, /* lbp_image */ static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */ _grid_x, /* grid size x */ _grid_y, /* grid size y */ true); // add to templates _histograms.push_back(p); } }

訓(xùn)練進(jìn)程分為以下幾個(gè)進(jìn)程:

  1. 首先進(jìn)行必要的毛病檢查,得到人臉圖象向量和標(biāo)簽向量
  2. 計(jì)算lbp圖象
  3. 根據(jù)lbp圖象得到空間直方圖
  4. 將空間直方圖矩陣納入到私有變量_histograms向量中

生成lbp空間直方圖的進(jìn)程:
* elbp函數(shù)用于生成lbp圖象。
* spatial_histogram函數(shù)用于將lbp圖象分塊,對每個(gè)區(qū)塊進(jìn)行直方圖統(tǒng)計(jì)。

LBPH的預(yù)測進(jìn)程

下面給出了LBPH預(yù)測函數(shù)predict的源碼,再進(jìn)行分析。

void LBPH::predict(InputArray _src, int &minClass, double &minDist) const { if(_histograms.empty()) { // throw error if no data (or simply return ⑴?) string error_message = "This LBPH model is not computed yet. Did you call the train method?"; CV_Error(CV_StsBadArg, error_message); } Mat src = _src.getMat(); // get the spatial histogram from input image Mat lbp_image = elbp(src, _radius, _neighbors); Mat query = spatial_histogram( lbp_image, /* lbp_image */ static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */ _grid_x, /* grid size x */ _grid_y, /* grid size y */ true /* normed histograms */); // find 1-nearest neighbor minDist = DBL_MAX; minClass = -1; for(int sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) { double dist = compareHist(_histograms[sampleIdx], query, CV_COMP_CHISQR); if((dist < minDist) && (dist < _threshold)) { minDist = dist; minClass = _labels.at<int>(sampleIdx); } } }

預(yù)測進(jìn)程就比較簡單了,首先將待查詢點(diǎn)圖象進(jìn)行l(wèi)bp編碼并生成空間直方圖,然后線性暴力的計(jì)算直方圖的距離,終究輸出距離最小的預(yù)測種別。

compareHist函數(shù)
通過cv::compareHist函數(shù)來評估兩個(gè)直方圖有多么不同、或多么類似,返回丈量距離。
類似度衡量的辦法目前支持4種:

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 91av在线免费观看 | 欧美成人福利 | 成人午夜毛片 | 久久se精品一区精品二区 | 西欧free性video巴西 | 精品一区久久 | 国内精品免费 | 密臀av| 综合久久久久久久久久 | av中文天堂| 国产精品黄色在线观看 | 欧美第一页 | 99精品欧美一区二区三区综合在线 | 精品999久久久 | 国产一区二区三区网站 | 久久欧美| 国内精品视频在线 | 嫩草导航 | 九九综合久久 | 国产精品麻豆欧美日韩ww | 97久久超碰国产精品2021 | 国产精品久久久久久一区二区三区 | 免费黄色小网站 | 九九九久久久久久久 | 国产精品裸体一区二区三区 | 国产精品久久久久久吹潮 | 国产精品网址 | 亚洲精品视频在线 | 免费观看不卡av | 久草福利在线视频 | 91精品国产高清久久久久久久久 | 国产露脸国语对白在线 | 黄色网页大全 | 国产高清免费 | 成人亚洲综合 | 蜜桃精品一区二区三区 | 草草网| 丰满少妇久久久久久久 | 精品久久久一区二区 | 亚洲午夜视频在线观看 | 国产欧美日韩在线观看 |