浅谈Openv中人脸识别类FaceRecognizer

如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢。 



   opencv2.4版本中封装了可用于人脸识别的类FaceRecognizer,其对应代码在动态链接库opencv_contrib249d.dll中(我用的是opencv2.4.9版本),这个动态链接库在opencv安装目录下可以找到,要想使用FaceRecognizer,首先要保证上述动态链接库正确配置。在此关于opencv的配置问题多说几句,就是建议大家尽量使用VS2010及以上版本来配置opencv,因为在最新的opencv2.4.9版本中已经添加了对vs2010及以上版本的自动支持,无需再用CMaker进行编译了,配置简单可靠。我之前用的是VS2008版本,在自己编译opencv_contrib249d.dll这个库时总提示编译出错,如果你也遇到了这个问题,建议你换装vs2010版本吧,至于具体如何配置网上有很多教程,这里不再赘述。

  FaceRecognizer这个类目前包含三种人脸识别方法:基于PCA变换的人脸识别(EigenFaceRecognizer)、基于Fisher变换的人脸识别(FisherFaceRecognizer)、基于局部二值模式的人脸识别(LBPHFaceRecognizer)。对于像我这样的人脸识别初学者,对人脸识别理论了解得不是很透彻,但并不影响对函数的使用,下面就EigenFaceRecognizer来详细的谈一下opencv人脸识别的实现。

  首先简单说一下PCA变换原理。在人脸识别过程中,一般把图片看成是向量进行处理,高等数学中我们接触的一般都是二维或三维向量,向量的维数是根据组成向量的变量个数来定的,例如就是一个二维向量,因为其有两个参量。而在将一幅图像抽象为一个向量的过程中,我们把图像的每个像素定为一维,对于一幅的普通图像来说,最后抽象为一个维的高维向量,如此庞大的维数对于后续图像计算式来说相当困难,因此有必要在尽可能不丢失重要信息的前提下降低图像维数,PCA就是降低图像维数的一种方法。图像在经过PCA变换之后,可以保留任意数量的对图像特征贡献较大的维数分量,也就是你可以选择降维到30维或者90维或者其他,当然最后保留的维数越多,图像丢失的信息越少,但计算越复杂。至于具体PCA变换的原理,网上有很多好的博客,也有很多专业论文来论证,有兴趣的可以查阅。

    下面来谈一谈具体如何使用这个人脸识别类。首先需要一个人脸库,因为你想让计算机识别人脸,首先得让计算机知道不同的人长什么样不同的脸。网上有很多现成的人脸数据库,我在做实验时选用了ORL数据库。数据库中包含40个人的人脸图像,每人十张,共400张,有bmp和png两种格式,大小均为。数据库中有光照变化(中心光照、左侧光照、右侧光照)、表情变化(开心、正常、悲伤、瞌睡、惊讶、眨眼)、眼镜(戴眼镜或者没戴),且包含男性图片和女性图片,比较适合做人脸识别的仿真实验。唯一的不足就是照片中全部为外国人,如果你想开发出一套人脸识别系统在国内用,建议还是费点功夫自己建一个合适的人脸数据库吧。

    人脸库确定之后需要进行训练,即让计算机“学习”这些人脸样本。这时面临的一个问题就是如何把训练样本读进内存中。opencv手册中明确说明EigenFaceRecognizer的训练函数的入口参数是一个图像容器,容器中包含所有训练图像。那么如何创建一个这样的容器并把训练样本全部放进去呢?方法有很多,我在实验中采用CSV文件读取方法。首先创建一个包含所有文件路径名的CSV文件,也就是一个文本文件。假设ORL数据库存放地址为:“E:\ORL”;在DOS窗口下输入命令:E:\ORL>dir /b/s *.bmp > at.txt,执行成功后发现在ORL文件夹下出现一个文本文件at.txt,里面内容如下(分号后面的标签是人为添加的):

E:\ORL\s1\1.bmp;1

E:\ORL\s1\10.bmp;1

E:\ORL\s1\2.bmp;1

E:\ORL\s1\3.bmp;1

E:\ORL\s1\4.bmp;1

E:\ORL\s1\5.bmp;1

E:\ORL\s1\6.bmp;1

E:\ORL\s1\7.bmp;1

E:\ORL\s1\8.bmp;1

E:\ORL\s1\9.bmp;1

E:\ORL\s10\1.bmp;10

E:\ORL\s10\10.bmp;10

E:\ORL\s10\2.bmp;10

E:\ORL\s10\3.bmp;10

E:\ORL\s10\4.bmp;10

E:\ORL\s10\5.bmp;10

E:\ORL\s10\6.bmp;10

E:\ORL\s10\7.bmp;10

E:\ORL\s10\8.bmp;10

E:\ORL\s10\9.bmp;10

    CSV文件创建成功后,可以在程序中读取文件了,网上有一段比较好的CSV读取代码,如下所示:

void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator =';') 

{

std::ifstream file(filename.c_str(), ifstream::in);//c_str()函数可用可不用,无需返回一个标准C类型的字符串

if (!file) {

string error_message ="No valid input file was given, please check the given filename.";

CV_Error(CV_StsBadArg, error_message);

}

string line, path, classlabel;

while (getline(file,line))//从文本文件中读取一行字符,未指定限定符默认限定符为“/n”

{

stringstream liness(line);//这里采用stringstream主要作用是做字符串的分割

getline(liness, path, separator);//读入图片文件路径以分好作为限定符

getline(liness, classlabel);//读入图片标签,默认限定符

if(!path.empty()&&!classlabel.empty())//如果读取成功,则将图片和对应标签压入对应容器中 

{

images.push_back(imread(path, 0));

labels.push_back(atoi(classlabel.c_str()));

}

}

}

    这段代码涉及C++中有关输入输出流iosream的相关知识,这里不作过多描述,如果需要的话可另写一篇文章来专门谈谈void read_csv()这个函数,需要说明的一点是:在使用这个函数的时候必须包含以下几个头文件:

#include <iostream>

#include <fstream>

#include <sstream>

    在完成训练数据读取之后就可以真正开始数据训练过程了,首先创建一个图像容器和标签容器来存储训练图像以及对应人脸标签,然后调用void read_csv()填充这两个容器,代码如下:

string fn_csv = "E:\\ORL\\at.txt";//读取你的CSV文件路径.

vector<Mat> images;// 2个容器来存放图像数据和对应的标签

vector<int> labels;

read_csv(fn_csv, images, labels);//从csv文件中批量读取训练数据

    然后创建一个PCA人脸分类器,暂时命名为model吧,创建完成后,调用其中的成员函数train()来完成分类器的训练,代码如下:

Ptr<FaceRecognizer> model = createEigenFaceRecognizer();

model->train(images, labels);

    注意,通过createEigenFaceRecognizer()函数来创建分类器时是可以人为指定训练结果的维数以及判别阈值,这里我们采用系统默认的参数。train()函数的执行时间与训练样本图片数目有关,训练ORL的400张图片大约需要一分钟,因此为了避免每次识别时都进行训练,推荐把训练得到的分类器model用save()函数保存成XML文件存储下来,下次用的时候直接用laod()加载就行,具体如下:

model->save("E:\\ORL_PCAModel.xml");//保存路径可自己设置,但注意用“\\”

    训练完成之后开始对新输入的图片进行识别,主要使用成员函数predict()来进行识别。注意predict()入口参数必须为单通道灰度图像,如果图像类型不符,需要先进行转换,predict()函数返回一个整形变量作为识别标签,代码如下:

model->load("E:\\ORL\\ORL_PCAModel.xml");//加载分类器

Mat testSample = imread("E:\\2.bmp",CV_LOAD_IMAGE_GRAYSCALE);//读入人脸图片

int predictedLabel = model->predict(testSample);

    函数运行完之后变量predictedLabel中存储了识别结果,整个人脸识别过程完成。

  需要注意的一点是:EigenFaceRecognizer在完成人脸识别后,还可以输出一些与训练集相关的结构,比如训练集的均值特征脸、重构特征脸等,不过这些与人脸识别的结果没有太大关系,在这里不作赘述。

   前面提到过,FaceRecognizer这个类除了支持PCA方法的人脸识别外,还支持另外两种方法,即Fisher变换和局部二值化模式,它们之间的用法大同小异,都是调用一些API函数,对原理不是很了解也没关系,有关代码我已经上传到网上,当然如果大家需要的话可以在评论中注明。 

  最后需要说明的一点,opencv中封装的这几个方法并不是单纯的为人脸识别服务的,同时人脸识别也不止有这几种方法。这几个函数本质上可以看成模式分类方法,即分类器。图像处理的很多问题最后都可以归结为分类问题,比如性别识别、警觉度识别、美丽度识别等等,人脸识别只是一个应用实例而已,大家不要被局限住,这是一个工具,一个可以用来解决很多分类问题的工具,有感兴趣的欢迎大家加群51701853一起讨论。

### 回答1: OpenV2G(Open Vehicle-to-Grid)是一种开放式的车辆对电网系统。它允许电动车与电网之间相互通信和交互,以实现双向能量流动。OpenV2G的运行如下: 首先,电动车需要与电网连接,通常是通过充电桩。充电桩是一个关键的组件,它提供了车辆与电网之间的物理连接。在充电过程,车辆向电网获取能量。 然后,OpenV2G启动交流过程。电动车和电网通过OpenV2G协议进行通信,交换信息和命令。OpenV2G协议定义了双方之间的通信规则和数据格式,以确保有效的能量流动和系统安全。 OpenV2G使得电动车能够根据电网需求灵活地提供能量。它可以通过将电能从电动车电池释放到电网上,以降低电网负荷。这对于电网调度和负荷管理非常有用,尤其是在需求高峰期。 同时,OpenV2G还允许电网向电动车提供能量,以满足车主的需求。这可以在车主需要额外能量时,例如在旅途充电时使用。OpenV2G可以确保能量在双向流动时的安全和可靠性。 最后,OpenV2G系统的运行还受到相关设备和软件的支持。这些设备和软件包括充电桩、电动车控制器、通信模块等。它们协同工作,以实现电动车与电网之间的顺畅能量交互。 总而言之,OpenV2G是通过充电桩和OpenV2G协议实现电动车与电网之间双向能量交互的开放式系统。它为电网调度、负荷管理和车主需求提供了新的解决方案,促进了可持续能源的应用。 ### 回答2: openv2g 是一种开放源代码的软件库,用于支持车辆与电网之间的双向通信和交互,实现智能充电和电网支持服务。下面是 openv2g 的运行流程: 1. 准备工作:首先,需要安装 openv2g 软件库,并确保它与所使用的车辆和电网通信硬件兼容。还需要进行安全设置,例如加密和身份验证,以保护通信和数据的安全性。 2. 接入电网:使用合适的通信协议和硬件设备,将车辆连接到电网。车辆和电网之间的通信可以通过有线或无线方式进行。 3. 车辆识别与认证:车辆连接到电网后,电网会对车辆进行识别和认证,以验证其身份和访问权限。这可以通过电网向车辆发送认证请求,并等待其回应来完成。 4. 选择合适的充电模式:一旦车辆被认证,车主可以选择所需的充电模式。openv2g 支持不同的充电模式,例如普通充电、快速充电、放电和双向能量传输。 5. 通信与交互:openv2g 通过与车辆和电网之间进行通信和交互,共享必要的信息和数据,例如电池状态、充电需求、电网负载等。这些信息用于调整充电过程,以实现最佳的充电效率和电网支持。 6. 充电管理和监控:openv2g 可以对充电过程进行管理和监控,例如控制充电速率、优化充电时间、检测充电的问题等。这有助于确保充电过程的安全性和可靠性。 总的来说,openv2g 是通过车辆和电网之间的双向通信和交互来实现智能充电和电网支持的。它允许车辆和电网之间共享信息和数据,并根据需要调整充电过程,以实现最佳的充电效率和电网支持。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值