兴趣学习: 人脸识别系统实现 …
2016-05-19 23:27
267 查看
人脸识别系统
这个学期的软件工程作业----人脸识别系统, 基本功能还是实现了,
具体思路从国外一篇博客
学习而得, http://www.shervinemami.info/faceRecognition.html,
写的非常好. 具体实现的方法呢,
我就不讲解了, 看了就懂. 需要完整代码可以留言.
还是前面总结的问题"道"与"术"的问题, 学习要
学习解决方法的思路.
难点: 人脸库的制作, 人脸的照片需要计算出特征向量, PCA主成分析法.
提高人脸识别精确度需要自己
根据具体情况取照片. 以下是我的读入人脸的train.txt文件(部分).
我用的是每人20张照片, 实验证明
相识度计算出来大概是40%~60%左右.
1 shanghe tt\shanghe\1.jpg
1 shanghe tt\shanghe\2.jpg
1 shanghe tt\shanghe\3.jpg
2 zhijie tt\zijie\1.jpg
2 zhijie tt\zijie\2.jpg
2 zhijie tt\zijie\3.jpg
3 haoru tt\haoru\1.jpg
3 haoru tt\haoru\2.jpg
3 haoru tt\haoru\3.jpg
4 benson tt\jiayong\1.jpg
4 benson tt\jiayong\2.jpg
4 benson tt\jiayong\3.jpg
贴一些核心代码:(不完整, 不熟悉的代码不要随便用!!!)
//计算欧拉距离
//寻找最接近的图像
int findNearestNeighbor(float * projectedTestFace)
{
double
leastDistSq =
DBL_MAX; //定义最小距离,并初始化为无穷大
int i,
iTrain, iNearest = 0;
for(iTrain=0; iTrain
{
double distSq=0;
for(i=0; i
{
float d_i =
projectedTestFace[i] -
projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
distSq += d_i*d_i; // Euclidean算法计算的距离
}
if(distSq < leastDistSq)
{
leastDistSq = distSq;
iNearest = iTrain;
}
}
fConfidence
= 1.0f - sqrt( leastDistSq / (float)(nTrainFaces * nEigens) ) /
255.0f;
iCount++;
if(
fConfidence > thres )
recCount++;
printf("Confidence = %f\n",fConfidence);
if(fConfidence < 0.40) return -1;
//根据具体情况设置阀值
return
iNearest;
}
//主成分分析
void doPCA()
{
int i;
CvTermCriteria calcLimit;
CvSize
faceImgSize;
//
自己设置主特征值个数
nEigens =
nTrainFaces-1;
//分配特征向量存储空间
faceImgSize.width =
faceImgArr[0]->width;
faceImgSize.height = faceImgArr[0]->height;
eigenVectArr
= (IplImage**)cvAlloc(sizeof(IplImage*) *
nEigens); //分配个数为住特征值个数
for(i=0;
i
eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F,
1);
//分配主特征值存储空间
eigenValMat
= cvCreateMat( 1, nEigens, CV_32FC1 );
//
分配平均图像存储空间
pAvgTrainImg
= cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
//
设定PCA分析结束条件
calcLimit =
cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
//
计算平均图像,特征值,特征向量
cvCalcEigenObjects(
nTrainFaces,
(void*)faceImgArr,
(void*)eigenVectArr,
CV_EIGOBJ_NO_CALLBACK,
0,
0,
&calcLimit,
pAvgTrainImg,
eigenValMat->data.fl);
cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
}
//加载txt文件的列举的图像
int loadFaceImgArray(char * filename)
{
char
*faceCascadeFilename = "haarcascade_frontalface_alt2.xml";
CvHaarClassifierCascade *cascade;
cascade =
(CvHaarClassifierCascade *)cvLoad(faceCascadeFilename,0,0,0);
CvRect
rc;
FILE *
imgListFile = 0;
char
imgFilename[512];
int iFace,
nFaces=0;
num =
0;
char
temp[512];
if(
!(imgListFile = fopen(filename, "r")) )
{
fprintf(stderr, "Can\'t open file %s\n", filename);
return 0;
}
//
统计人脸数
while(
fgets(imgFilename, 512, imgListFile) ) ++nFaces;
rewind(imgListFile);
//
分配人脸图像存储空间和人脸ID号存储空间
faceImgArr
= (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
for(iFace=0;
iFace
{
// 从文件中读取序号和人脸名称
fscanf(imgListFile,
"%d %s %s", personNumTruthMat->data.i+iFace, temp,
imgFilename);
if( num != *(personNumTruthMat->data.i+iFace) )
{
strcpy(name[num], temp);
num = *(personNumTruthMat->data.i+iFace);
}
// 加载人脸图像
faceImgArr[iFace] = cvLoadImage(imgFilename,
CV_LOAD_IMAGE_GRAYSCALE);
if( !faceImgArr[iFace] )
{
fprintf(stderr, "Can\'t load image from %s\n", imgFilename);
return 0;
}
rc = detectFaceInImage(faceImgArr[iFace], cascade);
if(rc.width == -1 && rc.height == -1) return -1;
cvSetImageROI(faceImgArr[iFace], rc);
IplImage *temp = cvCreateImage(cvSize(200, 250),
faceImgArr[iFace]->depth,
faceImgArr[iFace]->nChannels);
cvResize(faceImgArr[iFace], temp, CV_INTER_LINEAR);
cvResetImageROI(faceImgArr[iFace]);
faceImgArr[iFace] = processedImage(temp);
// faceImgArr[iFace] =
cvCloneImage(temp);
//
cvSaveImage(imgFilename, faceImgArr[iFace]);
printf("%d\n", iFace+1);
}
fclose(imgListFile);
return
nFaces;
}
//图片预处理
IplImage* processedImage(IplImage *imageSrc)
{
IplImage
*imageProcessed;
4000
IplImage
*imageGrey;
if(imageSrc->nChannels == 3)
{
imageGrey = cvCreateImage(cvGetSize(imageSrc), IPL_DEPTH_8U,
1);
cvCvtColor( imageSrc, imageGrey, CV_BGR2GRAY );
}
else
{
imageGrey = imageSrc;
}
imageProcessed = cvCreateImage( cvSize(200, 200), IPL_DEPTH_8U, 1
);
cvResize(imageGrey, imageProcessed, CV_INTER_LINEAR);
cvEqualizeHist(imageProcessed, imageProcessed);
return
imageProcessed;
}
结果展示:
精确度有80%, 出奇高这次, 呵呵~~可能代码发现我要把它保存好. 这个学期学习opencv还是很好玩的.
自己继续加油吧!!!
这个学期的软件工程作业----人脸识别系统, 基本功能还是实现了,
具体思路从国外一篇博客
学习而得, http://www.shervinemami.info/faceRecognition.html,
写的非常好. 具体实现的方法呢,
我就不讲解了, 看了就懂. 需要完整代码可以留言.
还是前面总结的问题"道"与"术"的问题, 学习要
学习解决方法的思路.
难点: 人脸库的制作, 人脸的照片需要计算出特征向量, PCA主成分析法.
提高人脸识别精确度需要自己
根据具体情况取照片. 以下是我的读入人脸的train.txt文件(部分).
我用的是每人20张照片, 实验证明
相识度计算出来大概是40%~60%左右.
1 shanghe tt\shanghe\1.jpg
1 shanghe tt\shanghe\2.jpg
1 shanghe tt\shanghe\3.jpg
2 zhijie tt\zijie\1.jpg
2 zhijie tt\zijie\2.jpg
2 zhijie tt\zijie\3.jpg
3 haoru tt\haoru\1.jpg
3 haoru tt\haoru\2.jpg
3 haoru tt\haoru\3.jpg
4 benson tt\jiayong\1.jpg
4 benson tt\jiayong\2.jpg
4 benson tt\jiayong\3.jpg
贴一些核心代码:(不完整, 不熟悉的代码不要随便用!!!)
//计算欧拉距离
//寻找最接近的图像
int findNearestNeighbor(float * projectedTestFace)
{
double
leastDistSq =
DBL_MAX; //定义最小距离,并初始化为无穷大
int i,
iTrain, iNearest = 0;
for(iTrain=0; iTrain
{
double distSq=0;
for(i=0; i
{
float d_i =
projectedTestFace[i] -
projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
distSq += d_i*d_i; // Euclidean算法计算的距离
}
if(distSq < leastDistSq)
{
leastDistSq = distSq;
iNearest = iTrain;
}
}
fConfidence
= 1.0f - sqrt( leastDistSq / (float)(nTrainFaces * nEigens) ) /
255.0f;
iCount++;
if(
fConfidence > thres )
recCount++;
printf("Confidence = %f\n",fConfidence);
if(fConfidence < 0.40) return -1;
//根据具体情况设置阀值
return
iNearest;
}
//主成分分析
void doPCA()
{
int i;
CvTermCriteria calcLimit;
CvSize
faceImgSize;
//
自己设置主特征值个数
nEigens =
nTrainFaces-1;
//分配特征向量存储空间
faceImgSize.width =
faceImgArr[0]->width;
faceImgSize.height = faceImgArr[0]->height;
eigenVectArr
= (IplImage**)cvAlloc(sizeof(IplImage*) *
nEigens); //分配个数为住特征值个数
for(i=0;
i
eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F,
1);
//分配主特征值存储空间
eigenValMat
= cvCreateMat( 1, nEigens, CV_32FC1 );
//
分配平均图像存储空间
pAvgTrainImg
= cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
//
设定PCA分析结束条件
calcLimit =
cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
//
计算平均图像,特征值,特征向量
cvCalcEigenObjects(
nTrainFaces,
(void*)faceImgArr,
(void*)eigenVectArr,
CV_EIGOBJ_NO_CALLBACK,
0,
0,
&calcLimit,
pAvgTrainImg,
eigenValMat->data.fl);
cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
}
//加载txt文件的列举的图像
int loadFaceImgArray(char * filename)
{
char
*faceCascadeFilename = "haarcascade_frontalface_alt2.xml";
CvHaarClassifierCascade *cascade;
cascade =
(CvHaarClassifierCascade *)cvLoad(faceCascadeFilename,0,0,0);
CvRect
rc;
FILE *
imgListFile = 0;
char
imgFilename[512];
int iFace,
nFaces=0;
num =
0;
char
temp[512];
if(
!(imgListFile = fopen(filename, "r")) )
{
fprintf(stderr, "Can\'t open file %s\n", filename);
return 0;
}
//
统计人脸数
while(
fgets(imgFilename, 512, imgListFile) ) ++nFaces;
rewind(imgListFile);
//
分配人脸图像存储空间和人脸ID号存储空间
faceImgArr
= (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
for(iFace=0;
iFace
{
// 从文件中读取序号和人脸名称
fscanf(imgListFile,
"%d %s %s", personNumTruthMat->data.i+iFace, temp,
imgFilename);
if( num != *(personNumTruthMat->data.i+iFace) )
{
strcpy(name[num], temp);
num = *(personNumTruthMat->data.i+iFace);
}
// 加载人脸图像
faceImgArr[iFace] = cvLoadImage(imgFilename,
CV_LOAD_IMAGE_GRAYSCALE);
if( !faceImgArr[iFace] )
{
fprintf(stderr, "Can\'t load image from %s\n", imgFilename);
return 0;
}
rc = detectFaceInImage(faceImgArr[iFace], cascade);
if(rc.width == -1 && rc.height == -1) return -1;
cvSetImageROI(faceImgArr[iFace], rc);
IplImage *temp = cvCreateImage(cvSize(200, 250),
faceImgArr[iFace]->depth,
faceImgArr[iFace]->nChannels);
cvResize(faceImgArr[iFace], temp, CV_INTER_LINEAR);
cvResetImageROI(faceImgArr[iFace]);
faceImgArr[iFace] = processedImage(temp);
// faceImgArr[iFace] =
cvCloneImage(temp);
//
cvSaveImage(imgFilename, faceImgArr[iFace]);
printf("%d\n", iFace+1);
}
fclose(imgListFile);
return
nFaces;
}
//图片预处理
IplImage* processedImage(IplImage *imageSrc)
{
IplImage
*imageProcessed;
4000
IplImage
*imageGrey;
if(imageSrc->nChannels == 3)
{
imageGrey = cvCreateImage(cvGetSize(imageSrc), IPL_DEPTH_8U,
1);
cvCvtColor( imageSrc, imageGrey, CV_BGR2GRAY );
}
else
{
imageGrey = imageSrc;
}
imageProcessed = cvCreateImage( cvSize(200, 200), IPL_DEPTH_8U, 1
);
cvResize(imageGrey, imageProcessed, CV_INTER_LINEAR);
cvEqualizeHist(imageProcessed, imageProcessed);
return
imageProcessed;
}
结果展示:
精确度有80%, 出奇高这次, 呵呵~~可能代码发现我要把它保存好. 这个学期学习opencv还是很好玩的.
自己继续加油吧!!!
相关文章推荐
- ACM: 数学题 uva_11137
- 兴趣学习: 余弦定理的应用&nb…
- ACM: 二分题 uva 11627
- ACM: uva 11134
- ACM: LA 4254 记住…
- ACM: uva 10382
- ACM: 动态规划题 LA 4794
- ACM: 动态规划题 LA 3983
- ACM: 动态规划题 bnu 13149
- ACM: 动态规划题 uva 11825
- ACM: poj 1903
- ACM: uva_10755
- ACM: poj 3141
- Android五种储存方式—sqlite数据库存储
- ACM: poj 1964
- ACM: uva 3902
- 基于CXF Servlet方式发布Restful的Web服务(入门篇)
- ACM: 二分题 poj 3497
- ACM: uva 11210 &n…
- ACM: 暴力题 poj 2741