2017年认证杯SPSSPRO杯数学建模
B题 岁月的印记
原题再现:
对同一个人来说,如果没有过改变面容的疾病、面部外伤或外科手术等经历,年轻和年老时的面容总有很大的相似性。人们在生活中也往往能够分辨出来两张不同年龄段的照片是不是同一个人。当然,年龄段相差越大,识别起来也就越困难。
第二阶段问题: 我们希望通过一个人在年轻时的面部照片来预测其过若干年后的容貌,也希望做到通过一个人在较大年龄时的照片来还原其年轻时的容貌。请你建立合理的数学模型来完成这项任务。
整体求解过程概述(摘要)
本文采用局域二值模式特征提取,SVM 支持向量机对图像人脸进行年龄预测,又利用人脸随着年龄的形状变化和纹理特征变化对不同目标年龄的人脸进行重构,还对重构后的人脸和真实人脸进行了相似度分析。
首先,为了提高模型准确率,我们对图像进行灰度均衡化、旋转调整、尺度归一化处理。我们建立了基于局域二值模式的纹理特征提取模型,并且建立了基于 BP 神经网络贡献分析法对特征向量进行降维,得出额头、嘴巴、眼角等地方对年龄的影响较大,将原维数 256 维的纹理特征向量降到 30 维。我们将降维后的特征向量作为输入,训练了加权支持向量机的年龄估计函数。同时,我们利用 FG-NET 人脸数据库验证年龄估计的支持向量回归模型,准确率达到 76.2%,且误差控制在 3 岁以内。
其次,我们选取 50 个特征点来标定人脸正面,得到了 8 个年龄段的平均脸型。接着我们建立了基于径向基函数的人脸形状变化模型,并计算出该年龄段人脸纹理特征向量,利用 LBP 算子提取的纹理特征与人脸型的变化相结合,进而重构了出目标年龄的人脸图像,其中人脸预测时进行的是纹理特征向量的叠加计算,人脸还原时进行的是纹理特征向量的差运算。
最后,我们建立基于欧氏距离的照片相似度分析模型,对模型重构出的人脸与真实的人脸进行相似度分析,检验出模型的正确率在 58.6%。我们还分析了所建模型的优缺点,讨论了模型的推广应用。
问题分析:
人脸图像识别问题是现今模式识别、图像处理等学科的一大研究热点,可以广泛的应用于安全部门、身份鉴别、电视会议、数字监控等领域。随着年龄的变化,人脸会发生变化,具体表现在色相衰老和皱纹的出现。本题要求我们在第一阶段的基础上,建立数学模型,解决通过一个人年轻时候来预测其若干年后的容貌,以及通过一个人在年老
时的照片来还原其年轻时候的容貌两个问题。
首先,我们选取了 FG-NET 年龄人脸库,该人脸数据库中的人脸图像并不是在标准光线和标准角度中拍摄的,所以我们首先进行预处理,才能使用图像数据进行建模。但由于采集的图像往往会带有很多的噪声和干扰信号,因此对于采集的人脸图像,首先需要进行规范化处理,将外界的因素带来的影响提出,这里可以采用灰度化、集合规范化(图像的平移、旋转、缩放变化)、灰度规范化(即平滑、灰度均衡化)等预处理的方法。
其次,要对图像进行面部特征提取和年龄估计,因为只有根据人脸的特征才能对其年龄进行合理的估计。可以使用 LBP 纹理特征提取算法,提取出人脸的纹理特征向量,并通过神经网络贡献分析法对特征向量作降维处理。对降维后的人脸纹理特征向量,可以使用 SVR 支持向量机回归模型, 以特征向量为输入对 SVR 进行训练,可以得到年龄估计模型。以此对图像的人脸进行较为准确的年龄估计。为下一步的人脸预测和人脸还原做准备。
然后,是人脸的重构部分。由于人脸的变化主要表现为人脸形状随年龄的变化和人脸纹理特征(青春痘、皱纹等)随年龄的变化。因此,在确定目前人脸的年龄以后,就可以以此为基础,对人脸进行重构。这里的重构有两类,一类是对预测一张年轻的脸若干年后的容貌,令一类是还原一张年老的脸若干年前的容貌。重构主要包含有两个阶段,一是对人脸形状的改变,而是对人脸纹理的变化。在预测人脸的容貌时,只要利用该年龄段的人的脸形状变化后,叠加上预测年龄段的人脸纹理特征即可。对于还原人脸容貌,则要将人脸形状还原后,去除掉相应的纹理特征。
最后,还要检验人脸重构是否合理,即检验重构后的人脸是否还是与原来的人脸是同一个,因此可以建立人脸相似度检验模型,对重构后的人脸和该年龄的人脸进行相似度分析,检验模型的准确性。
模型假设:
1. 假设人的衰老是正常衰老,不考虑人的生病、吸烟、压力大等不良生活习惯造成的非正常变老。
2. 假设本文所研究的人在成长过程中没有经历因为搬家等造成的生存环境的改变,外部环境对其造成的外貌的影响不予考虑。
3. 假设选取的人脸图像样本采取时,没有意外伤害或病变导致的人脸局部区域的形状、颜色发生显著性改变
4. 假采样人脸图像时,被采样者没有故意扭曲脸型,即为正常拍照。
论文缩略图:
全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可
部分程序代码:(代码和文档not free)
function [ opic ] = picInit( ipic )
%PICINIT 此函数用来预处理图片
mysize=size(ipic);
if numel(mysize)>2
tmp = rgb2gray(ipic);% 将图像灰度化
else
tmp = ipic;
end
%灰度调整
gc = imadjust(tmp,[0.2, 0.6], [0, 1]);
opic = gc;
end
//----------------------------------------------------------------------------
function [out] = get_bar( pic )
%GET_LBR 此处显示有关此函数的摘要
% 此处显示详细说明
gpic = double(pic);
lw=int16(size(gpic,1)/7);
lh=int16(size(gpic,2)/7);
for i = 0:6
for j = 0:6
res = zeros(lh, lw);
for x = i*lw+1:(i+1)*lw
for y = j*lh+1:(j+1)*lh
if x > size(gpic, 1) || y > size(gpic, 2)
continue;
end
res(x-i*lw,y-j*lh) = pic(x,y);
end
end
tmp = get_barD(res);
if i == 0 && j == 0
out=tmp;
else
out=array_add(out,tmp);
end
end
end
end
function [ opic ] = lbp( pic )
%LBP 进行 lbp 处理
tmp=pic;
for i = 2:size(pic,1)-1
for j = 2:size(pic,2)-1
res=0;
for k=i-1:i+1
for l=j-1:j+1
if k==i && l == j
continue
end
res=res*2;
x = 0;
if pic(k,l)>pic(i,j)
x=1;
end
res = res+x;
end
end
tmp(i,j)=res;
end
end
opic = tmp;
end
function [out] = get_bar( pic )
%GET_LBR 此处显示有关此函数的摘要
% 此处显示详细说明
gpic = double(pic);
lw=int16(size(gpic,1)/7);
lh=int16(size(gpic,2)/7);
for i = 0:6
for j = 0:6
res = zeros(lh, lw);
for x = i*lw+1:(i+1)*lw
for y = j*lh+1:(j+1)*lh
if x > size(gpic, 1) || y > size(gpic, 2)
continue;
end
res(x-i*lw,y-j*lh) = pic(x,y);
end
end
tmp = get_barD(res);
if i == 0 && j == 0
out=tmp;
else
out=array_add(out,tmp);
end
end
end
end