Τ闽intface?拜肈- 屡︹?鏓 BlueShop
?芖程?祘Α砞璸?竤呼?
穦?羆计?238830
癚阶?肈?185362
舧?眤?禣??穦?
癚阶跋匡虫
︽笆杆竚秨祇
?碈砰 / 呼恨
&& Τ闽intface?拜肈
Τ闽intface?拜肈
基? : 500 QP&&翴綷计:2985 ?莱计:14
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
叫毙?????秈:??癸??ン旧??芠├獶盽痢畓 ???稱糶??interface ㄒ? ???interface 赣??龟暗 ?のㄏノよΑ ??叫???秈?癸?(?厩???灿)糶碭?絛ㄒ ???谅筁?} public interface accessdb{
//ㄏノsql??琩高戈? 肚?sql commandbool queryData(string strSQL);//?埃戈? 肚?戈???嘿 ?のwhere兵ンbool deletedata(string tablename, string where);//块?戈? 肚?戈???嘿 逆??嘿 逆??bool insertdata(string tablename, string[] filename, object[] filevalue);//?穝戈? 肚?戈???嘿 key??嘿 key? 逆??嘿 逆??bool updateData(string tablename, string keyname, object key, string[] filename,object[] filevalue);//肚?procedurebool execStoredProduce(string SPName);//?眔?笆絪腹?int getIdentity();}
セ絞ゅ彻祇?? 12:18
程Τ基?秆氮
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
class Class1:accessdb
#region accessdb Θ?
public bool queryData(string strSQL)
public bool deletedata(string tablename, string where)
public bool insertdata(string tablename, string[] filename, object[] filevalue)
public bool updateData(string tablename, string keyname, object key, string[] filename, object[] filevalue)
public bool execStoredProduce(string SPName)
throw new Exception(&The method or operation is not implemented.&);
public int getIdentity()
throw new Exception(&The method or operation is not implemented.&);
#endregion
セ絞ゅ彻?滦? 12:35
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
ぃ岿?把σ
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
矗ㄑ倒眤把σ....http://www.wretch.cc/blog/nobel12&category_id=柑?Τ碭絞ゅ彻闽?眤┮矗?? issue?辨癸?Τ┮腊?~~~
セ絞ゅ彻?滦? 12:42
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
ぃ岿?把σ
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
?稱ノ瓜???ぃ筁тぃ??肚?丁VS2005???笆玻ネざ??祘Α絏???膥尿?ざ?? public class MyAccessDB:accessdb?翴?accessdb?ウ穦?瞷??┏瞷??翴????匡龟?accessdbざ?硂妓ウ碞穦??玻ネ璶龟??ざ?よ猭(程?临琌璶???龟?)============ざ???干????Τノ?北?糶祘Α盾??北?祘Α?秈?翴碞??眖Main()?狦?Τ??盡??稱俱瞶?ㄇ玂痙?祘Α絏??穦?或俱瞶?Τ??ぃ岿?よ猭碞琌﹚?ざ???
interface IMySample
void ShowReslut();
и﹚竡???ざ?? IMySampleи?盡???р–?絛ㄒ常縒ミ?Θ??摸?
class DataTable_Method : IMySample
public void ShowReslut()
DataTable dt = GetSampleDT();
Console.pute(&SUM(engScore)&, &&));
private DataTable CopyDT(DataTable dt)
return dt.Copy();
private DataTable GetSampleDT()
DataTable dt = new DataTable();
dt.Columns.Add(&userId&);
dt.Columns.Add(&userName&);
dt.Columns.Add(&engScore&, typeof(int));
dt.Columns.Add(&chScore&, typeof(int));
dt.Rows.Add(&011&, &Bill&, 55, 82);
dt.Rows.Add(&015&, &John&, 52, 72);
dt.Rows.Add(&001&, &Joe&, 31, 62);
dt.Rows.Add(&005&, &Jack&, 65, 89);
dt.Rows.Add(&012&, &Marry&, 75, 53);
public enum MyEnum { A, B, C };
class Enum_Sample:IMySample
public void ShowReslut()
Console.WriteLine(Enum.GetName(typeof(MyEnum), 1));
Console.WriteLine(new String('=', 20));
foreach (string str in Enum.GetNames(typeof(MyEnum)))
Console.WriteLine(str);
程??Main()柑??璶new?龟???ン???磅︽ざ??よ猭??
public static void Main()
//IMySample mySample = new DataTable_Method(); //戈???絛ㄒ
IMySample mySample = new Enum_Sample();
//?羭?絛ㄒ
//===================== ?璶э?????ぃノэ
mySample.ShowReslut();
把σ??翅^^
セ絞ゅ彻?滦? 07:52
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
ぃ岿?把σ
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
笷?笷?羭硂ㄒ?临芞次?~~
?睲贰....
セ絞ゅ彻?滦? 09:36
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
ぃ岿?把σ
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
?拜???叫毙?????ざ?柑?ぃ???跑计??狦⊿Τ??ざ???钡рclass new?ㄓ?ぃ琌?Τ?妓??狦盾?
セ絞ゅ彻?滦? 12:03
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
????璝ぃノざ??杠璶ノ膥┯?Τ摸??狦ぃ筁ざ?籔膥┯?Τ翴ぃ?妓ざ?眏?┮ΤΘ?常璶龟暗ざ?琌﹚竡摸????籔︽???稱Θ琌摸?????芠種?琌behave like(︽?钩)τ膥┯琌is a┮?硄盽и???弧?摸?琌?摸?钩琌?摸膥┯徊ㄅ摸и?碞??弧?摸琌徊ㄅ摸
セ絞ゅ彻?滦? 13:14
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
ぃ筁и????俱计跑计?玱?岿????琌[ざ?ぃ???逆?]?琌и???よΑぃ癸盾?
セ絞ゅ彻?滦? 13:30
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
琌盾?狦?岿粇癟?常硂妓糶???ぃ︽?VB.NET??C#иぃ琌?絋﹚碞琌?
セ絞ゅ彻?滦? 13:34
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
稼祔稬刚???VB.NET琌ぃ?ノ逆????ノ妮┦C#莱赣?琌???Θ妮┦??
セ絞ゅ彻?滦? 13:37
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
??俱计跑计?ぃ碞琌妮┦盾?
interface myIn
//??ざ?
int push(int Var);
//砏﹚ㄧ计
int pop();
int a = 5; //硂︽岿粇
?????ゅ?祇瞷ざ??礚猭??妮┦?ぃ筁и??玱弧????
セ絞ゅ彻?滦? 13:59
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
interface Interface1
セ絞ゅ彻?滦? 14:36
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
?ㄓ妮┦琌?硂????阀?秆??Τ翴陈沸??ㄓ稱膥┯妮┦?临琌ノ┾禜摸??滦糶穦ゑ耕??Μ矛▆??稰谅???毙旧??
セ絞ゅ彻?滦? 15:13
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
to #12,?狦眤稱?琌膥┯,讽礛碞ぃ穦稱璶ㄏノざ??ぃ筁и??キ?耕盽糶ざ?,耕ぶ糶?膥┯碞琌?
セ絞ゅ彻?滦? 16:18
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
130){this.width=130;};if(this.height>130){this.height=130;}' onerror="this.src='/images/nophoto.gif'" onmousewheel="return ChgImgSize(this)" />
/zh-tw/library/ms229022(VS.80).aspx/zh-tw/library/cc437459(VS.71).aspx
セ絞ゅ彻?滦? 01:24
== 帽?郎 ==
--ゼ祅??穦?礚猭琩?癸よ帽?郎--
?璶?莱,叫?.私信发送成功
检测到您已登录开源中国,是否
系统将自动刷新
项目的主人没有开启捐赠功能,快通知他让他开启吧!
Fork 将在后台执行,是否继续?
人脸识别SDK
采用C++编写,支持两张照片进行比对1:1,以及1:N 人脸搜索
最后提交于
Loading...
FaceSDK
人脸识别SDK 采用C++编写,支持两张照片进行比对1:1,以及1:N 人脸搜索,SDK内部自己维护人脸特征数据,支持增、删、查找等操作,上层应用程序只需要关注自己的业务逻辑即可
支持库下载地址:
提供一个人脸识别的demo软件,下载地址:
SDK API ListCComFaceSDK(void);
//Summary: 比较两张照片的相似度
//Parameters:
//
imgPath1:照片1路径.
//
imgPath2:照片2路径.
//Return : 相似度
float Compare2Image(char* imgPath1, char* imgPath2);
//Summary: 比较两张照片的相似度
//Parameters:
//
imgBuffer1:照片1内存区.
//
imgBuffer1Length:照片1内存区长度.
//
imgBuffer2:照片2内存区.
//
imgBuffer2Length:照片2内存区长度.
//Return : 相似度
float Compare2Image(unsigned char* imgBuffer1,int imgBuffer1Length, unsigned char* imgBuffer2,int imgBuffer2Length);
//Summary: 比较两个人脸的相似度
//Parameters:
//
uid1:照片1编号.
//
uid2:照片2编号.
//Return : 相似度
float Compare2Uid(unsigned int uid1, unsigned int uid2);
//Summary: 注册人脸
//Parameters:
//
uid:人脸uid,这个需要在sdk外部自己定义.
//
imgPath:照片路径.
//Return : 0 表示成功,其他表示失败
int Data_Insert(unsigned int uid, char* imgPath);
//Summary: 注册人脸
//Parameters:
//
uid:人脸uid,这个需要在sdk外部自己定义.
//
imgBuffer:照片内存区.
//
imgBufferLength:照片内存区长度.
//Return : 0 表示成功,其他表示失败
int Data_Insert(unsigned int uid, unsigned char* imgBuffer,int imgBufferLength);
//Summary: 搜索相似脸
//Parameters:
//
imgPath:照片路径.
//
matchNode: 最相似结果.
//Return : 0 表示成功,其他表示失败
int Face_Search(char* imgPath, MatchNode &matchNode);
//Summary: 搜索相似脸
//Parameters:
//
uid:人脸uid,这个需要在sdk外部自己定义
//
matchNode: 最相似结果.
//Return : 0 表示成功,其他表示失败
int Face_Search(unsigned int uid, MatchNode &matchNode);
//Summary: 搜索相似脸
//Parameters:
//
imgPath:照片路径.
//
matchNodeArray:返回最相似的人脸结果数组,即top retNum.
//
retNum:按照相似度降序排序,返回最相似的人脸个数.
//Return : 0 表示成功,其他表示失败
int Face_Search(char* imgPath, MatchNode* matchNodeArray, int retNum);
//Summary: 搜索相似脸
//Parameters:
//
uid:人脸编号.
//
matchNodeArray:返回最相似的人脸结果数组,即top retNum.
//
retNum:按照相似度降序排序,返回最相似的人脸个数.
//Return : 0 表示成功,其他表示失败
int Face_Search(unsigned int uid, MatchNode* matchNodeArray, int retNum);
//Summary: 比较两张照片的相似度
//Parameters:
//
imgBuffer:照片内存区.
//
imgBufferLength:照片内存区长度.
//
matchNodeArray:返回最相似的人脸结果数组,即top retNum.
//
retNum:按照相似度降序排序,返回最相似的人脸个数.
//Return : 0 表示成功,其他表示失败
int Face_Search(unsigned char* imgBuffer,int imgBufferLength, MatchNode* matchNodeArray, int retNum);
//Summary: 查找uid是否在人脸库中出现过
//Parameters:
//
uid:注册人脸时的uid.
//Return : 0 表示成功,其他表示失败
int Data_Search(unsigned int uid);
//Summary:删除uid的人脸数据
//Parameters:
//
uid:注册人脸时的uid.
//Return : 0 表示成功,其他表示失败
int Data_Delete(unsigned int uid);
//Summary: 清空所有注册的人脸数据
//Parameters:
//Return : void
int Data_Clear();
//Summary: 获取目前已经注册的人脸特征个数
//Parameters:
//Return : 人脸特征个数
int Data_GetSize();
比对两张脸照片的相似度CComFaceSDK* FaceAPI = new CComFaceSDK();//初始化
char imgPath1[] = "1.jpg";
char imgPath2[] = "2.jpg";
//比较两张照片的相似度
float score = FaceAPI-&Compare2Image(imgPath1,imgPath2);
printf("similar=%f\n", score);
项目点评 (0 条)
你可以在登录后,对此项目发表评论8200人阅读
学习Opencv(3)
人脸识别要牵涉到一些数学计算和一些算法的理解,虽然这些算法和计算opencv已经帮我们完成,但我们还是要对其有一定的了解,才能进行人脸识别的实践,毕竟基础不牢,上层建筑也不稳。
要理解如何进行人脸识别,首先一定要理解主成分分析算法,即PCA,使用这种算法的原因是因为,一般图像数据量太大,而且其中的大部分数据点对我们进行人脸识别没有太大的帮助,因此为了减少数据量,采用了主成分分析法将数据进行压缩(算法中称为投影),然后用压缩后的图像进行图像识别的进一步应用。PCA的原理在前面的一篇文章中已经讲到过,大家可以参考:。肯能看完这个文章,大家开始对PCA有一定的理解,但总还是感觉有点模糊,因为那篇文章我只是转载,并没有进行太多自己的想法的标注,因此有些混乱,那么大家可以再继续读下面这篇文章:
在前面的PCA原理介绍中曾提到了两个函数,cvCalcPCA,cvProjectPCA。我在实际使用中参考了另外一篇文章,用的是另外两个函数,这个后面会讲到。这个不用太纠结,前面的文章可以只当学习原理的参考,等原理懂了之后看后面将要介绍的两个函数也会很简单。其中,有一点要说明,cvCalcPCA是新的PCA处理函数,而后面将要讲到的cvCalcEigenObjects是老的PCA处理函数。
经过上面的的两片文章相信大家应该对PCA的原理有所了解,下面开始讲怎样实现用PCA算法进行人脸识别。这个可以参考这篇文章:
这篇是英文文章,希望大家多读英文文章,因为我们在学习过程中如果遇到国内教材较少的情况,一般都是要参考国外的文章的,并且擅长阅读英文文章也为我们打开了通往另外一个更为博大的知识库的大门。读完这篇文章一定可以自己做出人脸识别程序的,因为这篇文章介绍的已经十分详细。
但是,在这里我还是将上面那篇文章的原理介绍一下。我下面的叙述主要是针对在一个图像库中找出我们给定的图像最接近的图像,以人脸图像为例也就是说数据库中肯定是包含我所给出的这个人的人脸,虽然数据库中的图片跟我给出的图片不是同一张图片,但必须是同一个人。
首先假如我有代号为1,2,3三个训练人的人脸图像,人脸大小调整为一致,例如文章中为92*112,在我们的分析中是以一个像素点作为一维,因此每个图像可以认为是一个1*10304的行向量,这样三个训练人的人脸图像就组成了一个3*10304的矩阵。(注意,实际中每个图像还是存在92*112的iplimage结构中,这里只是为了讲解方便而进行的假象)。根据这个矩阵,就可以计算出相应的协方差矩阵,大小为(这个大小我并没有考究,我觉得应该是这个大小,因为可以解释通上面那篇英文文章),接着再求出这个的矩阵的特征值和特征向量,并取前nEigens个(这个个数由我们自己确定,文章中是取nEigens为训练人个数-1)特征值(注意由于前面特征值已经是由大到小排好顺序的,因此这几个就是最大的几个)对应的特征向量组成10304*nEigens大小投影矩阵(注意这里发生了转置,有opencv函数内部完成),即所谓的特征脸(因为每一列的规模就是一张人脸图像的规模),也即子空间。然后再将每个大小为1*10304的训练人脸图像矩阵乘以这个投影矩阵,就可以得到每个图像在主成分子空间的投影,大小为1*nEigens,并用这个投影矩阵进行后续的分析。可见,经过投影后图像数据量大大减小。上面的计算投影矩阵的过程由cvCalcEigenObjects完成,而投影则由cvEigenDecomposite函数完成,具体实现见英文文章。为了方便理解这两个函数可以参见:,这个空间内有两篇介绍这两个函数的文章。
同样,当给出测试图像时,先将测试人脸缩放为与训练人脸相同的大小,即92*112,然后用前面的特征矩阵将其投影到子空间中,即投影为大小为1*nEigens的矩阵。接着就可以用这个子空间投影跟前面的训练图像在子空间的投影进行比较,最接近的就是目标图像。比较方法文章中也有提到,有欧式算法&Euclidean 和较新的&Mahalanobis算法。
至此,整个人脸识别原理已经讲完,虽然有点复杂,但花点时间也不难理解。
下面贴出文章中给出的程序,我进行了一些注释,使用方法程序头部也有介绍。
// eigenface.c, by Robin Hewitt, 2007
// Example program showing how to implement eigenface with OpenCV
// First, you need some face images. I used the ORL face database.
// You can download it for free at
www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
// List the training and test face images you want to use in the
// input files train.txt and test.txt. (Example input files are provided
// in the download.) To use these input files exactly as provided, unzip
// the ORL face database, and place train.txt, test.txt, and eigenface.exe
// at the root of the unzipped database.
// To run the learning phase of eigenface, enter
eigenface train
// at the command prompt. To run the recognition phase, enter
eigenface test
#include &stdio.h&
#include &string.h&
#include &cv.h&
#include &cvaux.h&
#include &highgui.h&
////定义几个重要的全局变量
IplImage ** faceImgArr
= 0; // 指向训练人脸和测试人脸的指针(在学习和识别阶段指向不同)
personNumTruthMat = 0; // 人脸图像的ID号
int nTrainFaces
= 0; // 训练图像的数目
int nEigens
= 0; // 自己取的主要特征值数目
IplImage * pAvgTrainImg
= 0; // 训练人脸数据的平均值
IplImage ** eigenVectArr
= 0; // 投影矩阵,也即主特征向量
CvMat * eigenValMat
= 0; // 特征值
CvMat * projectedTrainFaceMat = 0; // 训练图像的投影
//// 函数原型
void learn();
void recognize();
void doPCA();
void storeTrainingData();
loadTrainingData(CvMat ** pTrainPersonNumMat);
findNearestNeighbor(float * projectedTestFace);
loadFaceImgArray(char * filename);
void printUsage();
//主函数,主要包括学习和识别两个阶段,需要运行两次,通过命令行传入的参数区分
void main( int argc, char** argv )
// validate that an input was specified
if( argc != 2 )
printUsage();
//通过判断命令行参数分别执行学习和识别代码
if( !strcmp(argv[1], &train&) ) learn();
else if( !strcmp(argv[1], &test&) ) recognize();
printf(&Unknown command: %s\n&, argv[1]);
printUsage();
//学习阶段代码
void learn()
//加载训练图像集
nTrainFaces = loadFaceImgArray(&train.txt&);
if( nTrainFaces & 2 )
fprintf(stderr,
&Need 2 or more training faces\n&
&Input file contains only %d\n&, nTrainFaces);
// 进行主成分分析
//将训练图集投影到子空间中
projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
offset = projectedTrainFaceMat-&step / sizeof(float);
for(i=0; i&nTrainF i++)
//int offset = i * nE
cvEigenDecomposite(
faceImgArr[i],
eigenVectArr,
pAvgTrainImg,
//projectedTrainFaceMat-&data.fl + i*nEigens);
projectedTrainFaceMat-&data.fl + i*offset);
//将训练阶段得到的特征值,投影矩阵等数据存为.xml文件,以备测试时使用
storeTrainingData();
//识别阶段代码
void recognize()
int i, nTestFaces
// 测试人脸数
CvMat * trainPersonNumMat = 0;
// 训练阶段的人脸数
float * projectedTestFace = 0;
// 加载测试图像,并返回测试人脸数
nTestFaces = loadFaceImgArray(&test.txt&);
printf(&%d test faces loaded\n&, nTestFaces);
// 加载保存在.xml文件中的训练结果
if( !loadTrainingData( &trainPersonNumMat ) )
projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
for(i=0; i&nTestF i++)
int iNearest, nearest,
//将测试图像投影到子空间中
cvEigenDecomposite(
faceImgArr[i],
eigenVectArr,
pAvgTrainImg,
projectedTestFace);
iNearest = findNearestNeighbor(projectedTestFace);
= personNumTruthMat-&data.i[i];
= trainPersonNumMat-&data.i[iNearest];
printf(&nearest = %d, Truth = %d\n&, nearest, truth);
//加载保存过的训练结果
int loadTrainingData(CvMat ** pTrainPersonNumMat)
CvFileStorage * fileS
fileStorage = cvOpenFileStorage( &facedata.xml&, 0, CV_STORAGE_READ );
if( !fileStorage )
fprintf(stderr, &Can't open facedata.xml\n&);
nEigens = cvReadIntByName(fileStorage, 0, &nEigens&, 0);
nTrainFaces = cvReadIntByName(fileStorage, 0, &nTrainFaces&, 0);
*pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, &trainPersonNumMat&, 0);
eigenValMat
= (CvMat *)cvReadByName(fileStorage, 0, &eigenValMat&, 0);
projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, &projectedTrainFaceMat&, 0);
pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, &avgTrainImg&, 0);
eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
for(i=0; i&nE i++)
char varname[200];
sprintf( varname, &eigenVect_%d&, i );
eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
cvReleaseFileStorage( &fileStorage );
//存储训练结果
void storeTrainingData()
CvFileStorage * fileS
fileStorage = cvOpenFileStorage( &facedata.xml&, 0, CV_STORAGE_WRITE );
//存储特征值,投影矩阵,平均矩阵等训练结果
cvWriteInt( fileStorage, &nEigens&, nEigens );
cvWriteInt( fileStorage, &nTrainFaces&, nTrainFaces );
cvWrite(fileStorage, &trainPersonNumMat&, personNumTruthMat, cvAttrList(0,0));
cvWrite(fileStorage, &eigenValMat&, eigenValMat, cvAttrList(0,0));
cvWrite(fileStorage, &projectedTrainFaceMat&, projectedTrainFaceMat, cvAttrList(0,0));
cvWrite(fileStorage, &avgTrainImg&, pAvgTrainImg, cvAttrList(0,0));
for(i=0; i&nE i++)
char varname[200];
sprintf( varname, &eigenVect_%d&, i );
cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
cvReleaseFileStorage( &fileStorage );
//寻找最接近的图像
int findNearestNeighbor(float * projectedTestFace)
double leastDistSq = DBL_MAX;
//定义最小距离,并初始化为无穷大
int i, iTrain, iNearest = 0;
for(iTrain=0; iTrain&nTrainF iTrain++)
double distSq=0;
for(i=0; i&nE i++)
float d_i =
projectedTestFace[i] -
projectedTrainFaceMat-&data.fl[iTrain*nEigens + i];
distSq += d_i*d_i / eigenValMat-&data.fl[i];
// Mahalanobis算法计算的距离
// distSq += d_i*d_i; // Euclidean算法计算的距离
if(distSq & leastDistSq)
leastDistSq = distSq;
iNearest = iT
//主成分分析
void doPCA()
CvTermCriteria calcL
CvSize faceImgS
// 自己设置主特征值个数
nEigens = nTrainFaces-1;
//分配特征向量存储空间
faceImgSize.width
= faceImgArr[0]-&
faceImgSize.height = faceImgArr[0]-&
eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens); //分配个数为住特征值个数
for(i=0; i&nE 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,
&calcLimit,
pAvgTrainImg,
eigenValMat-&data.fl);
cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
//加载txt文件的列举的图像
int loadFaceImgArray(char * filename)
FILE * imgListFile = 0;
char imgFilename[512];
int iFace, nFaces=0;
if( !(imgListFile = fopen(filename, &r&)) )
fprintf(stderr, &Can\'t open file %s\n&, filename);
// 统计人脸数
while( fgets(imgFilename, 512, imgListFile) ) ++nF
rewind(imgListFile);
// 分配人脸图像存储空间和人脸ID号存储空间
faceImgArr
= (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
for(iFace=0; iFace&nF iFace++)
// 从文件中读取序号和人脸名称
fscanf(imgListFile,
&%d %s&, personNumTruthMat-&data.i+iFace, imgFilename);
// 加载人脸图像
faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
if( !faceImgArr[iFace] )
fprintf(stderr, &Can\'t load image from %s\n&, imgFilename);
fclose(imgListFile);
void printUsage()
printf(&Usage: eigenface &command&\n&,
Valid commands are\n&
}由于两个主要的函数cvCalcEigenObjects,cvEigenDecomposite的原型说明包含在cvaux.h,因此不要忘记添加该头文件。
通过上面的介绍,大家应该对人脸识别的方法有所了解,并针对自己的问题编写人脸识别程序了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:57510次
排名:千里之外
原创:19篇
评论:24条
(1)(1)(1)(1)(1)(7)(2)(4)(4)