68特征点模型下载:
https://download.csdn.net/download/weixin_44152895/12025691
caffe模型和deploy.prototxt下载:
https://download.csdn.net/download/weixin_44152895/12272530
交叉编译opencv和dlib.注意dlib的lib路径最好在/usr/local不然会找不到。
树莓派读取usb摄像头用cap(1),读取排线摄像头是cap(0),(我的排线摄像头用不了,出现错误:如下:)
VIDIOC_DQBUF: Resource temporarily unavailable
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(3.4.5) /usr/local/arm/opencv-3.4.5/modules/imgproc/src/color.cpp:
181: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'
目前原因在查找,所以先用usb摄像头。下面是dlib和opencv的结合。
#include
#include
#include
#include
#include
#include
#include
using namespace dlib;
using namespace std;
int main() {
cv::VideoCapture cap(1); //范围解析运算符,定义类成员。
if (!cap.isOpened()) {
cout << "连接不上摄像头" << endl;
return 1;
}
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pos_modle; //将文件中的模型放置再pos_modle中
deserialize("shape_predictor_68_face_landmarks.dat") >> pos_modle;
for(;;)
{
cv::Mat temp,gray_img; //将摄像头获取的当前帧图片放入到中间文件中
cap >> temp;
//cv_image cimg(temp); //将其转化为RGB像素图片
cv::cvtColor(temp,gray_img,cv::COLOR_BGR2GRAY);
dlib::cv_image cimg(gray_img);
std::vector faces = detector(cimg); //开始进行脸部识别
//std::vector就是数组容器类,尖括号表示里面的是实际类,整体定义了faces对象是一个RECT数组。
std::vector shapes; //发现每一个脸的pos估计
unsigned faceNumber=faces.size(); //将所有脸的区域放入集合之中
for (unsigned i = 0; i < faceNumber; i++)
shapes.push_back(pos_modle(cimg, faces[i])); //第i个人的关键点。
if (!shapes.empty()) {
int faceNumber = shapes.size();
for (int j = 0; j < faceNumber; j++)
{
for (int i = 0; i < 68; i++)
{
cv::circle(temp, cvPoint(shapes[j].part(i).x(), shapes[j].part(i).y()), 1, cv::Scalar(0, 0, 255), -1);
if (shapes[0].part(66).y()-shapes[0].part(62).y()>20 || shapes[0].part(40).y()-shapes[0].part(38).y()<4 || shapes[0].part(46).y()-shapes[0].part(44).y()<4)
{
cv::putText(temp,"be careful", cvPoint(100, 100), CV_FONT_HERSHEY_PLAIN,4, cv::Scalar(255, 0, 255),2);
}
imwrite("dlib.jpg", temp);
}
}
}
}
}
下面是caffe和dlib和opencv的结合:
#include
#include
#include
#include
#include
#include
#include "time.h"
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace cv::dnn;
using namespace std;
using namespace dlib;
const size_t inWidth = 300;
const size_t inHeight = 300;
const double inScaleFactor = 1.0; //缩放比例
const Scalar meanVal(104.0, 177.0, 123.0); //均值
int main( )
{
float min_confidence = 0.5;
String modelConfiguration = "deploy.prototxt";
String modelBinary = "res10_300x300_ssd_iter_140000.caffemodel";
dnn::Net net = readNetFromCaffe(modelConfiguration, modelBinary);
shape_predictor pos_modle;
deserialize("shape_predictor_68_face_landmarks.dat") >> pos_modle;
VideoCapture cap(1);
for (;;)
{
Mat frame;
cap >> frame;
Mat inputBlob = blobFromImage(frame, inScaleFactor,
Size(inWidth, inHeight), meanVal, false, false);
net.setInput(inputBlob, "data");
Mat detection = net.forward("detection_out");
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr());
float confidenceThreshold = min_confidence;
for (int i = 0; i < detectionMat.rows; i++)
{
//分类精度
float confidence = detectionMat.at(i, 2);
if (confidence > confidenceThreshold)
{ //左下 右上
int xLeftBottom = static_cast(detectionMat.at(i, 3) * frame.cols);
int yLeftBottom = static_cast(detectionMat.at(i, 4) * frame.rows);
int xRightTop = static_cast(detectionMat.at(i, 5) * frame.cols);
int yRightTop = static_cast(detectionMat.at(i, 6) * frame.rows);
cv::Rect object((int)xLeftBottom, (int)yLeftBottom, (int)(xRightTop - xLeftBottom),
(int)(yRightTop - yLeftBottom));
cv::rectangle(frame, object, Scalar(0, 255, 0),8);
dlib::rectangle dlibRect((int)xLeftBottom, (int)yLeftBottom, (int)(xRightTop - xLeftBottom),
(int)(yRightTop - yLeftBottom));
cv::cvtColor(frame,frame,cv::COLOR_BGR2GRAY);
//dlib::cv_image cimg(frame);
dlib::full_object_detection shape = pos_modle(dlib::cv_image(frame), dlibRect);
//std::vector faces = detector(frame);
std::vector shapes;
shapes.push_back(shape);
if (!shapes.empty())
{
int faceNumber = shapes.size();
for (int j = 0; j < faceNumber; j++)
{
for (int i = 0; i < 68; i++)
{
cv::circle(frame, cvPoint(shapes[j].part(i).x(), shapes[j].part(i).y()), 1, cv::Scalar(0, 0, 255), -1);
//cv::putText(temp,to_string(i), cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), CV_FONT_HERSHEY_PLAIN,1, cv::Scalar(0, 0, 255));
//cout << shapes[0].part(38).y() <<" "<< shapes[0].part(40).y()<
编译代码:
arm-linux-gnueabihf-g++ -o face1 facelandmark.cpp `pkg-config --cflags --libs opencv` -I.. /usr/local/arm/dlib/dlib/all/source.cpp -lpthread -DDLIB_NO_GUI_SUPPORT=1 -std=c++11