Face recognition classic algorithm implementation python[Copy link]
I have recently studied face recognition and found that it is very complex. I am new to it and do not fully understand it. I can only look at the forum and learn from everywhere. Thanks to all the predecessors for their posts and codes. This post is partly original and partly borrowed. Any similarity is purely coincidental! ! ! [size=18p x]First you need 2 third-party libraries opencv-python, numpy After the installation is complete, you can program. Let me first explain the required algorithm: The basic idea of eigenface technology is to find the basic elements of face image distribution, that is, the eigenvectors of the covariance matrix of face image sample set, from a statistical point of view, so as to approximately characterize the face image. These eigenvectors are called eigenfaces. [p=30, null,In fact, the eigenface reflects the information implicit in the face sample set and the structural relationship of the face. The eigenvectors of the covariance matrix of the eye, cheek, and jaw sample set are called eigeneyes, eigenjaws, and eigenlips, collectively known as eigensubfaces. The eigensubface generates a subspace in the corresponding image space, called the subface space. Calculate the projection distance of the test image window in the sub-face space. If the window image meets the threshold comparison condition, it is judged to be a human face. Based on the feature analysis method, the relative ratio of the facial reference points and other shape parameters or category parameters describing the facial features of the face are combined to form a recognition feature vector. This recognition based on the whole face not only retains the topological relationship between the facial components, but also retains the information of each component itself. The recognition based on the components is to design a specific recognition algorithm by extracting local contour information and grayscale information. Now the Eigenface (PCA) algorithm has become a benchmark algorithm for testing the performance of face recognition systems together with the classic template matching algorithm; and since the birth of the eigenface technology in 1991, researchers have conducted various experiments and theoretical analyses on it. The FERET'96 test results also show that the improved eigenface algorithm is the mainstream face recognition technology and one of the recognition methods with the best performance. This method first determines the size, position, distance and other attributes of the facial features such as the iris, nose, and mouth corners, and then calculates their geometric feature quantities, which form a feature vector that describes the face. The core of its technology is actually "local human feature analysis" and "graphic/neural recognition algorithm." This algorithm is a method that uses various organs and characteristic parts of the human face. For example, the corresponding geometric relationship multi-data forms recognition parameters and compares, judges and confirms all the original parameters in the database. Turk and Pentland proposed the eigenface method, which constructs the principal component subspace based on a set of face training images. Since the principal component has the shape of the face, it is also called the eigenface. During recognition, the test image is projected onto the principal component subspace to obtain a set of projection coefficients, which are compared with the face images of each known person for recognition. Pentland et al. reported quite good results, obtaining a 95% correct recognition rate in 3,000 images of 200 people, and only one misrecognition of 150 frontal faces on the FERE database. However, the system needs to do a lot of preprocessing work such as normalization before using the eigenface method. On the basis of traditional eigenfaces, researchers noticed that eigenvectors with large eigenvalues (i.e., eigenfaces) are not necessarily the direction of good classification performance. Based on this, a variety of feature (subspace) selection methods have been developed, such as Peng's dual subspace method, Weng's linear ambiguity analysis method, Belhumeur's FisherFace method, etc. In fact, the eigenface method is an explicit principal component analysis face modeling, and some linear autoassociation and linear compression BP networks are implicit principal component analysis methods. They all represent the face as the weighted sum of some vectors, which are the main eigenvectors of the cross product matrix of the training set. Valen discussed this in detail. In short, the eigenface method is a simple, fast, and practical algorithm based on transformation coefficient features, but because it essentially relies on the grayscale correlation between the training set and the test set images, and requires the test image to be similar to the training set, it has great limitations.
Features based on KL transformFace recognitionBasic principle of the method: KL transform is an optimal orthogonal transform in image compression. People use it for statistical feature extraction, thus forming the basis of subspace pattern recognition. If KL transform is used for face recognition, it is necessary to assume that the face is in a low-dimensional linear space and that different faces are separable. Since a new set of orthogonal bases can be obtained after KL transform of high-dimensional image space, a low-dimensional face space can be generated by retaining some of the orthogonal bases. The basis of the low-dimensional space is obtained by analyzing the statistical characteristics of the face training sample set. The generation matrix of KL transform can be the overall scatter matrix of the training sample set or the inter-class scatter matrix of the training sample set. That is, the average of several images of the same person can be used for training. This can eliminate interference from light to a certain extent, and the amount of calculation is also reduced, while the recognition rate will not decrease.
Let's start programming. During the process, I found that pcv is very complicated, so I added some printing to facilitate debugging.
#encoding=utf-8 import numpy as np import cv2 import os class EigenFace(object): def __init__(self,threshold,dimNum,dsize): self.threshold = threshold # The threshold is not used yet self.dimNum = dimNum self.dsize = dsize def loadImg(self,fileName,dsize):''''' Load image, grayscale, unify size, histogram equalization:param fileName: image file name:param dsize: unify size. Tuple form:return: image matrix''' 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): ''''' Generate an image sample matrix, organized as behavioral attributes and columns as samples:param dirName: image folder path containing training data set:return: sample matrix, label matrix''' 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 function, used for data dimensionality reduction:param dataMat: sample matrix:param dimNum: target dimension after dimensionality reduction:return: sample matrix and transformation matrix after dimensionality reduction''' # Mean matrix meanMat = np.mat(np.mean(dataMat,1)).T print u'mean matrix dimension',meanMat.shape diffMat = dataMat-meanMat # Find the covariance matrix. Since the sample dimension is much larger than the number of samples, the covariance matrix is not directly found. The following method is used covMat = (diffMat.T*diffMat)/float(diffMat.shape[1]) # Normalization #covMat2 = np.cov(dataMat,bias=True) #print 'The basic method to calculate the covariance matrix is',covMat2 print u'covariance matrix dimension',covMat.shape eigVals, eigVects = np.linalg.eig(np.mat(covMat)) print u'eigenvector dimension',eigVects.shape print u'eigenvalue',eigVals eigVects = diffMat*eigVects eigValInd = np.argsort(eigVals) eigValInd = eigValInd[::-1] eigValInd = eigValInd[:dimNum] # Take out the top n eigenvalues of the specified number print u'Selected eigenvalue',eigValInd eigVects = eigVects/np.linalg.norm(eigVects,axis=0) # Normalize the eigenvector redEigVects = eigVects[:,eigValInd] print u'Selected eigenvector',redEigVects.shape print u'Mean matrix dimension',diffMat.shape lowMat = redEigVects.T*diffMat print u'Low dimensional matrix dimension',lowMat.shape return lowMat,redEigVects def compare(self,dataMat,testImg,label):''''' Comparison function, here we only use the simplest Euclidean distance comparison, you can also use KNN and other methods, if you need to modify it, just modify it here:param dataMat: sample matrix:param testImg: test image matrix, the most original form:param label: label matrix:return: The image file name closest to the test image''' 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 u'Detect the dimension of the sample after transformation',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): ''''' Prediction function:param dirName: Folder path containing training data set:param testFileName: Test image file name:return: Prediction result''' testImg = cv2.imread(testFileName) dataMat,label = self.createImgMat(dirName) print u'Load image label',label ans = self.compare(dataMat,testImg,label) return ans if __name__ == '__main__': eigenface = EigenFace(200,500,(500,500)) print eigenface.predict('d:/face/11.bmp','D:/face1/1.bmp')
It’s a very difficult algorithm. I’m currently researching algorithm-related stuff. Let’s work hard together! ! ! !
Details
Published on 2024-3-18 20:50