dlib是一个开源的C++机器学习库,它提供了一系列用于图像处理、人脸检测、人脸识别、物体检测、图像标注等功能的算法和工具。dlib库使用了现代C++和模板元编程的技术,并且具有高度的可移植性和可扩展性。
dlib库的主要特点包括:
dlib库在计算机视觉、模式识别和机器学习领域被广泛应用,是一个功能强大且易用的机器学习库。对外提供了C++和python两种接口。
#define DLIB__CMAKE_GENERATED_A_CONFIG_H_FILE
cmake -G "Visual Studio 14 2015" ..
cmake --build ./ --config Release
cmake -G "Visual Studio 14 2015" ..
cmake --build ./ --config Release
facec
├── dlib-19.24
│ └── dlib
├── opencv-4.5.0
│ ├── include
│ └── modules
├── lib
├── src
│ └── main.cpp
└──CMakeLists.txt
cmake -G "Visual Studio 14 2015" ..
cmake --build ./ --config Release
#include
#include
#include
#include
#include
#include
#include
using namespace dlib;
using namespace std;
int main()
{
try
{
// 打开摄像头
cv::VideoCapture cap(0, cv::CAP_DSHOW);
if (!cap.isOpened())
{
printf("open VideoCapture failed.\n");
return 1;
}
printf("open VideoCapture success.\n");
image_window win;
// Load face detection and pose estimation models.
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
static int mouthIndex = 0;
static int leyeIndex = 0;
static int reyeIndex = 0;
int counter_mouth = 0;
int counter_leye = 0;
int counter_reye = 0;
// Grab and process frames until the main window is closed by the user.
while(!win.is_closed())
{
// Grab a frame
cv::Mat frame;
if (!cap.read(frame))
{
break;
}
cv_image<bgr_pixel> cimg(frame);
// 保存图片
cv::Mat imgPng = dlib::toMat(cimg);
cv::imwrite("face.png", imgPng);
// Detect faces
std::vector<rectangle> faces = detector(cimg);
// Find the pose of each face.
std::vector<full_object_detection> shapes;
printf("faces number is %d\n", faces.size());
for (unsigned long i = 0; i < faces.size(); ++i) {
shapes.push_back(pose_model(cimg, faces[i]));
//计算人眼纵横比
//左眼
dlib::point leyeLeft = shapes.at(i).part(37);
dlib::point leyeRight = shapes.at(i).part(40);
dlib::point leyeLeftUp = shapes.at(i).part(38);
dlib::point leyeLeftDowm = shapes.at(i).part(42);
dlib::point leyeRightUp = shapes.at(i).part(39);
dlib::point leyeRightDowm = shapes.at(i).part(41);
float leyeA = sqrt(pow(leyeLeftUp.x() - leyeLeftDowm.x(), 2) + pow(leyeLeftUp.y() - leyeLeftDowm.y(), 2));
float leyeB = sqrt(pow(leyeRightUp.x() - leyeRightDowm.x(), 2) + pow(leyeRightUp.y() - leyeRightDowm.y(), 2));
float leyeC = sqrt(pow(leyeLeft.x() - leyeRight.x(), 2) + pow(leyeLeft.y() - leyeRight.y(), 2));
float leyeEVR = (leyeA + leyeB) / (2 * leyeC);
//右眼
dlib::point reyeLeft = shapes.at(i).part(43);
dlib::point reyeRight = shapes.at(i).part(46);
dlib::point reyeLeftUp = shapes.at(i).part(44);
dlib::point reyeLeftDowm = shapes.at(i).part(48);
dlib::point reyeRightUp = shapes.at(i).part(45);
dlib::point reyeRightDowm = shapes.at(i).part(47);
float reyeA = sqrt(pow(reyeLeftUp.x() - reyeLeftDowm.x(), 2) + pow(reyeLeftUp.y() - reyeLeftDowm.y(), 2));
float reyeB = sqrt(pow(reyeRightUp.x() - reyeRightDowm.x(), 2) + pow(reyeRightUp.y() - reyeRightDowm.y(), 2));
float reyeC = sqrt(pow(reyeLeft.x() - reyeRight.x(), 2) + pow(reyeLeft.y() - reyeRight.y(), 2));
float reyeEVR = (reyeA + reyeB) / (2 * reyeC);
//计算人嘴纵横比
dlib::point mouth_left = shapes.at(i).part(49);
dlib::point mouth_right = shapes.at(i).part(55);
dlib::point mouth_leftUp = shapes.at(i).part(51);
dlib::point mouth_leftDown = shapes.at(i).part(59);
dlib::point mouth_rightUp = shapes.at(i).part(53);
dlib::point mouth_rightDown = shapes.at(i).part(57);
float mouthA = sqrt(pow(mouth_leftUp.x() - mouth_leftDown.x(), 2) + pow(mouth_leftUp.y() - mouth_leftDown.y(), 2));
float mouthB = sqrt(pow(mouth_rightUp.x() - mouth_rightDown.x(), 2) + pow(mouth_rightUp.y() - mouth_rightDown.y(), 2));
float mouthC = sqrt(pow(mouth_left.x() - mouth_right.x(), 2) + pow(mouth_left.y() - mouth_right.y(), 2));
float mouthEVR = (mouthA + mouthB) / (2 * mouthC);
//摇头
//左脸边缘
dlib::point face_left = shapes.at(i).part(2);
//右脸边缘
dlib::point face_right = shapes.at(i).part(16);
//鼻子中心
dlib::point face_nose = shapes.at(i).part(31);
//鼻子到左脸边缘距离
float lfaceLength = sqrt(pow(face_nose.x() - face_left.x(), 2) + pow(face_nose.y() - face_left.y(), 2));
//鼻子到右脸边缘距离
float rfaceLength = sqrt(pow(face_nose.x() - face_right.x(), 2) + pow(face_nose.y() - face_right.y(), 2));
//记录张嘴次数
if (mouthEVR < 0.62){
//闭嘴
counter_mouth += 1;
}else if(mouthEVR > 0.70){
//张嘴
if (counter_mouth >= 1) {
mouthIndex += 1;
}
counter_mouth = 0;
}
else {
//此区间处于临界区,不稳定,不做检测
}
// 显示张嘴次数
char mouthBuf[100] = { 0 };
sprintf(mouthBuf, "mouth couent : %d", mouthIndex);
cv::putText(frame, mouthBuf, cv::Point(0, 20), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);
//记录左眼眨眼次数
if (leyeEVR > 2.9) {
//闭眼
counter_leye += 1;
}
else {
//睁眼
if (counter_leye >= 1) {
leyeIndex += 1;
}
counter_leye = 0;
}
//记录右眼眨眼次数
if (reyeEVR > 5.0) {
//闭眼
counter_reye += 1;
}
else {
//睁眼
if (counter_reye >= 1) {
reyeIndex += 1;
}
counter_reye = 0;
}
//取最小值
if (reyeIndex > leyeIndex) {
reyeIndex = leyeIndex;
}
//显示眨眼次数
char eyeBuf[100] = { 0 };
sprintf(eyeBuf, "eye count: %d", reyeIndex);
cv::putText(frame, eyeBuf, cv::Point(0, 45), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);
}
// Display it all on the screen
win.clear_overlay();
win.set_image(cimg);
win.add_overlay(render_face_detections(shapes));
}
}
catch(serialization_error& e)
{
cout << endl << e.what() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}
cmake_minimum_required (VERSION 3.5)
project (faceRecongize)
MESSAGE(STATUS "PROJECT_SOURCE_DIR " ${PROJECT_SOURCE_DIR})
SET(SRC_LISTS ${PROJECT_SOURCE_DIR}/src/main.cpp)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 配置头文件目录
include_directories(${PROJECT_SOURCE_DIR}/dlib-19.24)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/core/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/calib3d/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/features2d/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/flann/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/dnn/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/highgui/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/imgcodecs/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/videoio/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/imgproc/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/ml/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/objdetect/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/photo/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/stitching/include)
include_directories(${PROJECT_SOURCE_DIR}/opencv-4.5.0/modules/video/include)
# 设置不显示命令框
if(MSVC)
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
endif()
# 添加库文件
set(PRO_OPENCV_LIB ${PROJECT_SOURCE_DIR}/lib/opencv_video450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_core450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_videoio450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_calib3d450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_dnn450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_features2d450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_flann450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_highgui450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_gapi450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_imgcodecs450.lib
${PROJECT_SOURCE_DIR}/lib/opencv_imgproc450.lib
)
set(PRO_DLIB_LIB ${PROJECT_SOURCE_DIR}/lib/dlib19.24.0_release_32bit_msvc1900.lib)
# 生成可执行程序
ADD_EXECUTABLE(faceRecongize ${SRC_LISTS})
# 链接库文件
TARGET_LINK_LIBRARIES(faceRecongize ${PRO_OPENCV_LIB} ${PRO_DLIB_LIB})