ホームページ >よくある問題 >顔認識アルゴリズムとは何を意味しますか?

顔認識アルゴリズムとは何を意味しますか?

青灯夜游
青灯夜游オリジナル
2022-08-12 11:26:149281ブラウズ

顔認識アルゴリズムとは、顔を検出して主要な顔の特徴点を特定した後、主要な顔領域を切り出し、前処理後にバックエンド認識アルゴリズムに入力できる認識アルゴリズムを指します。認識アルゴリズムは、顔の特徴の抽出を完了し、それらをインベントリ内の既知の顔と比較して、最終的な分類を完了する必要があります。顔認識アルゴリズムの原理: システムは、身元が未決定の 1 つまたは一連の顔画像と、顔データベースまたは対応するコード内の既知の身元を持つ複数の顔画像を入力し、その出力は一連の類似性スコアを示します。認識される顔のアイデンティティ。

顔認識アルゴリズムとは何を意味しますか?

このチュートリアルの動作環境: Windows 7 システム、Dell G3 コンピューター。

顔認識とは、ビデオ収集デバイスを通じてユーザーの顔画像を取得し、コア アルゴリズムを使用して顔の特徴の位置、形状、角度を計算および分析し、それを独自のデータベースと比較することです。既存のテンプレートを比較して、ユーザーの本当の身元を判断します。

顔認識アルゴリズムとは、顔を検出して主要な顔の特徴点を特定した後、主要な顔領域を切り出し、前処理後にバックエンド認識アルゴリズムに入力できる認識アルゴリズムを指します。認識アルゴリズムは、顔の特徴の抽出を完了し、それらをインベントリ内の既知の顔と比較して、最終的な分類を完了する必要があります。

顔認識アルゴリズムには、顔の特徴点に基づく認識アルゴリズム、顔画像全体に基づく認識アルゴリズム、テンプレートベースの認識アルゴリズム、ニューラルネットワークを使用した認識アルゴリズムの4種類があります。

顔認識アルゴリズムの原理:

システム入力は通常、未確認の顔を含む 1 つまたは一連の顔画像と顔データベースです。いくつかあります。既知のアイデンティティまたはそれに対応するコードを含む顔画像。その出力は、認識される顔のアイデンティティを示す一連の類似性スコアです。

顔認識のための 3 つの古典的なアルゴリズム

1. 固有顔アルゴリズム

##Eigenfaces は、顔認識のコンピュータ ビジョン問題で使用される特徴ベクトルのセットの名前です。Eigenfaces は PCA (主成分分析) に基づいているため、Eigenfaces を学習するには、次の原理を理解する必要があります。 PCA。

基本的な考え方

主成分分析 (PCA) は、行列の次元を可能な限り削減する行列圧縮アルゴリズムです。元の行列の変換は、単に n×m 行列を n×k 行列に変換することを意味し、行列に存在する主な特徴のみを保持するため、スペースとデータ量を大幅に節約できます。 PCA の実装には次元削減、つまり行列を高次元から低次元に変換する必要がありますが、PCA の次元削減は共分散行列と切り離すことができません。分散は、1 次元のデータ サンプルの平均からの偏差を表します。これは、2 つの確率変数間の関係を測定するために使用される統計です。観点から見ると、角度が小さいほど、値は大きくなり、方向がより類似します。つまり、相関関係は正であるほど高くなります。 2 つの確率変数間の関係に加えて、共分散行列測定はサンプル間の関係ではなく、次元間の関係でもあります。

新しいこと、特に知識を学ぶには、

知識の考え方を理解する必要があります。 Eigenface アルゴリズムを理解して学ぶと、その考え方は、画像認識ではまず適切な部分空間を選択し、すべての画像をこの部分空間に集中させ、次にこの部分空間で類似性を測定するか分類学習を実行してから、それについて話す必要があるということです。この効果は、同じカテゴリの画像は近くにあり、異なるカテゴリの画像は遠く離れていることです。このようにして、線形分類によって分離された画像を新しい空間に簡単に変換できます。同時に、固有顔テクノロジーは、顔画像分布の基本要素、つまり顔画像サンプル セットの共分散行列の固有ベクトルを探して、顔画像を特徴付けます。人間の顔画像には目、頬、唇などの基本要素が多数あり、これらの特徴ベクトルに対応して固有顔の画像空間に生成される部分空間をsubface spaceと呼びます。 部分空間を生成したら空間を構築する必要がありますが、空間はどのように構築するのでしょうか。第一に、人間の顔の共通点を探す必要があります。第二に、個人と共通点の違いを探す必要があります。第三に、共通点は実際には空間であり、個人はベクトルであることを理解する必要があります。共分散行列を使用してターゲット セット内のすべての顔画像の固有値を分解し、対応する固有ベクトルを取得します。これらの固有ベクトルは「
eigenface」です。固有ベクトルの特性を見つけて、それらを線形結合します。各特徴サブフェイスに基づく空間では、各面は点であり、この点の座標が各特徴ベースの下での各面の投影座標となる。

#Eigenfaces アルゴリズム プロセス

    # 顔画像データを取得し、各顔画像行列を行ごとに 1 次元に文字列化します。各顔はベクトルです。
  • 対応する次元に M 個の顔を追加し、平均して「平均顔」を取得します;

  • 各画像ベクトルから平均顔を減算します;

  • 共分散行列の計算;

  • Reigenfaces メモリ顔認識の使用;

アルゴリズムの練習プロセス;

  • トレーニング画像

  • # 平均的な顔を見つける

  • # 特徴的なサブフェイスを取得する

  • 画像再構成を実行します。

  • 類似性の高い顔画像を見つけます。

2. FisherFace アルゴリズム

FisherFace は、顔認識におけるフィッシャー線形識別の応用です。 線形判別分析 (LDA) アルゴリズムのアイデアは、英国の統計学者および遺伝学者であり、現代統計科学の創始者の 1 人であるロナルド フィッシャー (ロナルド) によって最初に提案されました。 LDA アルゴリズムは、統計的手法を使用してオブジェクト間の特徴の線形結合を見つけ、次元を削減しながらカテゴリ情報を考慮します。このアルゴリズムによって得られた線形結合は、線形分類子として使用したり、次元削減を達成したりするために使用できます。

基本的な考え方

線形判別分析の 基本的な考え方は、高次元のパターン サンプルを低次元に投影することです。最適なベクトル空間は、重要な分類情報を抽出し、特徴空間の次元を圧縮する効果を実現できます。投影後、パターン サンプルが新しい部分空間で最大のクラス間距離と最小のクラス内距離を持つことが保証されます。つまり、この空間内でパターンの距離が最小となり、分離性に優れています。この理論は、固有面で使用される固有面に似ています。これらはどちらも、全体の次元削減と元のデータの低次元空間へのマッピングの方法です。フィッシャーフェイスと固有面はどちらも全体のデータから開始され、ローカル テクスチャを抽出する点で LBP とは異なります。特徴。

次元削減されたサンプルに対してフィッシャー線形判別法を使用して、最適な投影方向を決定し、一次元の符号空間を構築し、多次元の顔画像をフィッシャーフェイス特徴空間に投影し、クラス内サンプル データは一連の特徴ベクトルを形成し、この一連の特徴ベクトルは人間の顔の特徴を表します。

このアルゴリズムは、サンプル データが別の特徴空間にマッピングされた後、クラス内距離を最小化し、クラス間距離を最大化することがわかっています。 LDA アルゴリズムは次元削減に使用でき、このアルゴリズムの原理は PCA アルゴリズムと非常に似ているため、顔認識の分野でも使用できます。 PCAアルゴリズムを用いた顔認識アルゴリズムはEigenface法と呼ばれ、LDAアルゴリズムを用いた顔認識アルゴリズムはFisher face法と呼ばれます。

LDAPCA との比較:

  • は同じです: 1. 次元を削減するとき、どちらも行列を使用します。特徴分解のアイデア; 2どちらも、データがガウス分布に従うことを前提としています。
  • 相違点: 1. LDA は教師あり次元削減手法ですが、PCA は教師なしです。 2. データが k 次元の場合、LDA は (k-1) 次元までしか縮小できませんが、PCA はこの制限を受けません。 3. 数学的な観点から、LDA は最高の分類パフォーマンスを持つ投影方向を選択しますが、PCA はサンプル投影点の分散が最大になる方向を選択します。

Fisherfaces アルゴリズム Eigenfaces アルゴリズム との比較:

  • 同じ: どちらもデータに対して実行できます次元削減; どちらも次元を削減するときに行列固有分解の考え方を使用します。

  • 違い: Fisherfaces は教師あり次元削減手法ですが、Eigenfaces は教師なし次元削減手法であり、Fisherfaces は次元削減だけでなく分類にも使用できます。

FisherFace アルゴリズム認識のエラー率は、ハーバード大学とエール大学の顔データベースでテストされた固有顔認識結果よりも低いことは言及する価値があります。

Fisherface アルゴリズムの処理

  • 顔画像データを取得し、顔の平均値を求めます。

  • 各面の特性値を観察します。

  • 顔識別を実行し、顔の特徴を観察し、個人であるかどうかを判断します。

  • 最後に顔認証を実行します。

3. LBPH (ローカル バイナリ パターン ヒストグラム) アルゴリズム

ローカル バイナリ パターン ヒストグラムは、LBP の統計ヒストグラムです。特徴 図 LBPH は、LBP (ローカル バイナリ コーディング) 特徴と画像の空間情報を組み合わせたものです。 LBP エンコードされた画像が顔認識に直接使用される場合。実際には、LBP特徴量を抽出しないのと大きな違いはないため、実際のLBPアプリケーションでは、LBP符号化画像の統計ヒストグラムを特徴量ベクトルとして分類・認識することが一般的です。

このピクセルの位置は 1 としてマークされ、それ以外の場合は 0 になります。このようにして、33 近傍内の 8 点を比較して、8 ビットの 2 進数 (通常は 10 進数に変換される、つまり LBP コード、合計 256 種類)、つまりピクセルの LBP 値を生成できます。ウィンドウの中央の を取得し、この値を使用して領域のテクスチャ特性を反映します。

LBPH の次元: サンプリング ポイントは 8 つあります。オリジナルの LBP または拡張 LBP 特徴が使用される場合、LBP 特徴量モードは 256 で、画像の LBP 特徴ベクトルの次元は次のようになります: 64256 =16384次元、UniformPatternLBP 特徴が使用される場合、LBP 値パターンは 59、特徴ベクトルの次元は 6459=3776 次元になります。同等のパターン特徴を使用すると、特徴ベクトルの次元が大幅に削減されることがわかります。これは、パフォーマンスに大きな影響を与えることなく、機械学習手法を使用した学習時間が大幅に短縮されることを意味します。

基本的な考え方

LBPHに基づく顔認識手法基本的な考え方

は以下のとおりです。 まず、各ピクセルを中心として判断し、周囲のピクセルのグレー値間の関係をバイナリエンコードして画像全体のLBPエンコード画像を取得し、次にLBP画像を領域に分割し、各領域のLBPエンコードヒストグラムを取得して、画像全体のLBPを取得します。エンコーディング ヒストグラムは、異なる顔画像の LBP エンコーディング ヒストグラムを比較することで顔認識の目的を達成します。利点は、照明、スケーリング、回転、平行移動の影響を受けないことです。

LBPH アルゴリズム「people」は、その名の通り、識別方法に局所特徴抽出法が使用されており、これが前 2 つの方法との最大の違いです。

LBPH アルゴリズム プロセス

  • #LBP 特徴抽出: 上記の均一 LBP 演算子に従って元の画像を処理します;
  • LBP 特徴マッチング (ヒストグラムの計算): 画像をいくつかのサブ領域に分割し、ヒストグラムを判別特徴として使用し、サブ領域内の LBP 値に従ってヒストグラムをカウントします。

4. アルゴリズムの複製コード

1)、EigenFaces アルゴリズム

#encoding=utf-8
import numpy as np
import cv2
import os
 
class EigenFace(object):
    def __init__(self,threshold,dimNum,dsize):
        self.threshold = threshold # 阈值暂未使用
        self.dimNum = dimNum
        self.dsize = dsize
 
    def loadImg(self,fileName,dsize):
        '''
        载入图像,灰度化处理,统一尺寸,直方图均衡化
        :param fileName: 图像文件名
        :param dsize: 统一尺寸大小。元组形式
        :return: 图像矩阵
        '''
        img = cv2.imread(fileName)
        retImg = cv2.resize(img,dsize)
        retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY)
        retImg = cv2.equalizeHist(retImg)
        # cv2.imshow('img',retImg)
        # cv2.waitKey()
        return retImg
 
 
    def createImgMat(self,dirName):
        '''
        生成图像样本矩阵,组织形式为行为属性,列为样本
        :param dirName: 包含训练数据集的图像文件夹路径
        :return: 样本矩阵,标签矩阵
        '''
        dataMat = np.zeros((10,1))
        label = []
        for parent,dirnames,filenames in os.walk(dirName):
            # print parent
            # print dirnames
            # print filenames
            index = 0
            for dirname in dirnames:
                for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname):
                    for filename in subFilenames:
                        img = self.loadImg(subParent+'/'+filename,self.dsize)
                        tempImg = np.reshape(img,(-1,1))
                        if index == 0 :
                            dataMat = tempImg
                        else:
                            dataMat = np.column_stack((dataMat,tempImg))
                        label.append(subParent+'/'+filename)
                        index += 1
        return dataMat,label
 
 
    def PCA(self,dataMat,dimNum):
        '''
        PCA函数,用于数据降维
        :param dataMat: 样本矩阵
        :param dimNum: 降维后的目标维度
        :return: 降维后的样本矩阵和变换矩阵
        '''
        # 均值化矩阵
        meanMat = np.mat(np.mean(dataMat,1)).T
        print '平均值矩阵维度',meanMat.shape
        diffMat = dataMat-meanMat
        # 求协方差矩阵,由于样本维度远远大于样本数目,所以不直接求协方差矩阵,采用下面的方法
        covMat = (diffMat.T*diffMat)/float(diffMat.shape[1]) # 归一化
        #covMat2 = np.cov(dataMat,bias=True)
        #print '基本方法计算协方差矩阵为',covMat2
        print '协方差矩阵维度',covMat.shape
        eigVals, eigVects = np.linalg.eig(np.mat(covMat))
        print '特征向量维度',eigVects.shape
        print '特征值',eigVals
        eigVects = diffMat*eigVects
        eigValInd = np.argsort(eigVals)
        eigValInd = eigValInd[::-1]
        eigValInd = eigValInd[:dimNum] # 取出指定个数的前n大的特征值
        print '选取的特征值',eigValInd
        eigVects = eigVects/np.linalg.norm(eigVects,axis=0) #归一化特征向量
        redEigVects = eigVects[:,eigValInd]
        print '选取的特征向量',redEigVects.shape
        print '均值矩阵维度',diffMat.shape
        lowMat = redEigVects.T*diffMat
        print '低维矩阵维度',lowMat.shape
        return lowMat,redEigVects
 
    def compare(self,dataMat,testImg,label):
        '''
        比较函数,这里只是用了最简单的欧氏距离比较,还可以使用KNN等方法,如需修改修改此处即可
        :param dataMat: 样本矩阵
        :param testImg: 测试图像矩阵,最原始形式
        :param label: 标签矩阵
        :return: 与测试图片最相近的图像文件名
        '''
        testImg = cv2.resize(testImg,self.dsize)
        testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY)
        testImg = np.reshape(testImg,(-1,1))
        lowMat,redVects = self.PCA(dataMat,self.dimNum)
        testImg = redVects.T*testImg
        print '检测样本变换后的维度',testImg.shape
        disList = []
        testVec = np.reshape(testImg,(1,-1))
        for sample in lowMat.T:
            disList.append(np.linalg.norm(testVec-sample))
        print disList
        sortIndex = np.argsort(disList)
        return label[sortIndex[0]]
 
 
    def predict(self,dirName,testFileName):
        '''
        预测函数
        :param dirName: 包含训练数据集的文件夹路径
        :param testFileName: 测试图像文件名
        :return: 预测结果
        '''
        testImg = cv2.imread(testFileName)
        dataMat,label = self.createImgMat(dirName)
        print '加载图片标签',label
        ans = self.compare(dataMat,testImg,label)
        return ans
 
 
if __name__ == '__main__':
    eigenface = EigenFace(20,50,(50,50))
    print eigenface.predict('d:/face','D:/face_test/1.bmp')
2 )、FisherFaces アルゴリズム

#encoding=utf-8
import numpy as np
import cv2
import os
 
class FisherFace(object):
    def __init__(self,threshold,k,dsize):
        self.threshold = threshold # 阈值,暂未使用
        self.k = k         # 指定投影w的个数
        self.dsize = dsize # 统一尺寸大小
 
    def loadImg(self,fileName,dsize):
        '''
        载入图像,灰度化处理,统一尺寸,直方图均衡化
        :param fileName: 图像文件名
        :param dsize: 统一尺寸大小。元组形式
        :return: 图像矩阵
        '''
        img = cv2.imread(fileName)
        retImg = cv2.resize(img,dsize)
        retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY)
        retImg = cv2.equalizeHist(retImg)
        # cv2.imshow('img',retImg)
        # cv2.waitKey()
        return retImg
 
    def createImgMat(self,dirName):
        '''
        生成图像样本矩阵,组织形式为行为属性,列为样本
        :param dirName: 包含训练数据集的图像文件夹路径
        :return: 包含样本矩阵的列表,标签列表
        '''
        dataMat = np.zeros((10,1))
        label = []
        dataList = []
        for parent,dirnames,filenames in os.walk(dirName):
            # print parent
            # print dirnames
            # print filenames
            #index = 0
            for dirname in dirnames:
                for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname):
                    for index,filename in enumerate(subFilenames):
                        img = self.loadImg(subParent+'/'+filename,self.dsize)
                        tempImg = np.reshape(img,(-1,1))
                        if index == 0 :
                            dataMat = tempImg
                        else:
                            dataMat = np.column_stack((dataMat,tempImg))
                dataList.append(dataMat)
                label.append(subParent)
        return dataList,label
 
    def LDA(self,dataList,k):
        '''
        多分类问题的线性判别分析算法
        :param dataList: 样本矩阵列表
        :param k: 投影向量k的个数
        :return: 变换后的矩阵列表和变换矩阵
        '''
        n = dataList[0].shape[0]
        W = np.zeros((n,self.k))
        Sw = np.zeros((n,n))
        Sb = np.zeros((n,n))
        u = np.zeros((n,1))
        N = 0
        meanList = []
        sampleNum = []
 
        for dataMat in dataList:
            meanMat = np.mat(np.mean(dataMat,1)).T
            meanList.append(meanMat)
            sampleNum.append(dataMat.shape[1])
 
            dataMat = dataMat-meanMat
            sw = dataMat*dataMat.T
            Sw += sw
        print 'Sw的维度',Sw.shape
 
        for index,meanMat in enumerate(meanList):
            m = sampleNum[index]
            u += m*meanMat
            N += m
        u = u/N
        print 'u的维度',u.shape
 
        for index,meanMat in enumerate(meanList):
            m = sampleNum[index]
            sb = m*(meanMat-u)*(meanMat-u).T
            Sb += sb
        print 'Sb的维度',Sb.shape
 
        eigVals, eigVects = np.linalg.eig(np.mat(np.linalg.inv(Sw)*Sb))
        eigValInd = np.argsort(eigVals)
        eigValInd = eigValInd[::-1]
        eigValInd = eigValInd[:k] # 取出指定个数的前k大的特征值
        print '选取的特征值',eigValInd.shape
        eigVects = eigVects/np.linalg.norm(eigVects,axis=0) #归一化特征向量
        redEigVects = eigVects[:,eigValInd]
        print '变换矩阵维度',redEigVects.shape
 
        transMatList = []
        for dataMat in dataList:
            transMatList.append(redEigVects.T*dataMat)
        return transMatList,redEigVects
 
    def compare(self,dataList,testImg,label):
        '''
        比较函数,这里只是用了最简单的欧氏距离比较,还可以使用KNN等方法,如需修改修改此处即可
        :param dataList: 样本矩阵列表
        :param testImg: 测试图像矩阵,最原始形式
        :param label: 标签矩阵
        :return: 与测试图片最相近的图像文件夹,也就是类别
        '''
        testImg = cv2.resize(testImg,self.dsize)
        testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY)
        testImg = np.reshape(testImg,(-1,1))
        transMatList,redVects = fisherface.LDA(dataList,self.k)
        testImg = redVects.T*testImg
        print '检测样本变换后的维度',testImg.shape
        disList = []
        testVec = np.reshape(testImg,(1,-1))
        sumVec = np.mat(np.zeros((self.dsize[0]*self.dsize[1],1)))
        for transMat in transMatList:
            for sample in transMat.T:
                disList.append( np.linalg.norm(testVec-sample))
        print disList
        sortIndex = np.argsort(disList)
        return label[sortIndex[0]/9]
 
    def predict(self,dirName,testFileName):
        '''
        预测函数
        :param dirName: 包含训练数据集的文件夹路径
        :param testFileName: 测试图像文件名
        :return: 预测结果
        '''
        testImg = cv2.imread(testFileName)
        dataMat,label = self.createImgMat(dirName)
        print '加载图片标签',label
        ans = self.compare(dataMat,testImg,label)
        return ans
 
if __name__=="__main__":
   
    fisherface = FisherFace(10,20,(20,20))
    ans = fisherface.predict('d:/face','d:/face_test/8.bmp')
    print ans
3)、LBPH アルゴリズム

#encoding=utf-8
import numpy as np
import os
import cv2
 
class LBP(object):
    def __init__(self,threshold,dsize,blockNum):
        self.dsize = dsize # 统一尺寸大小
        self.blockNum = blockNum # 分割块数目
        self.threshold = threshold # 阈值,暂未使用
 
    def loadImg(self,fileName,dsize):
        '''
        载入图像,灰度化处理,统一尺寸,直方图均衡化
        :param fileName: 图像文件名
        :param dsize: 统一尺寸大小。元组形式
        :return: 图像矩阵
        '''
        img = cv2.imread(fileName)
        retImg = cv2.resize(img,dsize)
        retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY)
        retImg = cv2.equalizeHist(retImg)
        # cv2.imshow('img',retImg)
        # cv2.waitKey()
        return retImg
 
    def loadImagesList(self,dirName):
        '''
        加载图像矩阵列表
        :param dirName:文件夹路径
        :return: 包含最原始的图像矩阵的列表和标签矩阵
        '''
        imgList = []
        label = []
        for parent,dirnames,filenames in os.walk(dirName):
            # print parent
            # print dirnames
            # print filenames
            for dirname in dirnames:
                for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname):
                    for filename in subFilenames:
                        img = self.loadImg(subParent+'/'+filename,self.dsize)
                        imgList.append(img) # 原始图像矩阵不做任何处理,直接加入列表
                        label.append(subParent+'/'+filename)
        return imgList,label
 
 
    def getHopCounter(self,num):
        '''
        计算二进制序列是否只变化两次
        :param num: 数字
        :return: 01变化次数
        '''
        binNum = bin(num)
        binStr = str(binNum)[2:]
        n = len(binStr)
        if n < 8:
            binStr = "0"*(8-n)+binStr
        n = len(binStr)
        counter = 0
        for i in range(n):
            if i != n-1:
                if binStr[i+1] != binStr[i]:
                    counter += 1
            else:
                if binStr[0] != binStr[i]:
                    counter += 1
        return counter
 
    def createTable(self):
        &#39;&#39;&#39;
        生成均匀对应字典
        :return: 均匀LBP特征对应字典
        &#39;&#39;&#39;
        self.table = {}
        temp = 1
        print type(temp)
        for i in range(256):
            if self.getHopCounter(i) <= 2:
                self.table[i] = temp
                temp += 1
            else:
                self.table[i] = 0
        return self.table
 
    def getLBPfeature(self,img):
        &#39;&#39;&#39;
        计算LBP特征
        :param img:图像矩阵
        :return: LBP特征图
        &#39;&#39;&#39;
        m = img.shape[0];n = img.shape[1]
        neighbor = [0]*8
        featureMap = np.mat(np.zeros((m,n)))
        for y in xrange(1,m-1):
            for x in xrange(1,n-1):
                neighbor[0] = img[y-1,x-1]
                neighbor[1] = img[y-1,x]
                neighbor[2] = img[y-1,x+1]
                neighbor[3] = img[y,x+1]
                neighbor[4] = img[y+1,x+1]
                neighbor[5] = img[y+1,x]
                neighbor[6] = img[y+1,x-1]
                neighbor[7] = img[y,x-1]
                center = img[y,x]
                temp = 0
                for k in range(8):
                    temp += (neighbor[k] >= center)*(1<<k)
                featureMap[y,x] = self.table[temp]
        featureMap = featureMap.astype('uint8') # 数据类型转换为无符号8位型,如不转换则默认为float64位,影响最终效果
        return featureMap
 
    def calcHist(self,roi):
        '''
        计算直方图
        :param roi:图像区域
        :return: 直方图矩阵
        '''
        hist = cv2.calcHist([roi],[0],None,[59],[0,256]) # 第四个参数是直方图的横坐标数目,经过均匀化降维后这里一共有59种像素
        return hist
 
    def compare(self,sampleImg,testImg):
        '''
        比较函数,这里使用的是欧氏距离排序,也可以使用KNN,在此处更改
        :param sampleImg: 样本图像矩阵
        :param testImg: 测试图像矩阵
        :return: k2值
        '''
        testImg = cv2.resize(testImg,self.dsize)
        testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY)
        testFeatureMap = self.getLBPfeature(testImg)
        sampleFeatureMap = self.getLBPfeature(sampleImg)
        # 计算步长,分割整个图像为小块
        ystep = self.dsize[0]/self.blockNum
        xstep = self.dsize[1]/self.blockNum
        k2 = 0
        for y in xrange(0,self.dsize[0],ystep):
            for x in xrange(0,self.dsize[1],xstep):
                testroi = testFeatureMap[y:y+ystep,x:x+xstep]
                sampleroi =sampleFeatureMap[y:y+ystep,x:x+xstep]
                testHist = self.calcHist(testroi)
                sampleHist = self.calcHist(sampleroi)
                k2 += np.sum((sampleHist-testHist)**2)/np.sum((sampleHist+testHist))
        print 'k2的值为',k2
        return k2
 
    def predict(self,dirName,testImgName):
        '''
        预测函数
        :param dirName:样本图像文件夹路径
        :param testImgName: 测试图像文件名
        :return: 最相近图像名称
        '''
        table = self.createTable()
        testImg = cv2.imread(testImgName)
        imgList,label = self.loadImagesList(dirName)
        k2List = []
        for img in imgList:
            k2 = self.compare(img,testImg)
            k2List.append(k2)
        order = np.argsort(k2List)
        return label[order[0]]
 
if __name__ == "__main__":
 
    lbp = LBP(20,(50,50),5)
    ans = lbp.predict('d:/face','d:/face_test/9.bmp')
    print ans
知識の拡大: 顔認識アルゴリズム研究の難しさ

# #顔認識アルゴリズムは長い間研究されており、背景が単純であれば、ほとんどのアルゴリズムがうまく処理できます。ただし、顔認識には幅広い用途があり、単純な画像テストでは実際のニーズを満たすには程遠いです。したがって、顔認識アルゴリズムには依然として多くの困難が存在します。

照明

照明の問題はマシン ビジョンにおける古い問題であり、特に顔認識では顕著であり、アルゴリズムはまだ使用レベルに達していません。

姿勢

照明の問題と同様に、姿勢の問題も顔認識研究において解決する必要がある技術的な問題です。姿勢に関する研究は比較的少なく、ほとんどの顔認識アルゴリズムは主に正面または正面に近い顔画​​像を対象としていますが、ピッチや左右の傾きが激しい場合、顔認識アルゴリズムの認識率も低下します。衰退。

オクルージョン

非協力的な状況での顔画像収集の場合、オクルージョンの問題は非常に深刻な問題であり、特に監視対象物が頻繁に存在する監視環境では顕著です。彼らは全員、眼鏡、帽子、その他のアクセサリーを着用しているため、収集された顔画像が不完全になる可能性があり、その後の特徴抽出と認識に影響を与え、さらには顔認識アルゴリズムの失敗を引き起こす可能性があります。

年齢の変化

年齢が変化すると、顔の外観も変化します。特に 10 代の場合、この変化はより顕著です。年齢層が異なると、顔認識アルゴリズムの認識率も異なります。

画像品質

顔画像のソースは多様である可能性があり、収集機器が異なるため、取得された顔画像の品質も異なります。高解像度、高ノイズ、低品質の顔画像に対して効果的な顔認識を実行する方法は注意が必要な問題です。同様に、高解像度画像の場合、顔認識アルゴリズムへの影響についてもさらなる研究が必要です。

サンプル不足

顔認識分野では統計学習に基づく顔認識アルゴリズムが主流ですが、統計学習手法には多くのトレーニングが必要です。高次元空間における顔画像の分布は不規則なポピュラー分布であるため、取得できるサンプルは顔画像空間のごく一部のみであり、小さなサンプルの下で統計的学習問題を解決する方法についてはさらなる研究が必要です。 。

大量のデータ

PCA、LDA などの従来の顔認識アルゴリズムは、小規模なデータで簡単にトレーニングおよび学習できます。ただし、大量のデータの場合、これらの方法のトレーニング プロセスは困難であり、破綻する可能性もあります。

大規模な顔認識

顔データベースのサイズが増加すると、顔アルゴリズムのパフォーマンスが低下します。

関連知識の詳細については、FAQ 列をご覧ください。

以上が顔認識アルゴリズムとは何を意味しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。