之前的一篇博客中提到了,用dlib库Face Landmark Detection自带的人脸检测算法速度慢,准确率低,因此博主将人脸检测算法代替为于老师的人脸检测算法,效果大幅度提升。
博主是在ubuntu16.04 qt5实现的,其实就是前两篇博客中程序的结合。
1、qt编译
(1)配置.pro文件
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
souce.cpp \
libfacedetectcnn-example.cpp \
facedetectcnn-int8data.cpp \
facedetectcnn-floatdata.cpp \
facedetectcnn-model.cpp \
facedetectcnn.cpp
HEADERS += \
facedetectcnn.h
#system
INCLUDEPATH += /usr/local/lib \
/usr/lib/x86_64-linux-gnu
LIBS += -L/usr/local/lib
#opencv 其实在/usr/include就可以不要添加
#INCLUDEPATH += /usr/include \
# /usr/include/opencv \
# /usr/include/opencv2/
LIBS += -L /usr/lib/libopencv_*.so
QMAKE_CXXFLAGS_RELEASE += -O3 # Release -O3
QMAKE_CXXFLAGS_RELEASE += -march=native
#dlib
SOURCES += /home/bjw/git/dlib-master/dlib/all/source.cpp #源码
INCLUDEPATH += /home/bjw/git/dlib-master
LIBS += -L/usr/lib -lpthread -lX11
(2)修改libfacedetectcnn-example.cpp(我是用摄像头测试)
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "facedetectcnn.h"
#include "time.h"
#include <dlib/opencv.h>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
//define the buffer size. Do not change the size!
#define DETECT_BUFFER_SIZE 0x20000
using namespace cv;
using namespace dlib;
using namespace std;
int main(int argc, char* argv[])
{
// Load pose estimation models.
shape_predictor pose_model;
deserialize("/home/bjw/QT_Project/dlib_landmark/dlib_landmark/shape_predictor_68_face_landmarks.dat") >> pose_model;
//usb camera
Mat image;
VideoCapture cam(0);
while(1){
cam >> image;
if(image.empty())
{
fprintf(stderr, "Can not open camera.\n");
return -1;
}
resize(image,image,Size(320,240));
// Turn OpenCV's Mat into something dlib can deal with. Note that this just
// wraps the Mat object, it doesn't copy anything. So cimg is only valid as
// long as temp is valid. Also don't do anything to temp that would cause it
// to reallocate the memory which stores the image as that will make cimg
// contain dangling pointers. This basically means you shouldn't modify temp
// while using cimg.
cv_image<bgr_pixel> cimg(image);
time_t start = clock();
int * pResults = NULL;
//pBuffer is used in the detection functions.
//If you call functions in multiple threads, please create one buffer for each thread!
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
if(!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return -1;
}
///
// CNN face detection
// Best detection rate
//
//!!! The input image must be a RGB one (three-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_cnn(pBuffer, (unsigned char*)(image.ptr(0)), image.cols, image.rows, (int)image.step);
printf("%d faces detected.\n", (pResults ? *pResults : 0));
Mat result_cnn = image.clone();;
//print the detection results
for(int i = 0; i < (pResults ? *pResults : 0); i++)
{
short * p = ((short*)(pResults+1))+142*i;
int x = p[0];
int y = p[1];
int w = p[2];
int h = p[3];
int neighbors = p[4];
int angle = p[5];
printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x,y,w,h,neighbors, angle);
cv::rectangle(result_cnn, Rect(x, y, w, h), Scalar(0, 255, 0), 2);
// Find the pose of each face.
dlib::rectangle face;
std::vector<dlib::rectangle> faces;
std::vector<full_object_detection> shapes;
face.set_left(x);
face.set_top(y);
face.set_right(x+w);
face.set_bottom(y+h);
faces.push_back(face);
for (unsigned long i = 0; i < faces.size(); ++i)
shapes.push_back(pose_model(cimg, faces[i]));
//draw 68 points
if (!shapes.empty()) {
for (int i = 0; i < 68; i++) {
circle(image, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 3, cv::Scalar(0, 0, 255), -1);
}
}
}
time_t end = clock();
//show in the screen
imshow("landmark", image);
imshow("result_cnn", result_cnn);
//release the buffer
free(pBuffer);
//calculate running time
double total_time = (double)(end-start)/CLOCKS_PER_SEC*1000;
cout<<"total_time:"<<total_time<<"ms"<<endl;
waitKey(1);
}
return 0;
}
2、测试