導航:首頁 > 編程語言 > 人臉紋理變換代碼

人臉紋理變換代碼

發布時間:2023-05-05 13:06:49

㈠ opengl es怎麼實現紋理變化

呃,提供一個思路還不夠啊....好吧,看著你在群里支持le3d的友情上,給你寫段偽代碼~~(0)在類的成員函數里,定義一個int textureId,作為紋理的id;(1)在核橡onsurfacecreated相關初始化的函數里,創建一張紋理1.1 glGenTexture申請一個id1.2 bind texture1.3 glTexImage()分配一張空紋理1.4 set texture parameter 設置紋理相關參扒拍數(2)在onDrawFrame等回調函數里2.1 bind texture幫頂紋理2.2 glTexSubImage更新改此旁紋理,用你每幀截取的畫面2.3 繪制(3)在onsurfacedestroyed相關函數,釋放資源。

㈡ uniform lbp運算元進行人臉識別得到的圖像整體偏

uniform lbp運算元進行人臉識別得到的圖像整體偏是:是一種用來描述圖像局部紋理特徵的運算元;它具有旋轉不變性和灰度級不變性等顯著的優點。

它是首先由T. Ojala, M.Pietikäinen, 和 D. Harwood 在1994年提出,用於紋理特徵提取。而且,提取的特徵是圖像的局部的紋理特徵。

並且原始的LBP運算元定義為在3*3的窗口內,以窗口中心像素為閾值,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大於中心像素值,則該像素點的位置被標記為1,否則為0。

這樣,3*3領域內的8個點經比較可產生8位二進制數(通常轉換為十進制數即LBP碼,共256種),即得到該窗口中心像素點的LBP值,並用這個值來反映該區域的紋理信息。

LBP等價模式是:

一個LBP運算元可以產生不同的二進制模式,對於半徑為R的圓形區域內含有P個采樣點的LBP運算元將會產生P2種模式。很顯然,隨著鄰域集內采樣點數的增加,二進制模式的種類是急劇增加的。

例如:5×5鄰域內20個采樣點,有220=1,048,576種二進制模式。如此多的二值模式無論對於紋理的提取還是對於紋理的識別、分類及信息的存取都是不利的。

同時,過多的模式種類對於紋理的表達是不利的。例如,將LBP運算元用於紋理分類或人臉識別時,常採用LBP模式的統計直方圖來表達圖像的信息,而較多的模式種類將使得數據量過大。

且直方圖過於稀疏。因此,需要對原始的LBP模式進行降維,使得數據量減少的情況下能最好的代表圖像的信息。

㈢ 求gabor濾波器分析圖像紋理的c++程序 opencv的就不要了

整個項目的結構圖:

編寫DetectFaceDemo.java,代碼如下:

[java] view
plainprint?

package com.njupt.zhb.test;

import org.opencv.core.Core;

import org.opencv.core.Mat;

import org.opencv.core.MatOfRect;

import org.opencv.core.Point;

import org.opencv.core.Rect;

import org.opencv.core.Scalar;

import org.opencv.highgui.Highgui;

import org.opencv.objdetect.CascadeClassifier;

//

// Detects faces in an image, draws boxes around them, and writes the results

// to "faceDetection.png".

//

public class DetectFaceDemo {

public void run() {

System.out.println("\nRunning DetectFaceDemo");

System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath());

// Create a face detector from the cascade file in the resources

// directory.

//CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("森段並lbpcascade_frontalface.xml").getPath());

//Mat image = Highgui.imread(getClass().getResource("lena.png").getPath());

//注意:源程序的路徑會多列印一個燃豎『/』,因此總是出現如下錯誤

/*

* Detected 0 faces Writing faceDetection.png libpng warning: Image

* width is zero in IHDR libpng warning: Image height is zero in IHDR

* libpng error: Invalid IHDR data

*/

//因此,我們將第一個字元去掉

String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1);

CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath);

Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1));

// Detect faces in the image.

// MatOfRect is a special container class for Rect.

MatOfRect faceDetections = new MatOfRect();

faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("此跡Detected %s faces", faceDetections.toArray().length));

// Draw a bounding box around each face.

for (Rect rect : faceDetections.toArray()) {

Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));

}

// Save the visualized detection.

String filename = "faceDetection.png";

System.out.println(String.format("Writing %s", filename));

Highgui.imwrite(filename, image);

}

}
package com.njupt.zhb.test;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;

//
// Detects faces in an image, draws boxes around them, and writes the results
// to "faceDetection.png".
//
public class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath());
// Create a face detector from the cascade file in the resources
// directory.
//CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("lbpcascade_frontalface.xml").getPath());
//Mat image = Highgui.imread(getClass().getResource("lena.png").getPath());
//注意:源程序的路徑會多列印一個『/』,因此總是出現如下錯誤
/*
* Detected 0 faces Writing faceDetection.png libpng warning: Image
* width is zero in IHDR libpng warning: Image height is zero in IHDR
* libpng error: Invalid IHDR data
*/
//因此,我們將第一個字元去掉
String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1);
CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath);
Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1));
// Detect faces in the image.
// MatOfRect is a special container class for Rect.
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

// Draw a bounding box around each face.
for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}

// Save the visualized detection.
String filename = "faceDetection.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}
}

3.編寫測試類:

[java] view
plainprint?

package com.njupt.zhb.test;

public class TestMain {

public static void main(String[] args) {

System.out.println("Hello, OpenCV");

// Load the native library.

System.loadLibrary("opencv_java246");

new DetectFaceDemo().run();

}

}

//運行結果:

//Hello, OpenCV

//

//Running DetectFaceDemo

///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml

//Detected 8 faces

//Writing faceDetection.png
package com.njupt.zhb.test;
public class TestMain {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
// Load the native library.
System.loadLibrary("opencv_java246");
new DetectFaceDemo().run();
}
}
//運行結果:
//Hello, OpenCV
//
//Running DetectFaceDemo
///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml
//Detected 8 faces
//Writing faceDetection.png

㈣ 人臉識別特徵碼有哪些信息組成

人臉的位置和大小和人臉的紋理信息。確定圖像中人臉所在的位置和大小是人臉識別特族芹征碼中最基本的信息,兆岩畢人臉的紋理信息包括皮膚紋理、皺紋、色斑、痣等信息。棗迅人臉識別系統要考慮光照、素質、姿態等諸多影響因素,以獲得更准確的識別結果。

㈤ 人臉識別演算法是指什麼

教程操作環境:windows7系統、Dell G3電腦。
人臉識別(Facial Recognition),就是通過視頻採集設備獲取用戶的面部圖像,再利用核心的演算法對其臉部的五官位置、臉型和角度進行計算分析,進而和自身資料庫里已有的範本進行比對,後判斷出用戶的真實身份。
人臉識別演算法是指在檢測到人臉並定位面部關鍵特徵點之後,主要的人臉區域就可以被裁剪出來,經過預處理之後,饋入後端的識別演算法。識別演算法要完成人臉特徵的提取,並與庫存的已知人臉進行比對,完成最終的分類。
人臉識別的演算法有 4 種:基於人臉特徵點的識別演算法、基於整幅 人臉圖像的識別演算法、基於模板的識別演算法、利用神經網路進行識別的演算法。

人臉識別演算法的原理:
系統輸入一般是一張或者一系列含有未確定身份的人臉圖像,以及人臉資料庫中的若干已知身份的人臉圖象或者相應的編碼,而其輸出則是一系列相似度得分,表明待識別的人臉的身份。
人臉識別的三個經典演算法
1、Eigenfaces(特徵臉)演算法

Eigenfaces是在人臉識別的計算機視覺問題中使用的一組特徵向量的名余滑舉稱,豎碧Eigenfaces是基於PCA(主成分分析)的,所以學習Eigenfaces需要我們了解PCA的原理。
基本思想
主成分分析(PCA)是一種矩陣的壓縮演算法,在減少矩陣維數的同時盡可能的保留原矩陣的信息,簡單來說就是將 n×m的矩陣轉換成n×k的矩陣,僅保留矩陣中所存在的主要特性,從而可以大大節省空間和數據量。PCA的實現需要進行降維,也就是將矩陣進行變換,從更高的維度降到低的維度,然而PCA的降維離不開協方差矩陣。方差是描述一維數據樣本本身相對於均值的偏離程度,是一種用來度量兩個隨機變數關系的統計量,從角度來說,其夾角越小,值越大,方向越相近,也就是越正相關。協方差矩陣度量除了是兩個隨機變數的關系外,還是維度與維度之間的關系,而非樣本與樣本之間的關系。
學習一種新的東西,尤其是知識,我們需要了解知識中的思想。我在了解和學習Eigenface演算法時它的思想是圖像識別首先要選擇一個合適的子空間,將所有的圖像集中到這個子空間中,然後在這個子空間中衡量相似性或者進行分類學習,再講子空間變換到另一個空間中,這樣的作用一是同一個類別的圖像離得更近,二是不同的類別的圖像會離得比較遠;這樣經過線性分類分開的圖像在新空間就能容易分開。同時特徵臉技術會尋找人臉圖像分布的基本元素,即人臉圖像樣本集協方差矩陣的特徵向量,以此來表徵人臉圖像。人臉圖像的基本元素有很多,比如眼、面頰、唇等基本元素,這些特徵向量在特徵臉的圖像空間中對應生成的子空間被稱為子臉空間。
生成了子空間之後就要進行空間構造,那麼如何進行空間構造呢?首先要尋找人臉的共性,其次是要尋找個體與共性的差異,還有就是要明白共性其實是空間,個體就是向量。利用協方差矩陣把目標集中所有人臉圖像的特徵值進行分解,得到對應的特徵向量,這些特徵向量就是「特徵臉」。尋找特徵向量的特性,將其進行線性組合。在以每一個特徵子臉為基的空間,每個人臉就是一個點,這個點的坐標就是每一個人臉在每個特徵基下的的投影坐標。
Eigenfaces演算法過程
獲得人臉圖像數據,將每一個人臉圖像矩陣按行串成一維,每個人臉就是一個向量;
將M個人臉在對應維度上加起來,然後求平均得到「平均臉」;
將每個圖像都減去平均臉向量;
計算協方差矩陣;
運用Eigenfaces記性人臉識別;
演算法實踐過程;
訓練圖像
求出平均臉
獲得特徵子臉
進行圖像重構
尋找相似度高的人臉圖像。
2、FisherFace演算法
FisherFace是Fisher線性判別在人臉識別的應用。線性判別分析(LDA)演算法思想最早由英國統計與遺傳學家,現代統計科學的奠讓巧基人之一羅納德*費舍爾(Ronald)提出。LDA演算法使用統計學方法,嘗試找到物體間特徵的一個線性組合,在降維的同時考慮類別信息。通過該演算法得到的線性組合可以用來作為一個線性分類器或者實現降維。
基本思想
線性判別分析的基本思想是:將高維的模式樣本投影到低維最佳矢量空間,以達到抽取重要分類信息和壓縮特徵空間維度的效果,投影後保證模式樣本在新的子空間有最大的類間距離、最小的類內距離,即模式在該空間中有最佳的可分離性。理論和特徵臉里用到的Eigenfaces有相似之處,都是對原有數據進行整體降維映射到低維空間的方法,fisherfaces和Eigenfaces都是從數據整體入手而不同於LBP提取局部紋理特徵。
對降維後的樣本使用Fisher線性判別方法,確定一個最優的投影方向,構造一個一維的體征空間,將多維的人臉圖像投影到 fisherfaces特徵空間,利用類內樣本數據形成一組特徵向量,這組特徵向量就代表了人臉的特徵。
我們知道,該演算法是在樣本數據映射到另外一個特徵空間後,將類內距離最小化,類間距離最大化。LDA演算法可以用作降維,該演算法的原理和PCA演算法很相似,因此LDA演算法也同樣可以用在人臉識別領域。通過使用PCA演算法來進行人臉識別的演算法稱為特徵臉法,而使用LDA演算法進行人臉識別的演算法稱為費舍爾臉法。
LDA和PCA相比:
相同:1、在降維的時候,兩者都使用了矩陣的特徵分解思想;2、兩者都假設數據符合高斯分布。不同:1、LDA是有監督的降維方法,而PCA是無監督的。2、如果說數據是k維的,那麼LDA只能降到(k-1)維度,而PCA不受此限制。3、從數學角度來看,LDA選擇分類性能最好的投影方向,而PCA選擇樣本投影點具有最大方差的方向。Fisherfaces演算法和Eigenfaces演算法相比:
相同:兩者均可以對數據進行降維;兩者在降維時均使用了矩陣特徵分解的思想。
不同:Fisherfaces是有監督的降維方法,而是Eigenfaces無監督的降維方法;Fisherfaces除了可以用於降維,還可以用於分類。
值得一提的是,FisherFace演算法識別的錯誤率低於哈佛和耶魯人臉資料庫測試的Eigenfaces識別結果。
Fisherface演算法流程
獲得人臉圖像數據,然後求出人臉的均值。
觀察各個人臉的特徵值。
進行人臉鑒定,觀察人臉特徵,判斷是否是個人。
最後進行人臉識別。
3、LBPH(Local Binary Patter Histogram)演算法
Local Binary Patterns Histograms即LBP特徵的統計直方圖,LBPH將LBP(局部二值編碼)特徵與圖像的空間信息結合在一起。如果直接使用LBP編碼圖像用於人臉識別。其實和不提取LBP特徵區別不大,因此在實際的LBP應用中,一般採用LBP編碼圖像的統計直方圖作為特徵向量進行分類識別。
原始的LBP運算元定義為在33的窗口內,以窗口中心像素為閾值,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大於或等於中心像素值,則該像素點的位置被標記為1,否則為0。這樣,33鄰域內的8個點經比較可產生8位二進制數(通常轉換為十進制數即LBP碼,共256種),即得到該窗口中心像素點的LBP值,並用這個值來反映該區域的紋理特徵。
LBPH的維度: 采樣點為8個,如果用的是原始的LBP或Extended LBP特徵,其LBP特徵值的模式為256種,則一幅圖像的LBP特徵向量維度為:64256=16384維,而如果使用的UniformPatternLBP特徵,其LBP值的模式為59種,其特徵向量維度為:6459=3776維,可以看出,使用等價模式特徵,其特徵向量的維度大大減少,這意味著使用機器學習方法進行學習的時間將大大減少,而性能上沒有受到很大影響。
基本思想
建立在LBPH基礎上的人臉識別法基本思想如下:首先以每個像素為中心,判斷與周圍像素灰度值大小關系,對其進行二進制編碼,從而獲得整幅圖像的LBP編碼圖像;再將LBP圖像分為個區域,獲取每個區域的LBP編碼直方圖,繼而得到整幅圖像的LBP編碼直方圖,通過比較不同人臉圖像LBP編碼直方圖達到人臉識別的目的,其優點是不會受到光照、縮放、旋轉和平移的影響。
LBPH演算法「人」如其名,採用的識別方法是局部特徵提取的方法,這是與前兩種方法的最大區別。
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 ans3)、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 = center)*(1擴展知識:人臉識別演算法研究的難點
人臉識別演算法研究已久,在背景簡單的情形下,大部分演算法都能很好的處理。但是,人臉識別的應用范圍頗廣,僅是簡單圖像測試,是遠遠不能滿足現實需求的。所以人臉識別演算法還是存在很多的難點。
光照
光照問題是機器視覺中的老問題,在人臉識別中的表現尤為明顯,演算法未能達到使用的程度。
姿態
與光照問題類似,姿態問題也是人臉識別研究中需要解決的一個技術難點。針對姿態的研究相對比較少,多數的人臉識別演算法主要是針對正面,或接近正面的人臉圖像,當發生俯仰或者左右側而比較厲害的情況下,人臉識別演算法的識別率也將會急劇下降。
遮擋
對於非配合情況下的人臉圖像採集,遮擋問題是一個非常嚴重的問題,特別是在監控環境下,往往被監控對象都會帶著眼鏡﹑帽子等飾物,使得被採集出來的人臉圖像有可能不完整,從而影響了後面的特徵提取與識別,甚至會導致人臉識別演算法的失效。
年齡變化
隨著年齡的變化,面部外觀也在變化,特別是對於青少年,這種變化更加的明顯。對於不同的年齡段,人臉識別演算法的識別率也不同。
圖像質量
人臉圖像的來源可能多種多樣,由於採集設備的不同,得到的人臉圖像質量也不同,特別是對於那些低解析度﹑雜訊大﹑質量差的人臉圖像如何進行有效的人臉識別是個需要關注的問題。同樣的,對於高分辨圖像,對人臉識別演算法的影響也需要進一步研究。
樣本缺乏
基於統計學習的人臉識別演算法是人臉識別領域中的主流演算法,但是統計學習方法需要大量的培訓。由於人臉圖像在高維空間中的分布是一個不規則的流行分布,能得到的樣本只是對人臉圖像空間中的一個極小部分的采樣,如何解決小樣本下的統計學習問題有待進一步的研究。
大量數據
傳統人臉識別演算法如PCA、LDA等在小規模數據中可以很容易進行訓練學習。但是對於大量數據,這些方法其訓練過程難以進行,甚至有可能崩潰。
大規模人臉識別
隨著人臉資料庫規模的增長,人臉演算法的性能將呈現下降。

㈥ 用java寫人臉識別演算法有哪些

Java中常見的人臉識別演算法有:

㈦ 仿抖音特效相機之大眼瘦臉

本文是講解特效相機中的大眼瘦臉的實現,完整源碼可查看 AwemeLike 。
要實現瘦臉大眼,首先需要獲取到人臉特徵點,在本項目中使用的是Face++的人臉識別庫,它可以獲取到106個人臉特徵點,接著再通過變形演算法就可以實現了。

項目使用的瘦臉演算法是參照這篇文章 在OpenGL中利用shader進行實時瘦臉大眼等臉型微調

textureCoord 表示陵耐當前要修改的尺拆春坐標, originPosition 表示圓心坐標, targetPosition 表示目標坐標, delta 用來控制變形強度。

上述shader方法可以這樣理解,首先確定一個以 originPosition 為圓心、 targetPosition 和 originPosition 之間的距離為半徑的圓,然後將圓內的像素朝著同一個方向移動一個偏移值,且偏移值在距離圓心越近時越大,最終將變換後的坐標返回。

如果將方法簡化為這樣的表達式 變換後的坐標 = 原坐標 - (目標坐標 - 圓心坐標) * 變形強度 ,也就是說,方法的作用就是要在原坐標的基礎上減去一個偏移值,而 (targetPosition - originPosition) 決定了移動的方向和最大值。

式子中的 變形強度 可以這樣表示:

除了項目中使用的演算法,還有另外兩種臉部變形演算法可以使用,一個是基於 Interactive Image Warping 的局部調整演算法(其原理可查看 文章 ),我們在項目中使用的演算法其實可以看做是它的一個變種,都御乎可以用表達式 變換後的坐標 = 原坐標 - (目標坐標 - 圓心坐標) * 變形強度 來表示,不同之處在於 變形強度 的取值不同。;另一個是基於 Image deformation using moving least squares 的全局點位變形演算法(其原理可查看 文章 )。

當我們要使用上述瘦臉演算法時,只需要選取多對特徵點作為 originPosition 和 targetPosition ,使得它們作用范圍覆蓋的兩個臉頰和下巴,然後通過改變 delta 來控制瘦臉的強度。

在Face++中,獲取的106個特徵點分布如下

將這106個特徵點上傳到片元著色器

設置統一的變形強度

指定圓心坐標和目標坐標,共有9對

大眼演算法也是參照這篇文章 在OpenGL中利用shader進行實時瘦臉大眼等臉型微調

textureCoord 表示當前要修改的坐標, originPosition 表示圓心坐標, radius 表示圓的半徑, delta 用來控制變形強度。
和瘦臉的演算法類似,根據 originPosition 和 targetPosition 確定一個圓,圓內的坐標會參與計算,圓外的不變。
圓內的坐標圍繞圓心 originPosition 在變化,最終的坐標完全是由 weight 的值決定, weight 越大,最終的坐標變化越小,當 weight 為1,即坐標處於圓邊界或圓外時,最終的坐標不變;當 weight 小於1時,最終的坐標會落在原坐標和圓點之間,也就是說最終返回的像素點比原像素點距離圓點更近,這樣就產生了以圓點為中心的放大效果。

項目中的 FaceDetector 是一個專門用來處理Face++相關的操作的類,其頭文件如下

使用前需要替換Face++的key和secret,在項目中,它的路徑是 Face++/MGNetAccount.h ,然後調用授權方法,授權成功之後才能使用face++的人臉檢測。

face++接受的是 CMSampleBufferRef 類型的視頻幀,但他不支持YUV格式,所以在解碼時需要選擇BGRA格式。

項目使用 GPUImage 來做解碼,但 GPUImage 庫在將視頻幀解碼為BGRA格式時有一些實現問題,所以我們在使用相機和讀取視頻文件時,一定要使用項目自己創建的 GPUImageFaceCamera 和 GPUImageFaceMovie ,它們分別繼承自 GPUImage 的 GPUImageVideoCamera 和 GPUImageMovie ,在內部重寫了一些配置方法,使得返回的視頻幀格式都是BGRA。

除此以外,這兩個類在獲取到視頻幀之後還會自行調用 FaceDetector 的 - (void)getLandmarksFromSampleBuffer:(CMSampleBufferRef)detectSampleBufferRef; 方法獲取人臉信息,使得我們可以在之後的濾鏡類中直接使用它解析出來的人臉數據了。

人臉方向是指人臉在視頻幀中的逆時針偏移角度,偏移角度為0表示人臉是正的,處於豎直方向。

如果給我們一張人臉的圖片,我們的肉眼很容易判斷出人臉在圖片中的偏移角度,但是傳遞給face++的是一個來自相機或視頻文件視頻幀,那麼我們應該如何獲取人臉的偏移角度呢。

1. 相機拍攝( GPUImageFaceCamera )

當使用相機拍攝時,相機產生的視頻幀默認情況下和我們看到的並不一樣,可以通過 AVCaptureConnection 類的屬性 videoOrientation 來指定視頻幀的方向,其取值有如下幾種

上面提到的原圖就是我們肉眼看到的場景,它和相機或視頻文件產生的視頻幀可能是不一樣的。

因為項目是通過 GPUImage 庫來調用相機的,而 GPUImage 並沒有設置這個屬性——它使用的是默認值,所以項目使用的是這個屬性的默認值。(使用默認值可能是性能原因,因為設置這個屬性會導致系統應用一個相應matrix來旋轉視頻幀,GPUImage選擇將旋轉操作放到了GPU中執行)

後置攝像頭

在使用後置攝像頭時, videoOrientation 屬性的默認值是 ,也就是說當手機水平方向放置,且home鍵在右邊時,相機產生的圖片和原圖一致。
根據這個,我們可以得出下面兩個變換圖,左邊的圖片代表原圖(實際場景),右邊代表相機產生的視頻幀,也是傳遞給face++的視頻幀,每一行代表一個放置手機的方向。

我們需要根據上面兩個圖來得到人臉的偏移角度

首先我們需要設置了一個前提,人臉在原圖中總是處於豎直方向的,即偏移角度為0,這其實是符合邏輯的,我們的腦袋不可能歪到大於90度。
然後我們可以將上圖中的3和4看做是人臉,計算出右圖中的3和4的旋轉角度,就可以得出在當前手機方向下人臉的偏移角度。

最終我們得出了下面這個對照表

前置攝像頭

使用前置攝像頭時, videoOrientation 的默認值為 ,同樣的,當手機水平方向放置進行拍攝,home鍵在左邊時,相機產生的圖片和原圖是水平鏡像的關系,所以還需要額外做一個水平方向的翻轉,這時的圖片才和原圖一樣。

同樣給出手機處於豎直方向或水平方向拍攝時,原圖和視頻幀的變換

手機方向和人臉偏移角度的對照表

相比後置攝像頭,使用前置攝像頭時需要多做一個額外的水平翻轉,由於face++並沒有提供設置水平翻轉的介面,所以在識別前置攝像頭產生的圖片時,face++返回的人臉數據有一些小問題——人臉特徵點的排列順序左右顛倒了,不過這個問題是可以忽略的,因為人臉兩邊是對齊的;還有一個問題就是歐拉角的方向會取反,這個我們後面會講到怎麼解決。

檢測手機的方向

由於App只支持 Portrait 方向,所以無法使用類似 - (void):(UIInterfaceOrientation)toInterfaceOrientation ration:(NSTimeInterval)ration 方法來獲取手機方向。
一個更好的方法是通過 CoreMotion 檢測xyz方向的加速度,以此來判斷當前手機的朝向

2. 從視頻文件獲取( GPUImageFaceMovie )

通過 AVAssetTrack 的 preferredTransform 屬性獲得變換矩陣,再通過矩陣來判斷視頻的旋轉角度,也即是人臉的旋轉角度。

face++返回的人臉數據會在哪裡被使用?

GPUImage 會將視頻幀上傳到紋理中,然後將紋理傳遞給後續的 targets , targets 是指那些遵守了 GPUImageInput 協議的類,在這里我們簡稱它們為濾鏡類。

face++返回的人臉數據只會被使用在這些濾鏡類中,這些濾鏡類中的紋理圖片和傳遞給face++做人臉檢測的視頻幀是不一樣的,也就是說生成人臉數據時的參考坐標系和使用人臉數據時的參考坐標系是不同的。所以在使用人臉數據之前,我們還需要對人臉數據做一些轉換操作。

問題是如何轉換

之前在設置人臉方向時,我們已經了解了視頻幀,那麼濾鏡類中的紋理又是什麼樣的,可以參考下面這張圖

第一行使用後置攝像頭,第二行使用前置攝像頭;
第一列和第二列分別表示原圖和相機產生的視頻幀;
第三列表示視頻幀上傳到紋理時的情形,因為OpenGL的原點是在左下角,所以需要上下顛倒;
第四列表示變換後的紋理圖片,也就是濾鏡類中的紋理圖片。

( GPUImage 是如何從上圖的第三列變換到第四列的,查看 GPUImageVideoCamera 的方法 可知,按照本項目對 GPUImageVideoCamera 的配置( outputImageOrientation=, _=true ,前置),當使用後置攝像頭時,用來指定旋轉的枚舉是 kGPUImageRotateRight ,當使用前置攝像頭時,用來指定旋轉的枚舉是 ,這兩個枚舉的名字剛好是反向變換——第四列變換到第三列所需要的步驟)

特徵點坐標

假設 point 表示使用後置攝像頭時Face++的特徵點坐標,對應上圖的第一行的視頻幀,它是以4號位作為原點,也就是說 point 的值是相對於4號位的,然後我們再看第一行的最終紋理圖片,原點是3號位,4號位變換到右下角了,我們需要做的是將 point 變換到以3號位為原點。

所以變換後的 point 應該等於 (height - point.y, point.x) ,其中width是第二列視頻幀的4號位和2號位所在的那條邊的長度,height是視頻幀的4號位和3號位所在的那條邊的長度。

特徵點變換規則如下

歐拉角

faceinfo 的三個屬性 pitch 、 yaw 、 roll 分別表示人臉在未變換的視頻幀中圍繞x、y、z軸的旋轉角度。

㈧ 求教高手--ps問題:如何把一張人臉改成有很多的圖片組成

我覺得可以肢叢棚這樣。1先建立一個與臉部一樣大小的選區,新建圖層,填充任意色。2然後置入圖片,ctrl+alt+g,那些需要在臉部顯示的圖片與任意填充顏色的圖層建立剪貼蒙版關系。3改變圖層混歷則合模式,疊加之類的(視情況而定吧)。當然濾鏡裡面的置換也很有用,臉部的紋理都會反映在圖片中。只是那個還要麻煩一點,需要單獨保存,還要置入,還要更改混合模式,那個使用置換的時候最好用重復邊緣像素鄭旅。額,希望幫得到你。

閱讀全文

與人臉紋理變換代碼相關的資料

熱點內容
更新後版本英文怎麼說 瀏覽:267
桌面雲配置文件分離 瀏覽:505
iphone5如何升級4g網路 瀏覽:5
團購是在哪個app 瀏覽:897
打開多個word文檔圖片就不能顯示 瀏覽:855
騰訊新聞怎麼切換版本 瀏覽:269
app安裝失敗用不了 瀏覽:326
桌面文件滑鼠點開會變大變小 瀏覽:536
手機誤刪系統文件開不了機 瀏覽:883
微信兔子甩耳朵 瀏覽:998
android藍牙傳文件在哪裡 瀏覽:354
蘋果6s軟解是真的嗎 瀏覽:310
c語言代碼量大 瀏覽:874
最新網路衛星導航如何使用 瀏覽:425
以下哪些文件屬於圖像文件 瀏覽:774
zycommentjs 瀏覽:414
確認全血細胞減少看哪些數據 瀏覽:265
文件有哪些要求 瀏覽:484
cad打開時會出現兩個文件 瀏覽:65
什麼是轉基因網站 瀏覽:48

友情鏈接