一.项目框架
基于OpenCV和百度云人脸识别的项目可以使用以下的框架来实现:
-
数据采集和预处理:使用OpenCV来采集摄像头或读取图像文件,并对图像进行预处理操作,例如裁剪、调整大小、灰度化等。
-
人脸检测:使用OpenCV的人脸检测功能来检测图像中的人脸。可以使用预训练的人脸检测器,如Haar Cascade或基于深度学习的人脸检测器。
-
百度云人脸识别API调用:将图像中检测到的人脸传递给百度云人脸识别API,进行人脸识别或分析。调用API需要使用密钥,包括API Key和Secret Key。
-
人脸比对和识别:使用百度云人脸识别API进行人脸比对,将待识别人脸与已知人脸进行对比,以确定是否匹配。您可以保存一些已知人脸的特征向量,将待识别的人脸与这些特征进行比较。
-
结果展示和应用:根据项目需求,将识别结果展示在界面上或进行相应的处理,例如门禁系统的控制、人脸识别支付等。
在这个框架中,OpenCV用于图像处理和人脸检测,百度云人脸识别API提供了人脸识别和分析的功能。根据项目的实际需求,您可以在这个基本框架上进行适当的扩展和优化。
二.下载Opencv库以及API
- 在线安装:sudo apt-get install libopencv-dev
- 在线文档:https://opencv.org/
1.VideoCapture 类
VideoCapture
是OpenCV中的一个类,用于读取图像或视频数据流。它可以读取来自摄像头、视频文件以及其他设备的输入流。
通过创建一个VideoCapture
对象,并传入特定的参数(例如摄像头设备或视频文件路径),可以打开并读取相应的图像或视频流。例如:
VideoCapture cap(0); // 打开默认的摄像头设备
if (!cap.isOpened()) {
// 处理无法打开摄像头的情况
}
Mat frame;
cap.read(frame); // 读取一帧视频数据
在上面的代码中,我们首先创建了一个VideoCapture
对象,并传入参数0
表示打开默认的摄像头。然后,我们使用cap.isOpened()
方法来检查摄像头是否被成功打开,如果不成功,则需要进行相应的错误处理。最后,我们使用cap.read(frame)
来读取摄像头的一帧数据,并将其存储在Mat
对象frame
中,以便进行后续的图像处理和人脸识别等操作。
VideoCapture
类还提供了其他一些方法和属性,例如set()
和get()
方法用于设置和获取视频流中的参数,如分辨率、帧率等等。您可以根据自己的需求进行进一步的探索和学习。
2.cvtColor函数
cvtColor
是OpenCV中的一个重要函数,用于在不同的色彩空间之间进行颜色转换。例如,您可以使用cvtColor
将一张RGB图像转换为灰度图像,在HSV、Lab等色彩空间中进行颜色分析等等。
cvtColor
函数的通用语法为:
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0);
其中,参数src
和dst
分别表示输入和输出的图像,类型为InputArray
和OutputArray
,它们可以是Mat
对象、图像数据的指针等。code
参数表示颜色转换的类型,通常是使用预定义的常量来表示转换方式,例如将RGB图像转换为灰度图像时,可以使用常量COLOR_RGB2GRAY
。dstCn
参数表示输出图像的通道数,当输出图像和输入图像通道数不一致时,需要进行通道数的补充或减少。
以下是一些常用的code
常量和对应的颜色转换类型:
- COLOR_BGR2GRAY:将BGR颜色图像转换为灰度图像
- COLOR_RGB2GRAY:将RGB颜色图像转换为灰度图像
- COLOR_GRAY2BGR:将灰度图像转换为BGR颜色图像
- COLOR_BGR2HSV:将BGR图像转换为HSV颜色空间中的图像
- COLOR_HSV2BGR:将HSV图像转换为BGR颜色空间中的图像
- COLOR_BGR2Lab:将BGR图像转换为Lab颜色空间中的图像
- COLOR_Lab2BGR:将Lab图像转换为BGR颜色空间中的图像
对于转换的输出图像,可以直接创建一个Mat
对象,然后将其传递给cvtColor
函数。例如,将一张BGR图像转换为灰度图像可以使用以下代码:
Mat input_image = imread("input.jpg");
Mat gray_image;
cvtColor(input_image, gray_image, COLOR_BGR2GRAY);
在上面的代码中,我们首先使用imread
函数读取一张BGR图像,并将其存储在input_image
对象中。然后,我们创建一个名为gray_image
的Mat
对象用于存储转换后的灰度图像。最后,我们使用cvtColor
函数将输入图像转换为灰度图像,并将结果存储在gray_image
对象中。
3.equalizeHist函数
equalizeHist
是OpenCV库中的一个直方图均衡化函数,用于提高图像的对比度和亮度分布。该函数可以应用于灰度图像或彩色图像的每个通道。
直方图均衡化可以通过拉伸图像灰度级的像素值来增强图像的对比度。它会尽量使得图像的像素值均匀分布在整个灰度范围内,从而提高图像细节的可见性。
函数的通用语法如下:
void equalizeHist(InputArray src, OutputArray dst);
其中,src
是输入图像,可以是灰度图像或彩色图像,dst
是输出图像,经过直方图均衡化后的结果。
以下是一个使用equalizeHist
函数的示例:
Mat inputImage = imread("input.jpg", 0); // 读取灰度图像
Mat equalizedImage;
equalizeHist(inputImage, equalizedImage);
在示例中,我们首先使用imread
函数读取了一张灰度图像,并将其存储在inputImage
对象中。然后,我们创建一个名为equalizedImage
的Mat
对象用于存储直方图均衡化后的结果。最后,我们使用equalizeHist
函数将输入图像进行直方图均衡化,并将结果存储在equalizedImage
对象中。
需要注意的是,equalizeHist
函数只适用于灰度图像的直方图均衡化。如果要对彩色图像进行直方图均衡化,需要将彩色图像转换为HSV或Lab等颜色空间,然后对亮度通道进行直方图均衡化,最后再将图像转换回原始颜色空间。
更多函数接口请查询官方API文档。
3.百度云配置及SDK的下载
领取免费权益
领取成功后返回上一个界面
填写完各种信息后创建
创建人脸库
为了节约时间,小编已经将SDK包下载好打包,放在这里了。SDK的使用方法请到官网自行查询。
四·opencv程序编写
#include <iostream>
#include "opencv2/opencv.hpp"
#include <vector>
#include "face.h"
#include <thread> // std::thread
#include <unistd.h>
using namespace std;
using namespace cv;
using namespace aip;
Mat ColorImage, GrayImage;
//g++ face_check.cpp -o face_check -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_objdetect -std=c++11 -lcurl -lcrypto -ljsoncpp
int main(int, char **)
{
https://opencv.org/ //0代表打开编号0的摄像头
if (!cap.isOpe
{
cout << "Camera open failed" << endl;
return -1;
}
cout << "Caeera open success" << endl;
CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml"); //实例化(寻找多个人脸)
aip::Face client("40842479", "A71uFjITCpky0GKp4BUBwBXF", "VkovTGi97Rh6xSMcd8gjHWYXENRY6vdA"); //也可以这样写,用于与百度云建立连接
vector<Rect> AllFace; //成放图片的容器实例化
Mat MatFace; //成放人脸的容器
vector<uchar> JpgFace;
string Base64Face; // 存储 BASE64格式的照片
Json::Value result; // 百度返回的数据 存到了 result
Json::Value options;
time_t sec; //类似的定义了一个时间
int len = 0;
while (1)
{
cap >> ColorImage; //从摄像头获得一个图片
cvtColor(ColorImage, GrayImage, COLOR_BGRA2GRAY); //转换成灰度图
equalizeHist(GrayImage, GrayImage); //均衡化处理
Classifier.detectMultiScale(GrayImage, AllFace); //检测图片人脸,保存到容器中(坐标)
cout << AllFace.size() << endl;
if (AllFace.size())
{
MatFace = GrayImage(AllFace[0]); //将识别的人脸插入到数组中
imencode(".jpg", GrayImage, JpgFace); //将图片转换成jpg格式
Base64Face = base64_encode((char *)JpgFace.data(), JpgFace.size()); //将图片转换成Base64格式
result = client.search(Base64Face, "BASE64", "gongren", aip::null); //将Base64格式的人脸发送过去
if (!result["result"].isNull())
{
if (result["result"]["user_list"][0]["score"].asInt() > 80)
{
cout << result["result"]["user_list"][0]["user_id"] << endl;
sec = time(NULL);
cout << ctime(&sec) << endl;
putText(ColorImage, result["result"]["user_list"][0]["user_id"].asString(), Point(0, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 0));
rectangle(ColorImage, AllFace[0], Scalar(255, 255, 0)); //画长方体
}
}
}
imshow("video", ColorImage); //显示照片
waitKey(40);
}
return 0;
}
改文件调用了SDK中的函数,请注意头文件要加上SDK,我这里将改文件移动到了SDK文件中。