OpenCV+百度云人脸识别项目及源码
1、需要的硬件环境
- 虚拟机
- 带有摄像头的电脑
2、整体项目的框架
用Opencv识别人脸,上传百度云进行识别对比
3、虚拟机上需要装的库
sudo apt-get install libopencv-dev,验证是否安装完成dpkg -s libopencv-dev
Opencv官方文挡:https://opencv.org/
百度云SDK中需要的依赖库也装在虚拟机上:(百度云的SDK去官网下载即可,版本:aip-cpp-sdk-0.8.1)
sudo apt-get install libcurl4-openssl-dev,验证安装是否成功dpkg -s libcurl4-openssl-dev
sudo apt-get install openssl,验证安装是否成功dpkg -s openssl
sudo apt-get install libjsoncpp-dev,验证是否安装成功 dpkg -s libjsoncpp-dev 版本>1.7.2
sudo apt-get install libssl-dev,验证是否安装成功 dpkg -s libssl-dev
4、百度云中的环境搭建
https://cloud.baidu.com/product/face/search 百度智能云 人脸识别(人脸搜索)
立即使用 https://login.bce.baidu.com/?account=&redirect=http%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F#/ai/face/overview/index
注册一个账号 或者扫码登录 登陆成功 我同意
创建应用—名称自己起名字----接口选择(默认人脸)—应用归属(个人)–应用描述(随便写就行)
点击查看人脸库—新建组(名字自己起)–点击自己的名字–新建用户-用户id(名字-拼音)–添加图片(清晰的)
上传完之后确认—添加其他的人脸一样操作—完成
5、开始敲代码
注:代码文件要放在百度云SDK文件下
#include <iostream> #include "opencv2/opencv.hpp" #include "face.h" using namespace std; //命名空间,目的是,用不同的库的话,担心相同的库函数发生冲入,用于区分 using namespace cv; //opencv命名空间 using namespace aip; // sdk 方法 int main() { VideoCapture cap(0); // //初始化摄像头 if(!cap.isOpened()) // 打开摄像头 { cout << "Camera open failed" << endl; return -1; // return 0; 0和1是差不多的,就是一个是正常退出和异常退出//打不开摄像头就推出程序 } cout << "Camera open success" << endl; CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml")//传递一个人脸思维 有需要可以传递眼睛 鼻子 耳朵等 /*** 前三句是建了三个容器 第四句是将自己的容器加进去 建立关系 std::string app_id = "24694935"; //你的 App ID std::string api_key = "cwyOatQmgGGTCeXUd5x7Khv5"; //你的 Api key std::string secret_key = "ROkT0Z7UE0PBSCMM3co2hyAMctrORNAe"; //你的 Secret Key aip::Face client(app_id, api_key, secret_key);***/ aip::Face client("24694935", "cwyOatQmgGGTCeXUd5x7Khv5", "ROkT0Z7UE0PBSCMM3co2hyAMctrORNAe");//也可以这样写,用于与百度云建立连接 Mat paizhao; //存容器 将拍下来的彩色照片存起来 Mat cuntu; //存转换完的灰度的图像 vector<Rect> AllFace;//存放识别出的人脸 Mat MatFace; //存放识别框中截取出的人脸 vector<uchar> jpgFace;//存放JPG格式的截取出来的人脸图片 string Base64Face; // 存储 BASE64格式的照片 Json::Value result; // 百度返回的数据 存到了 result time_t sec;//类似的定义了一个时间 for(;;) { cap >> paizhao; // 拍照片 存到彩色照片容器里 cvtColor(paizhao, cuntu, CV_BGR2GRAY); //真彩转换成灰度 ,增加识别率 equalizeHist(cuntu,cuntu); //均衡化处理 可以想象成虚化背景凸显人脸,增加识别率 Classifier.detectMultiScale(cuntu,AllFace); //将所有人脸用矩形框起来 if(AllFace.size()) //检测是否有脸 { rectangle(cuntu,AllFace[0], Scalar(255,255,255));//在灰度照片上画一个矩形,画的就是AlLFace的第一张脸,框的颜色是后面的RGB的调出来的白色。 MatFace = cuntu(AllFace[0]); //将灰度图 截图存放到截图容器中 imencode(".jpg",MatFace,jpgFace);//转换成JPG格式,用于将图片上传到百度云,用于通过网络发送过去 Base64Face = base64_encode((char *)jpgFace.data(),jpgFace.size()); 将图片转换成Base64格式 result = client.search(Base64Face, "BASE64", "ha", aip::null);//将Base64格式的人脸发送过去 #if 1//一下这部分是将识别的人名和时间打印在图片流上 cout << result << endl; #else if( !result["result"].isNull() ) //判断有没有脸 没有人脸不打印 { if(result["result"]["user_list"][0]["score"].asInt() > 80) //判断我的这张脸高不高于80分 { cout << result["result"]["user_list"][0]["user_id"] << endl; //如果高于80分就只把名字打印出来到 sec = time(NULL); //这种时间是一串数字,这串数字的意义是距离1970一月一号零点零分零秒的秒数 cout << ctime(&sec) << endl;//将这串数字转换成人们熟悉的年月日的形式输出到LOG putText(cuntu, result["result"]["user_list"][0]["user_id"].asString(), Point(0,50), FONT_HERSHEY_SIMPLEX,1, Scalar(255,255,255));//将识别的人名发送到显示的图片上 putText(cuntu, ctime(&sec), Point(0,100), FONT_HERSHEY_SIMPLEX,1, Scalar(255,255,255));//将识别的时间发送到显示的图片上 } } #endif } imshow("video",cuntu); //显示照片 waitKey(40); //等待 40毫秒 1000/24=41.666人眼识别的是一秒内看到连续的24张图片就认为是视频了 } return 0; }
6、一切就绪,准备编译
g++ main.cpp -o main -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_objdetect -std=c++11 -lcurl -lcrypto -ljsoncpp
7、运行
./main >> log.txt
8、可能会遇到的一些问题及对应解决办法
摄像头打不开:cd /dev/ 查看有没有摄像头 没有的话进行以下操作
(1)虚拟机–设置—usb控制器—兼容性改成3.0或者3.1
(2) 虚拟机–可移动设备—Micro— 重新找/dev/下有没有video,或者右下角建一个小的摄像头
OpenCV有训练好的思维逻辑,无需我们自己训练,
cd /usr/share/opencv/haarcascades/ 里面有训练好的东西,
haarcascade_frontalface_alt2.xml 这个是训练人脸的