草庐IT

C++实现人脸识别(百度云平台)

徐先生没洗头 2023-05-25 原文

C++实现人脸识别(百度云平台)

项目资源下载

项目思路:opencv 采集人脸照片,将照片发送至百度智能云平台,百度云平台与人脸库中的数据进行比较并返回结果。

一、项目环境

  1. Ubuntu 64 20.0.4

  2. opencv 4.2.0

二、环境配置

1、安装 opencv

sudo apt-get install libopencv-dev

安装需要等待一段时间,有些系统可能要安装依赖,按照提示安装即可。

安装完成后可使用命令

dpkg -s libopencv-dev

查看安装的状态与版本。不同的系统版本有差别,我这里是 opencv4.2.0,具体版本和使用的软件源有关。

安装完成后可先测试。

/*
test.cpp
*/

#include<iostream>
#include "opencv4/opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main()
{
	// 打开默认摄像头0
	VideoCapture cap = 0;
	// 如果摄像头开启出现异常,则退出程序
	if(!cap.isOpened())
	{
		cout << "Camera open failed!" << endl;
		return -1;
	}
	cout << "Camera open success!" << endl;

	// 实例化人脸级联分类器
	cv::CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml");

	// 照片容器容器 Mat为 cv 内定义类型
	Mat ColorFace; // 用于展示,彩色展示效果较好
	Mat GrayFace;  // 用于查找人脸,灰色查找降低计算量
    
	// 人脸列表 Rect类型,为人脸的矩形框坐标
	vector<Rect> AllFace;

	// 存储从图片中截取的人脸
	Mat MatFace;

	// 存储截图
	vector<uchar> JpgFace;
	
    // 循环采集图片并展示,达到视频效果
	while(true)
	{
        // 拍照
		cap >> ColorFace;

		// 将彩色照片转为灰度,降低计算量
		cvtColor(ColorFace, GrayFace,cv::COLOR_BGR2GRAY);

		// 将灰度照片均衡化,便于从背景中分离人脸
		equalizeHist(GrayFace, GrayFace);

		// 从灰度照片中检测人脸,并将检测到的人脸存入人脸列表中
		Classifier.detectMultiScale(GrayFace, AllFace);
       
        // 判断是否检测到人脸,没有人脸则列表为空
		if(AllFace.size()==0){
			cout << "no face" << endl;
		}else{
			// 框出检测到的人脸,第一个参数为要框出的图片,第二个参数为人脸,最后一个是框的颜色
			rectangle(ColorFace, AllFace[0], Scalar(255, 255, 0));
		}
		
        // 显示图片,第一个参数为窗口名称,第二个为展示的图片
		imshow("test", ColorFace);
		
        // 等待40ms,相当于25帧(24帧是人眼连贯的最小帧率)
		waitKey(40);
	}

	return 0;
}

执行编译命令

g++ test.cpp -o test

这时我们会发现其报错了,报错如下

出现这种情况是因为我们的项目中引入了opencv4/opencv2/opencv.hpp这个库,但没有对其进行编译。

解决办法如下:

① 编译时动态链接用到的库

g++ test.cpp -o test -lopencv_highgui

很可惜,我使用这种方法并没有成功,又查阅了很多资料,发现是 .so 文件没能正确链接,也就是环境变量问题,所以有了第二种解决办法。

其次,这第一种方法每次使用新的 opencv 下的函数都需要增加 -l 的动态链接编译,过于繁琐,导致编译命令过于复杂,第二种方法也解决了这个问题。

②环境变量配置
链接: 参考文章

执行如下语句

pkg-config --cflags opencv

返回如下结果

Package opencv was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv' found

其原因是缺少 opencv.pc文件,我们需要创建这个文件并将其导入环境变量中,具体操作如下:

首先创建 opencv.pc文件,注意目录信息

cd /usr/local/lib
sudo mkdir pkgconfig
cd pkgconfig
sudo touch opencv.pc

然后在文件中添加如下内容

sudo nano opencv.pc
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib

Name: opencv
Description: The opencv library
Version:4.0.1
Cflags: -I${includedir}/opencv4
Libs: -L${libdir} -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann  -lopencv_core
~                                               

这里面主要是opencv的配置信息,我们可以看到Libs里有我们会用到的所有链接库。

保存并推出文件编辑:ctrl+ o ctrl + x.

将文件导入环境变量

export  PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

这就配置好 opencv 的环境变量了。

再次执行命令

pkg-config --cflags --libs opencv

返回结果如下,即配置成功

-I/usr/local/include/opencv4 -L/usr/local/lib \
-lopencv_shape -lopencv_stitching -lopencv_objdetect \
-lopencv_superres -lopencv_videostab -lopencv_calib3d \
-lopencv_features2d -lopencv_highgui -lopencv_videoio \
-lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml \
-lopencv_imgproc -lopencv_flann -lopencv_core

返回到项目文件夹,执行如下命令编译

sudo g++ test.cpp -o test `pkg-config --cflags --libs opencv`

执行 ls-l 发现已经生成了可执行文件 test

运行示例:

./test

发现又又又报错啦!!!

不用担心,这是因为我们的虚拟机没有连接到摄像头导致的,我们只需要按照如下步骤操作即可。

点开 虚拟机 --> 可移动设备 --> IMC Networks Integrated Camera --> 连接(断开与 主机 的连接) 即可。

再次执行 ./test

可以看到程序成功运行,在终端按下 ctrl+c 即可结束程序。

2、百度云平台配置

首先要到百度智能云平台创建一个人脸搜索的应用,百度云平台具体的使用方法可以去看百度的教程,非常简单。

①登录百度智能云
链接: 百度智能云平台

②找到人脸识别云服务

进入之后点击立即使用

③创建应用

创建成功后,进入管理应用

点击查看人脸库,新建用户分组

新建用户并上传照片即可,注意上传的用户照片要面部轮廓与五官清晰的正面照。

至此,我们在百度智能云上的人脸库就创建成功啦。

3、配置SDK

为了能够应用百度智能云,我们还需要下载相应的SDK配置本地环境。
链接: C++ SDK文档
链接: C++ SDK下载地址

因为我们的项目是在乌班图中运行,所以建议直接在乌班图内下载。

下载完成后解压到我们的项目文件中

进入项目目录,执行如下命令

cd aip-cpp-sdk-0.8.1
sudo mv * ../

SDK已经导入项目啦,还需要安装一些依赖包,参考上面的SDK文档。

以上就是我们需要下载安装的依赖包,执行如下命令

sudo apt-get install libcurl4-openssl-dev
sudo apt-get install openssl
sudo apt-get install libjsoncpp-dev

因为项目引入了这些库,且这些库是C++11标准,所以在编译时要在末尾添加如下链接

-lcurl -lcrypto -ljsoncpp  -std=c++11

全部安装好后,我们的项目环境就配置好啦。

但我们还有一些地方需要更改。

进入之前解压出来的 base 文件夹,打开 http.h,将 23 行的 #include <json/json.h> 更改为#include <jsoncpp/json/json.h>

同样 base.h 的 21 行也应作出相同的更改。

三、编码

下面就是完整的代码,备注详细。

#include<iostream>
#include "opencv4/opencv2/opencv.hpp"
#include "face.h"

using namespace std;
using namespace cv;
using namespace aip;

int main()
{
	// Json容器,用于存储云端发送回来的数据
	Json::Value result;

	// 打开默认摄像头0
	VideoCapture cap = 0;
	// 如果摄像头开启出现异常,则退出程序
	if(!cap.isOpened())
	{
		cout << "Camera open failed!" << endl;
		return -1;
	}
	cout << "Camera open success!" << endl;

	// 实例化人脸级联分类器
	cv::CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml");

	// 照片容器容器 Mat为 cv 内定义类型
	Mat ColorFace;
	Mat GrayFace;
    
	// 人脸列表 Rect类型,为人脸的矩形框坐标
	vector<Rect> AllFace;

	// 存储从图片中截取的人脸
	Mat MatFace;

	// 存储截图
	vector<uchar> JpgFace;

	// 连接百度智能云
	std::string app_id = "更换为你的 app_id";
	std::string api_key = "更换为你的 api_key";
	std::string secret_key = "更换为你的 secret_key";
    // 创建人脸识别云服务客户端
	aip::Face client(app_id, api_key, secret_key);

	// 因为百度智能云要求发送的人脸为 Base64 格式,所以声明一个 string 类型的容器存储它
	string Base64Face;

	// 循环采集图片并展示,达到视频效果
	while(true)
	{
        // 拍照
		cap >> ColorFace;

		// 将照片转化为灰度格式,降低计算量
		cvtColor(ColorFace, GrayFace,cv::COLOR_BGR2GRAY);

		// 将灰度照片均衡化,便于从背景中分离人脸
		equalizeHist(GrayFace, GrayFace);

		// 从灰度照片中检测人脸,并将检测到的人脸存入人脸列表中
		Classifier.detectMultiScale(GrayFace, AllFace);
		
        // 判断是否检测到人脸
		if(AllFace.size()==0){
			cout << "no face" << endl;
		}else{
			// 截取检测到的第一张人脸
			MatFace = GrayFace(AllFace[0]);
			// 将截取的无格式人脸转为 .jpg 格式
			imencode(".jpg", MatFace, JpgFace);
			// 将图片转为 Base64 格式
			Base64Face = base64_encode((char *)JpgFace.data(), JpgFace.size());
			// 从人脸库中搜索人脸
			result = client.search(Base64Face, "BASE64", "test1", aip::null);
			// 解析返回结果
			if(!result["result"].isNull()){
				// 当返回结果也检测到人脸时,将彩色照片中的人脸框起来
                rectangle(ColorFace, AllFace[0], Scalar(255, 255, 0));
				// 判断人脸相似度,当相似度大于80%,判定为同一人,输出其编号(人脸库中的编号),否则输出 unknown people
				if(result["result"]["user_list"][0]["score"].asInt() >= 80){
					cout << "find " << result["result"]["user_list"][0]["user_id"] << endl;
				}else{
					cout<< "unkown people" << endl;
				}
			}else{
				cout << "no face" << endl;
			}
		}
		// 展示图片
		imshow("test", ColorFace);

		waitKey(40);
	}

	return 0;
}

使用如下命令编译

sudo g++ test.cpp -o test `pkg-config --cflags --libs opencv` -lcurl -lcrypto -ljsoncpp  -std=c++11

运行

./test

运行结果

有关C++实现人脸识别(百度云平台)的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  3. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  4. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  5. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  6. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  7. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  8. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  9. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

  10. ruby-on-rails - 没有这样的文件或目录 - 用 Mini Magick 识别 - 2

    在我让另一个人重做我的前端UI之前,我的Rails应用程序运行平稳。我已经尝试解决此错误3天了。这是错误:Nosuchfileordirectory-identifyExtractedsource(aroundline#59):575859606162@post=Post.find(params[:id])authorize@postif@post.update_attributes(post_params)flash[:notice]="Postwasupdated."redirect_to[@topic,@post]else{"utf8"=>"✓","_method"=>"patc

随机推荐