如何用opencv在一周内实现人物行为语义识别

如何用opencv在一周内实现人物行为语义识别,第1张

 支持向量机在解决二分类问题方面有着强大的威力(当然也可以解决多分类问题),性别识别是典型的二分类模式识别问题,因此很适合用SVM进行处理,同时OpenCv又对SVM进行了很好的封装,调用非常方便,因此我们在这个性别识别程序中考虑加入SVM方法。

在这里我们采用了HOG+SVM的模式来进行,即先提取图像的HOG特征,然后将这些HOG特征输入SVM中进行训练。

一、SVM概述

SVM的数学原理十分复杂,我们不在这里过多讨论,有关OpenCv中SVM的用法,这里为大家提供两篇博客以供参考:OpenCV的SVM用法以及OpenCV 24+ C++ SVM介绍。

二、HOG特征概述

HOG特征是图像的梯度特征,具体参见:目标检测的图像特征提取之(一)HOG特征

三、建立训练集

这里继续沿用上一篇博文中提到的性别识别训练集,400张男性人脸样本400张女性人脸样本,下载地址:性别识别数据集。

四、算法的训练与测试

1、建立控制台工程,配置OpenCv环境

这里将工程命名为:GenderSVM。

2、编写批量读取函数read_csv()

只要涉及到训练,都需要批量读取训练样本的 *** 作,SVM也不例外,因此需要先编写批量读取函数read_csv()。考虑到之前的批量读取函数必须一次性将所有训练样本读入内存中,内存消耗较大,在这里做一个小小的改进:

void read_csv(String& csvPath,Vector<String>& trainPath,Vector<int>& label,char separator = ';')

{

string line,path,classLabel;

ifstream file(csvPathc_str(),ifstream::in);

while (getline(file,line))

{

stringstream lines(line);

getline(lines,path,separator);

getline(lines,classLabel);

if (!pathempty()&&!classLabelempty())

{

trainPathpush_back(path);

labelpush_back(atoi(classLabelc_str()));

}

}

}

可见这里我们将输入参数由vector<Mat>改为vector<String>,然后返回装有训练样本的所有路径的容器,需要时在根据其中的路径进行读取,降低了内存占用量。

3、读入训练样本路径

string trainCsvPath = "E:\\性别识别数据库—CAS-PEAL\\attxt";

vector<String> vecTrainPath;

vector<int> vecTrainLabel;

read_csv(trainCsvPath,vecTrainPath,vecTrainLabel);

顺利批量读入路径:

4、训练初始化

在提取HOG特征之前,需要初始化训练数据矩阵:

/初始化训练数据矩阵/

int iNumTrain = 800;

Mat trainDataHog;

Mat trainLabel = Mat::zeros(iNumTrain,1,CV_32FC1);

需要强调的是SVM的训练数据必须都是CV_32FC1格式,因此这里显式的将标签矩阵trainLabel初始化为CV_32FC1格式,trainDataHog稍后进行初始化。

5、提取图像HOG特征

接下来循环读入所有的训练样本,提取HOG特征,放在训练数据矩阵中。考虑嵌套代码的复杂性,这里先给出整体代码,稍后解释:

/提取HOG特征,放入训练数据矩阵中/

Mat imageSrc;

for (int i = 0; i < iNumTrain; i++)

{

imageSrc = imread(vecTrainPath[i]c_str(),1);

resize(imageSrc,imageSrc,Size(64,64));

HOGDescriptor hog = new HOGDescriptor(cvSize(64,64),cvSize(16,16),

cvSize(8,8),cvSize(8,8),9);

vector<float> descriptor;

hog->compute(imageSrc,descriptor,Size(1,1),Size(0,0));

if (i == 0)

{

trainDataHog = Mat::zeros(iNumTrain,descriptorsize(),CV_32FC1);

}

int n = 0;

for (vector<float>::iterator iter = descriptorbegin();iter != descriptorend();iter++)

{

trainDataHogat<float>(i,n) = iter;

n++;

}

trainLabelat<float>(i,0) = vecTrainLabel[i];

}

接下来我们对这段代码进行详细解释。

(1)循环读入训练样本

从vecTrainPath容器中逐条取出训练样本路径,然后读取:

imageSrc = imread(vecTrainPath[i]c_str(),1);

(2)尺寸归一化

我们这里将图像尺寸归一化为6464,这是因为当时在写程序时参考了一篇关于HOG特征的博客。这里的尺寸大家可以随意设定,当然也会影响最终的识别效率,6464可能并不是一个最优的尺寸:

imageSrc = imread(vecTrainPath[i]c_str(),1);

resize(imageSrc,imageSrc,Size(64,64));

(3)计算HOG特征

OpenCv给出的HOG特征计算接口非常简洁,三句话即完成:

HOGDescriptor hog = new HOGDescriptor(cvSize(64,64),cvSize(16,16),

cvSize(8,8),cvSize(8,8),9);

vector<float> descriptor;

hog->compute(imageSrc,descriptor,Size(1,1),Size(0,0));

提取的特征以容器的数据 结构形式给出。至于计算时的参数设定,参见我之前提供的那两篇博客即可。

(4)初始化数据矩阵trainDataHog

前面提到,SVM中用到的训练数据矩阵必须是CV_32FLOAT形式的,因此需要对数据矩阵显示的指定其尺寸和类型。然后由于trainDataHog行数为训练样本个数,而列数为HOG特征的维数,因此无法在进行HOG特征提取之前确定其尺寸,因此这里选择在进行完第一张样本的HOG特征、得到对应维数之后,在进行初始化:

if (i == 0)

{

trainDataHog = Mat::zeros(iNumTrain,descriptorsize(),CV_32FC1);

}

(5)将得到的HOG特征存入数据矩阵

得到的HOG特征是浮点数容器的形式,我们需要将其转换成矩阵的形式以便于训练SVM,这就涉及到了vector和Mat两个数据结构的遍历。vector遍历这里推荐使用迭代器的方式,而Mat遍历这里则选择了相对耗时但是最简单的方式——直接使用at函数:

int n = 0;

for (vector<float>::iterator iter = descriptorbegin();iter != descriptorend();iter++)

{

trainDataHogat<float>(i,n) = iter;

n++;

}

trainLabelat<float>(i,0) = vecTrainLabel[i];

训练得到的HOG特征如图所示:

可见在当前的参数设定下,提取到的HOG特征为1764维,共800张训练样本,每一行代表一个的HOG特征向量。通过“ctrl+鼠标滚轮”放大观察特征向量的具体参数:

6、训练SVM分类器

有关OpenCv中SVM分类器的使用可以参见以下博客:OpenCV 24+ C++ SVM介绍。

首先,初始化相关参数:

/初始化SVM分类器/

CvSVM svm;

CvSVMParams param;

CvTermCriteria criteria;

criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );

param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF,

100, 009, 10, 100, 05, 10, NULL, criteria );

开始训练、训练完成后保存分类器:

/训练并保存SVM/

svmtrain(trainDataHog,trainLabel,Mat(),Mat(),param);

svmsave("E:\\性别识别数据库—CAS-PEAL\\SVM_SEX_Modeltxt");

注意我们这里选择将分类器保存为txt形式:

当然,我们可以打开这个txt文件,查看里面的参数:

7、测试分类效果

测试过程和训练过程基本相同,读取、尺寸归一化、提取HOG特征、预测:

/测试SVM分类性能/

Mat testImage = imread("E:\\性别识别数据库—CAS-PEAL\\测试样本\\女性测试样本\\face_35bmp");

resize(testImage,testImage,Size(64,64));

HOGDescriptor hog = new HOGDescriptor(cvSize(64,64),cvSize(16,16),

cvSize(8,8),cvSize(8,8),9);

vector<float> descriptor;

hog->compute(testImage,descriptor,Size(1,1),Size(0,0));

Mat testHog = Mat::zeros(1,descriptorsize(),CV_32FC1);

int n = 0;

for (vector<float>::iterator iter = descriptorbegin();iter != descriptorend();iter++)

{

testHogat<float>(0,n) = iter;

n++;

}

int predictResult = svmpredict(testHog);

8、完整代码

 这里给出HOG+SVM进行性别识别的完整代码:

// GenderSVMcpp : 定义控制台应用程序的入口点。

//

#include "stdafxh"

#include <opencv2\opencvhpp>

#include <iostream>

#include <sstream>

#include <fstream>

using namespace std;

using namespace cv;

void read_csv(String& csvPath,vector<String>& trainPath,vector<int>& label,char separator = ';')

{

string line,path,classLabel;

ifstream file(csvPathc_str(),ifstream::in);

while (getline(file,line))

{

stringstream lines(line);

getline(lines,path,separator);

getline(lines,classLabel);

if (!pathempty()&&!classLabelempty())

{

trainPathpush_back(path);

labelpush_back(atoi(classLabelc_str()));

}

}

}

int _tmain(int argc, _TCHAR argv[])

{

/批量读入训练样本路径/

string trainCsvPath = "E:\\性别识别数据库—CAS-PEAL\\attxt";

vector<String> vecTrainPath;

vector<int> vecTrainLabel;

read_csv(trainCsvPath,vecTrainPath,vecTrainLabel);

/初始化训练数据矩阵/

int iNumTrain = 800;

Mat trainDataHog;

Mat trainLabel = Mat::zeros(iNumTrain,1,CV_32FC1);

/提取HOG特征,放入训练数据矩阵中/

Mat imageSrc;

for (int i = 0; i < iNumTrain; i++)

{

imageSrc = imread(vecTrainPath[i]c_str(),1);

resize(imageSrc,imageSrc,Size(64,64));

HOGDescriptor hog = new HOGDescriptor(cvSize(64,64),cvSize(16,16),

cvSize(8,8),cvSize(8,8),9);

vector<float> descriptor;

hog->compute(imageSrc,descriptor,Size(1,1),Size(0,0));

if (i == 0)

{

trainDataHog = Mat::zeros(iNumTrain,descriptorsize(),CV_32FC1);

}

int n = 0;

for (vector<float>::iterator iter = descriptorbegin();iter != descriptorend();iter++)

{

trainDataHogat<float>(i,n) = iter;

n++;

}

trainLabelat<float>(i,0) = vecTrainLabel[i];

}

/初始化SVM分类器/

CvSVM svm;

CvSVMParams param;

CvTermCriteria criteria;

criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );

param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF,

100, 009, 10, 100, 05, 10, NULL, criteria );

/训练并保存SVM/

svmtrain(trainDataHog>

公开人脸数据集

本页面收集到目前为止可以下载到的人脸数据库,可用于训练人脸深度学习模型。

人脸识别

数据库

描述

用途

获取方法

WebFace 10k+人,约500K张 非限制场景 链接

FaceScrub 530人,约100k张 非限制场景 链接

YouTube Face 1,595个人 3,425段视频 非限制场景、视频 链接

LFW 5k+人脸,超过10K张 标准的人脸识别数据集 链接

MultiPIE 337个人的不同姿态、表情、光照的人脸图像,共750k+人脸图像 限制场景人脸识别 链接 需购买

MegaFace 690k不同的人的1000k人脸图像 新的人脸识别评测集合 链接

IJB-A 人脸识别,人脸检测 链接

CAS-PEAL 1040个人的30k+张人脸图像,主要包含姿态、表情、光照变化 限制场景下人脸识别 链接

Pubfig 200个人的58k+人脸图像 非限制场景下的人脸识别 链接

人脸检测

数据库

描述

用途

获取方法

FDDB 2845张中的5171张脸 标准人脸检测评测集 链接

IJB-A 人脸识别,人脸检测 链接

Caltech10k Web Faces 10k+人脸,提供双眼和嘴巴的坐标位置 人脸点检测 链接

人脸表情

数据库

描述

用途

获取方法

CK+ 137个人的不同人脸表情视频帧 正面人脸表情识别 链接

人脸年龄

数据库

描述

用途

获取方法

IMDB-WIKI 包含:IMDb中20k+个名人的460k+张 和维基百科62k+张, 总共: 523k+张 名人年龄、性别 链接

Adience 包含2k+个人的26k+张人脸图像 人脸性别,人脸年龄段(8组) 链接

CACD2000 2k名人160k张人脸 人脸年龄 链接

人脸性别

数据库

描述

用途

获取方法

IMDB-WIKI 包含:IMDb中20k+个名人的460k+张 和维基百科62k+张, 总共: 523k+张 名人年龄、性别 链接

Adience 包含2k+个人的26k+张人脸图像 人脸性别,人脸年龄段(8组) 链接

人脸关键点检测

数据库

描述

用途

获取方法

数据库 描述 用途 获取方法

人脸其它

数据库

描述

用途

获取方法

CeleBrayA 200k张人脸图像40多种人脸属性 人脸属性识别 获取方法

GitHub:DeepFace

以上就是关于如何用opencv在一周内实现人物行为语义识别全部的内容,包括:如何用opencv在一周内实现人物行为语义识别、怎么区分 nonparametric data 和 parametric data、求下载过cacd2000数据集,Adience数据集和IMDB-WIKI数据集的大神能分享到我的邮箱,不胜感激!!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9792191.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存