当前位置:网站首页>人脸识别示例代码解析(一)——程序参数解析
人脸识别示例代码解析(一)——程序参数解析
2022-08-09 14:56:00 【LayeZhao】
上一篇我们下载安装了opencv,并且运行了第一个示例程序。接下来,我们剖析下该示例程序。
一、 示例代码来源
上一篇指出,opencv下载并解压后,目录下会产生两个目录

其中,”build”目录主要包含了我们程序开发和运行时所需要的头文件(.h)和库文件(.lib/.dll)。
”source”目录下,包含了项目源码、示例源码、编译相关的数据和文档。
其中”sample”目录中,提供了一定的示例的代码。

我们上一篇所运行的程序示例,就是这个”samples”目录下的facedetect.cpp。
该示例程序用于打开默认摄像头,捕捉图像,定位人脸,以及双眼部位。
二、 修改opencv头文件
*
如果想正常运行该程序,还需要做些修改

如上图所示,源文件中,需要包含一大堆的头文件,在新版的opencv中,只需包含”opencv.hpp”就可以了,原因很简单,这个头文件直接或间接包含了上述所使用到的头文件。
事实上,新版的opencv只提供了这一个头文件,所以几乎所有的opencv开发,都只需包含这一个头文件——“<opencv2/opencv.hpp>”。

注意:第三行加入了一句“#define _CRT_SECURE_NO_WARNINGS”,用于消除一些过期函数的错误提示。否则,会因为一些诸如“fopen”等函数报错而无法通过编译。
三、 使用opencv域名

使用域名很简单,就是如果你不想每次调用opencv相关函数时,都要在前面加上”cv::”,那么就把上述域名使用的声明添加上去。
四、 构造主函数,确定该程序运行时所需要的参数
程序看起来很复杂。实际上就是从程序入口“main”函数,传入一些参数,然后程序根据这些参数,确定“人脸模板”和“眼部模板”的位置,用于定位视频图像中的人脸和眼部。
所以,这个main函数,从一开始,就声明,需要传入的参数。

接下来,在主函数之前声明两个全局变量,字符串类型,用来接收和在函数间传递“人脸模板”路径,“眼部模板”路径。

最后,在主程序内部。解析参数,获取两个变量的值

这里用到一个重要的类,命令行解析
类:cv::CommandLineParser(这里”cv::”可省去)
(一)构造该类对象parser:

需要传递从main中获取的argv,argc,并待后续从中提取各个“参数—值”的键值对。
需要传递参数列表及其默认值。参数列表决定了,我们从argv中需要包含哪些参数信息(比如该程序需要参数“help”,“cascade”,“nested-cascade”,“scale)。
另外在argv中解析不到相应参数时(比如用户没有输入’cascade”参数值)时,默认参数值(比如“data/haarcascades/haarcascade_frontalface_alt.xml”)来代替。
(二)利用parser对象解析参数
- 在解析参数之前,我们应首先判断一下用户是否是需要调用帮助文档,如果是,那么并不真正执行程序,而是显示帮助文档内容,因此并不需要再往下解析参数

- parser对象的get函数,传入参数名,返回参数值。

- 继续解析,利用parser的check函数检查有无丢失参数等错误。

五、最后今天就解析这里,在此可以把本篇代码简化为以下
编译后,在命令行中运行该程序,可以检测参数的输入与解析
// face1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
string cascadeName;
string nestedCascadeName;
int main(int argc, const char** argv)
{
string inputName;
bool tryflip;
double scale;
CommandLineParser parser(argc, argv,
"{help h||}"
"{cascade|data/haarcascades/haarcascade_frontalface_alt.xml|}"
"{nested-cascade|data/haarcascades/smile.xml|}"
"{scale|1|}{try-flip||}{@filename||}"
);
if (parser.has("help"))
{
return 0;
}
cascadeName = parser.get<string>("cascade");
nestedCascadeName = parser.get<string>("nested-cascade");
scale = parser.get<double>("scale");
if (scale < 1)
scale = 1;
tryflip = parser.has("try-flip");
inputName = parser.get<string>("@filename");
if (!parser.check())
{
parser.printErrors();
return 0;
}
cout << "该程序接收参数如下:" << endl;
cout << "cascadeName:" << cascadeName << endl;
cout << "nestedCascadeName:" << nestedCascadeName << endl;
cout << "scale:" << scale << endl;
cout << "tryflip:" << tryflip << endl;
cout << "inputName:" << inputName << endl;
return 0;
}
没有输入参数情况下

用户指定inputName情况下

六:练习,大家可以修改此代码,试图在用户输入参数“-h”时显示帮助文档。
边栏推荐
猜你喜欢

More than pytorch from zero to build neural network to realize classification (training data sets)

At the beginning of the C language order 】 【 o least common multiple of three methods

ASP.Net Core实战——身份认证(JWT鉴权)

【研究生工作周报】(第十周)

WebGL:BabylonJS入门——初探:我的世界
深刻地认识到,编译器会导致编译结果的不同

【小白必看】初始C语言(上)

(12)Cookie和Session

九、【Vue-Router】缓存路由组件 keep-alive标签

stream去重相同属性对象
随机推荐
关于初级程序员职场如何提升技能的几点建议?
微信小程序tabs
【小白必看】初始C语言(下)
模仿微信金钱输入框规则(修复7.0手机崩溃)
GoogLeNet
C语言运算符优先级
抱抱脸(hugging face)教程-中文翻译-文本分类
PHP开源 | ysKit(ys工具包) - 微型Web框架
封装仿支付宝密码输入效果
C写菜单指令的快捷方法
Qt对话框中show和exec的区别
Simply record offsetof and container_of
Example of file operations - downloading and merging streaming video files
深度神经网络中的多任务学习研究综述
The difference between show and exec in Qt dialog
浏览器中的302你真的知道吗
More than pytorch from zero to build neural network to realize classification (training data sets)
抱抱脸(hugging face)教程-中文翻译-分享一个模型
YOLOV1详解
抱抱脸(hugging face)教程-中文翻译-预处理