您的位置:首页 > 其它

兴趣学习: 人脸识别系统实现 …

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还是很好玩的.
自己继续加油吧!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: