源代码来自http://hi.baidu.com/lvchengbin405/blog/item/82c059cb8203c8f552664f98.html
本人截取其中训练和识别部分的代码进行注释。 训练部分: void Face::TrainHMM(HMMParams params) m_hmm = cvCreate2DHMM(params.stateNum, params.mixNum, vect_len);//创建隐马尔科夫模型,第一个参数为初始状态数,第二个参数高斯混合矩阵,具体作用不明,但感觉是在函数cvEstimateHMMStateParams中使用,重复计算隐马尔科夫模型,第三个参数是观测向量的大小 int num_img = m_p_w_picpathlist.size(); // 从图像中提取的观测向量,即DCT系数 // 由混合分量来分割HMM的每个内在状态的所有观测值 bool trained = false; // 识别部分:识别部分主要是根据所得的观测向量,通过viterbi算法,与数据库中的每个subject的隐马尔科夫模型进行运算,选取其中最大的概率的subject void FaceRecognition::Recognize(IplImage* ipl) CvSize num_obs; CV_COUNT_OBS(&cvroi, &m_hmmp.dctSize, &m_hmmp.delta, &num_obs); int vect_len = m_hmmp.obsSize.height * m_hmmp.obsSize.width; info = cvCreateObsInfo(num_obs, vect_len); cvImgToObs_DCT(ipl, info->obs, m_hmmp.dctSize, m_hmmp.obsSize, m_hmmp.delta); float max_like = -100000000; cvEstimateObsProb(info, hmm);//获取图像的观测矩阵 for (int i = 0; i < MIN(3, per_num); i++)//选择最大概率 for(int j = 0; j < per_num; j++)
{
if (Release() == false)
return;
int vect_len = params.obsSize.height * params.obsSize.width;
m_vectSize = vect_len;
CvImgObsInfo** obs_info_array = new CvImgObsInfo*[num_img];//观测向量的信息
list<char*>::iterator it;
int i = 0;
for(it=m_p_w_picpathlist.begin(); it!=m_p_w_picpathlist.end(); it++)
{
IplImage* ipl = cvLoadImage(*it, -1);
if (ipl == NULL)
return;
CvSize num_obs;
CvSize roi = cvSize( ipl->roi ? ipl->roi->width : ipl->width,
ipl->roi ? ipl->roi->height : ipl->height);//获取所需要分段的区域
CV_COUNT_OBS(&roi, &(params.dctSize), &(params.delta), &num_obs);//获取num_obs,此为一图像要分成的段数,第一个参数是所要分段的图像,第二个参数是分段所使用的向量的大小,第三个是相邻两段的重叠大小
obs_info_array[i] = cvCreateObsInfo(num_obs, vect_len);//创建观测向量信息
CvImgObsInfo* info = obs_info_array[i];
cvImgToObs_DCT(ipl, info->obs, params.dctSize, params.obsSize, params.delta);
// 以HMM状态统一分割图像观测值
cvUniformImgSegm(info, m_hmm);
i++;
}
cvInitMixSegm(obs_info_array, num_img, m_hmm);
float old_likelihood = 0;
int counter = 0;
while ((!trained) && (counter<params.maxiterations))//开始训练
{
counter++;
int j;
// 计算每个HMM状态中的所有内在参数
cvEstimateHMMStateParams(obs_info_array, num_img, m_hmm);
// 运用现有的图像观测值分割为所有嵌入和内部的HMM函数,计算可能的变换矩阵
cvEstimateTransProb(obs_info_array, num_img, m_hmm);
float likelihood = 0;
for (j=0; j<num_img; j++)
{
cvEstimateObsProb(obs_info_array[j], m_hmm);//获取观测向量矩阵,由上述的dct进行运算所得
likelihood += cvEViterbi(obs_info_array[j], m_hmm);//Viterbi算法,计算最有可能的隐马尔科夫模型,即两次迭代的概率不超过阈值0.01
}
likelihood /= num_img*obs_info_array[0]->obs_size;
//
cvMixSegmL2(obs_info_array, num_img, m_hmm);
trained = (fabs(likelihood - old_likelihood) < 0.01);
old_likelihood = likelihood;
}
for(i=0; i<num_img; i++)
{
cvReleaseObsInfo(&(obs_info_array[i]));
}
m_trained = true;
}
{
float like_array[1000];
CvSize cvroi = cvSize(ipl->roi ? ipl->roi->width : ipl->width,
ipl->roi ? ipl->roi->height : ipl->height);
CvImgObsInfo* info;
list<Person*>::iterator it;
Person* per;
int per_num=0;
for (it=m_personList.begin(); it!=m_personList.end(); it++)
{
CvEHMM* hmm = 0;
per = *it;
if (!per->GetFace()->IsTrained())
{
m_rnum = -1;
return;
}
hmm = per->GetFace()->GetEHMM();
if (!hmm) //person not trained
{
m_rnum = -1;
return;
}
like_array[per_num++] = cvEViterbi(info, hmm);//据算概率
}
cvReleaseObsInfo(&info);
{
float maxl = -FLT_MAX;
int maxind = -1;
{
if (like_array[j] > maxl)
{
maxl = like_array[j];
maxind = j;
}
}
m_threeFirst[i] = maxind;
like_array[maxind] = -FLT_MAX;
}
m_rnum = MIN(3, per_num);
}
HMM Face Recognition Code解析
转载下一篇:博弈知识汇总
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
人脸识别 face_recognition
Github开源人脸识别项目face_recognition,face_recognition是一个强大、简单、易上手的人脸识别开源项
计算机视觉 opencv python 加载 人脸识别 -
python的face_recognition库 python recognition
如今是人工智能时代,人脸识别也是一大应用。我们的手机人脸解锁、火车站人脸识别检票、公积金查询的人脸识别登陆等等,总之,用处很是广泛。那么人脸识别是怎么完成的?这里你肯定要说一些复杂的算法,不用,Python的开源库Face Recognition帮助你实现操作。据说识别率达到99.38%,这肯定是一件很有趣的事情,下面我们来看看如何实现吧。 人工智能时代 在写文章之前,可以说是经历了千辛
python jpg转数组 python 人脸识别 python人脸识别 python人脸识别框很小 python安装dlib失败