使用小波特征的人脸识别

219 阅读10分钟

在靠近用户的地方部署容器

本工程教育(EngEd)计划由科支持。

在全球范围内即时部署容器。Section是经济实惠、简单而强大的。

免费开始吧。

利用小波特征进行人脸识别

2月9日, 2022

人脸识别是一个可以将图像或视频帧中的人脸与数据库中的人脸相匹配的系统。小波是一种振荡,其振幅从零开始,增加或减少,然后回到零。

小波系数被用来从高光谱数据中提取特征。这些提取的特征被称为小波特征。

在本教程中,使用小波特征实现了一个人脸检测方案。我们使用小波特征来提取面部特征,并使用主成分分析来减少小波特征向量。

所提出的方案非常稳健,即使脸部发生了一些变化,如长出胡须、胡须等,也能识别出人脸。

先决条件

要跟上本教程,你需要具备以下条件。

准备用于训练和测试的人脸图像数据库

在本教程中,我们使用faces94。这个数据库由153个人组成,每个人有20张脸部图像。这个数据库有三个文件夹:男性东西、女性和男性。

在训练中,使用了50个被选中的个体的16张图像。这总共有800张图像被用于训练。

这50个人中每个人剩下的4张图片被用于测试。所有这些图像都保存在一个文件夹中。这些图像必须被命名为1.jpg, 2.jpg, ... 。它们的尺寸是200x180。

请注意,所有用于训练和测试的MATLAB脚本都应该放在同一个文件夹中。

寻找小波特征

下面显示的图像是寻找这些特征的基本算法。

Finding wavelet features

  1. 对输入图像进行二值化处理,得到二值图像。
  2. 进行1级DWT,得到近似系数(cA),水平详细系数(cH),垂直详细系数(cV)和详细对角线系数(cD)。这个矩阵的尺寸是输入图像(100x90)的一半。
  3. 我们得到行的标准差和列的标准差来得到这些特征。
  4. 结合行标准差和列标准差,我们得到相应的小波特征向量。

小波特征向量的大小为380。因为这个尺寸太大,我们需要减少它以节省内存空间。因此,我们使用主成分分析(PCA)来减少这个维度。

主成分分析用于减少小波特征向量的大小

主成分分析(PCA)是一种用于降维的无监督机器学习技术。更多信息请看主成分分析期刊。

一般的算法如下所示。

PCA algorithm

我们的大尺寸特征向量被投射到PCA空间,得到一个小尺寸的PCA表示。这个PCA表示就是特征值。

一般的PCA公式是。

fvpca = [fvstd-m]*Ppca

其中。

  • fvstd - 是输入的特征向量,在我们的例子中是大小为380的向量。
  • M - 是所有特征向量的平均值。
  • Ppca - 是转换矩阵。
  • fvpca - 是缩小的特征向量。

训练

这涉及到获取小波特征并将其投影到PCA空间。

Training process

第一步是读取所有的图像并得到它们相应的380大小的小波特征(fvstd)。因为有800张图像,所以它给出了一个380x800的矩阵。这个矩阵通过PCA空间,得到一个70x800的矩阵。

用于训练的Matlab代码

第1步 - 定义值

第一步是定义训练图像的数量,为所需维度选择的主导特征值的数量,并初始化数据集矩阵。

n = 800; %No. of training images
L = 70; %No. of dominant eigen values selected
M = 200; N = 180; %Required image dimensions
X = zeros(n, (M+N)); %Initialize data set matrix[X]

接下来,我们使用一个for 循环来逐一读取图像。首先,使用imread() 函数读取图像。然后,使用rgb2gray() 函数将读取的图像转换为灰度,然后使用imresize() 函数将其大小调整为所需的尺寸。

最后,我们通过使用imbinirize() 函数将调整后的图像转换为二进制类型,得到二进制图像。这个函数考虑了阈值水平。

for count = 1:n
    I = imread(sprintf('%d.jpg', count)); %Reading images
    I = rgb2gray(I); %RGB to grayscale
    I = imresize(I, [M, N]); %Resize all images to specified MxN
    level = graythresh(I);
    Ibin = imbinarize(I, level); %Getting binary image.

graythresh() 函数是全局阈值处理方法。level 是一个归一化的强度值。

第2步--寻找离散小波变换

我们首先为离散小波变换模式的图像设置dwtmode 函数。之后,我们使用dwt() 函数找到离散小波变换。

这个函数给出四个输出,即近似系数(cA),水平详细系数(cH),垂直详细系数(cV)和对角线详细系数(cD)。然后将这些系数排列成一个单一的矩阵wc

%Finding discrete wavelet transform
dwtmode('per', 'nodisp');
[cA, cH, cV, cD] = dwt2(double(Ibin), 'db10');
wc = [cA, cH; cV cD]; %wavelet coefficients arranged

第3步--寻找小波系数的标准差

在这里,我们找到标准偏差的列和行。这是用std() 函数完成的。

列向量被存储在stdcol 变量中。存储在stdrow 变量中的是行向量。

当结合这两个矩阵,stdcolstdrow ,我们得到特征向量fvstd 。之后,我们将这些特征向量存储在我们之前初始化的X 矩阵中。

%Finding standard deviation of wavelet coefficients
stdcol = std(wc); %Column wise
wcc = (wc');
stdrow = std(wcc); %row wise
fvstd = [stdcol stdrow]; %Feature vector using STD
X(count, :) = fvstd; %Saving all feature vector
end

第4步--将所有的特征向量投射到PCA空间上

这样做是为了减少我们矩阵的大小。在PCA空间的投影中,我们使用mean() 函数找到X 矩阵的平均值。我们通过减去每个特征向量的平均值来修改X 矩阵。

% Projecting all the feature vectors to PCA space
m = mean(X); %Mean of all feature vectors
for i = 1:n
    X(i, :) = X(i, :)-m; % Subtracting mean from each feature vector.
end

在此之后,我们找到协方差矩阵。协方差矩阵将整个维度的关系定义为两个随机变量之间的关系。

使用eig() 函数,我们得到特征值Evalm 和特征矩阵Evecm 。接下来,使用diag(Evalm) 和存储在Eval 变量中的值提取特征值。

最后,使用sort() 函数将这些特征值按降序排序。sort() 函数给出排序后的特征值Evalsorted 和它们的index

利用这些索引,我们找到它们相应的特征向量。以这些排序的特征值,Evalsorted ,并考虑到所选的主导特征值的数量L ,我们得到转换后的矩阵pca

将我们的矩阵Xpca 矩阵相乘,就是特征向量投射到PCA空间的位置。

Q = (X'*X)/(n-1); %Finding covariance matrix
[Evecm, Evalm] = eig(Q); %Getting eigen values and eigen vectors of matrix Q
Eval = diag(Evalm); %Getting eigen values
[Evalsorted, Index] = sort(Eval, 'descend'); %Sorting eigen values
Evecsorted = Evecm(:, Index); %Getting corresponding eigen vectors
Ppca = Evecsorted(:, 1: L); % Reduced transformation matrix Ppca
T = X*Ppca; %Projecting each feature vector to a pca space

训练过程结束后,我们保存n,M,N,m,Ppca, 和T 。我们在测试过程中需要它们。

要保存它们,请到工作区,选择它们,右键单击,并选择保存。你应该用任何名字保存它们。对于我们的情况,我们把它保存为wpcadt.mat

用于离散测试的Matlab代码

步骤1 - 加载wpcadt.mat文件

我们使用load() 函数来加载这个文件。加载这个文件后,我们需要选择加载的数据将被落实到的图像。

为了从我们的个人电脑的不同文件夹中选择图像,我们使用uigetfile() 函数。strcat ,获取图像路径和名称,并将其转换为字符串数据类型。

这些转换后的变量被用来读取图像。我们在读取图像时使用imread() 函数,并提供转换后的变量作为参数。

图像矩阵被存储在img 变量中。由于我们需要这个图像矩阵来显示,我们复制imgo = img

% Program for face recognition(Discrete testing)
load('wpcadb.mat', 'n', 'M', 'N', 'm', 'Ppca', 'T');
% Number of total training images[n], Image size [M, N], mean image[m]
%Reduced eigen vectors transformation matrix[Ppca]
%Transformed dataset matrix[T]

[filename, pathname] = uigetfile('*.*', 'Select the input face image');
filewithpath = strcat(pathname, filename);
img = imread(filewithpath);
imgo = img; %Copying image for display

第2步 - 将图像转换为二进制

我们需要将我们的图像转换为二进制(黑与白)。这是因为这些图像处理功能是在二进制图像上工作的。

我们使用rgb2gray() 函数将我们的输入图像img 转换为灰度。使用imresize 函数将此图像调整为MxN尺寸。

接下来,我们将图像二进制化,同时考虑使用imbinarize() 函数的阈值,如下所示。

img = rgb2gray(img);
img = imresize(img, [M, N]);
level = graythresh(img);
Ibin = imbinarize(img, level);

第3步--寻找离散小波变换

这个离散小波变换(dwt)与我们训练图像时的方法相同。

%Finding discrete wavelet transform
dwtmode('per', 'nodisp');
[cA, cH, cV, cD] = dwt2(double(Ibin), 'db10');
wc = [cA, cH; cV cD]; %wavelet coefficients arranged

第4步--寻找小波系数的标准差

我们也使用训练图像时使用的相同代码。

%Finding standard deviation of wavelet coefficients
stdcol = std(wc); %Column wise
wcc = (wc');
stdrow = std(wcc); %row wise

让我们把特征向量fvstd 投射到PCA空间中进行还原。它是通过从特征向量中减去平均值和输出乘以Ppca 矩阵来完成的。

同时,我们初始化差异数组。

fvstd = [stdcol stdrow]; %feature vector using STD
fvpca = (fvstd-m)*Ppca; % Projecting fv to PCA space
disarray = zeros(n, 1); %Initialize difference array

差分数组是与每个存储的特征向量的特征距离。使用for 循环来寻找所有图像之间的这个距离。这有助于我们获得正确的图像。

for i = 1:n
    distarray(i) = sum(abs(T(i, :)-fvpca)); %finding L1 distance
end

第5步 - 显示前五个匹配的图像

在显示这些匹配图像之前,我们使用sort() 函数进行排序。这个距离是在考虑到差异数组的情况下进行的。

排列是按升序进行的。这意味着与输入图像相近的图像被排在第一位。

[result, indx] = sort(distarray);

这个sort() 函数给出了结果和数据库中图像的索引indx 。然后根据索引从数据库中读取这些图像。imshow() 显示了输出。

%--------------Displaying first five matches---------%
resultimg1 = imread(sprintf('%d.jpg', indx(1)));
resultimg2 = imread(sprintf('%d.jpg', indx(2)));
resultimg3 = imread(sprintf('%d.jpg', indx(3)));
resultimg4 = imread(sprintf('%d.jpg', indx(4)));
resultimg5 = imread(sprintf('%d.jpg', indx(5)));

subplot(231); imshow(imgo); title('input test image')
subplot(232); imshow(resultimg1); title('First Matched image')
subplot(233); imshow(resultimg2); title('Second Matched image')
subplot(234); imshow(resultimg3); title('Third Matched image')
subplot(235); imshow(resultimg4); title('Fourth Matched image')
subplot(236); imshow(resultimg5); title('Fifth Matched image')

我们在运行这个程序时,需要使用我们没有用于训练的图像。因此,输出结果如下。

Image without distortion

当我们使用一个扭曲的图像来测试我们的图像的鲁棒性。我们意识到,这个程序能够进行识别。

例如,下面是一个有扭曲的图像的样本。

Distorted image

扭曲了一些图像部分。

Distored image

结论

在本教程中,我们讨论了如何利用小波特征来制作一个人脸识别系统。正如我们所看到的,这种方法是一种非常稳健的方法。即使图像被扭曲了,仍然可以用这些特征准确地识别人脸。

另外,这个方法所使用的算法也非常有效。PCA算法也有效地减少了多个图像的尺寸,很容易。

编码愉快!


同行评审贡献者:。Dawe Daniel

类似文章

[

How to Create a Reusable React Form component Hero Image

语言

如何创建一个可重复使用的React表单组件

阅读更多

](www.section.io/engineering…

Building a payroll system with next.js Hero Image

语言, Node.js

用Next.js构建一个薪资系统

阅读更多

](www.section.io/engineering…

Creating and Utilizing Decorators in Django example image

架构

在Django中创建和使用装饰器

阅读更多

](www.section.io/engineering…)