【OpenCV】OpenCV人脸检测类
来源:互联网 发布:更改ssh 默认端口 编辑:程序博客网 时间:2024/06/03 16:37
源码地址:https://github.com/mc-jesus/face_detect_n_track
1、整张图检测人脸;detectFaceAllSizes
2、人脸区域检测人脸;detectFaceAroundRoi
3、作为模板做模板匹配(跟踪);detectFacesTemplateMatching
#pragma once#include <opencv2\core.hpp>#include <opencv2\highgui\highgui.hpp>#include <opencv2\objdetect\objdetect.hpp>class VideoFaceDetector{public: VideoFaceDetector(const std::string cascadeFilePath, cv::VideoCapture &videoCapture); ~VideoFaceDetector(); cv::Point getFrameAndDetect(cv::Mat &frame); cv::Point operator>>(cv::Mat &frame); void setVideoCapture(cv::VideoCapture &videoCapture); cv::VideoCapture* videoCapture() const; void setFaceCascade(const std::string cascadeFilePath); cv::CascadeClassifier* faceCascade() const; void setResizedWidth(const int width); int resizedWidth() const; boolisFaceFound() const; cv::Rect face() const; cv::Point facePosition() const; void setTemplateMatchingMaxDuration(const double s); double templateMatchingMaxDuration() const;private: static const double TICK_FREQUENCY; cv::VideoCapture* m_videoCapture = NULL; cv::CascadeClassifier* m_faceCascade = NULL; std::vector<cv::Rect> m_allFaces; cv::Rect m_trackedFace; cv::Rect m_faceRoi; cv::Mat m_faceTemplate; cv::Mat m_matchingResult; bool m_templateMatchingRunning = false; int64 m_templateMatchingStartTime = 0; int64 m_templateMatchingCurrentTime = 0; bool m_foundFace = false; double m_scale; int m_resizedWidth = 320; cv::Point m_facePosition; double m_templateMatchingMaxDuration = 3; cv::Rect doubleRectSize(const cv::Rect &inputRect, const cv::Rect &frameSize) const; cv::Rect biggestFace(std::vector<cv::Rect> &faces) const; cv::Point centerOfRect(const cv::Rect &rect) const; cv::Mat getFaceTemplate(const cv::Mat &frame, cv::Rect face); void detectFaceAllSizes(const cv::Mat &frame); void detectFaceAroundRoi(const cv::Mat &frame); void detectFacesTemplateMatching(const cv::Mat &frame);};
#include "VideoFaceDetector.h"#include <iostream>#include <opencv2\imgproc.hpp>const double VideoFaceDetector::TICK_FREQUENCY = cv::getTickFrequency();VideoFaceDetector::VideoFaceDetector(const std::string cascadeFilePath, cv::VideoCapture &videoCapture){ setFaceCascade(cascadeFilePath); setVideoCapture(videoCapture);}void VideoFaceDetector::setVideoCapture(cv::VideoCapture &videoCapture){ m_videoCapture = &videoCapture;}cv::VideoCapture *VideoFaceDetector::videoCapture() const{ return m_videoCapture;}void VideoFaceDetector::setFaceCascade(const std::string cascadeFilePath){ if (m_faceCascade == NULL) { m_faceCascade = new cv::CascadeClassifier(cascadeFilePath); } else { m_faceCascade->load(cascadeFilePath); } if (m_faceCascade->empty()) { std::cerr << "Error creating cascade classifier. Make sure the file" << std::endl << cascadeFilePath << " exists." << std::endl; }}cv::CascadeClassifier *VideoFaceDetector::faceCascade() const{ return m_faceCascade;}void VideoFaceDetector::setResizedWidth(const int width){ m_resizedWidth = std::max(width, 1);}int VideoFaceDetector::resizedWidth() const{ return m_resizedWidth;}bool VideoFaceDetector::isFaceFound() const{return m_foundFace;}cv::Rect VideoFaceDetector::face() const{ cv::Rect faceRect = m_trackedFace; faceRect.x = (int)(faceRect.x / m_scale); faceRect.y = (int)(faceRect.y / m_scale); faceRect.width = (int)(faceRect.width / m_scale); faceRect.height = (int)(faceRect.height / m_scale); return faceRect;}cv::Point VideoFaceDetector::facePosition() const{ cv::Point facePos; facePos.x = (int)(m_facePosition.x / m_scale); facePos.y = (int)(m_facePosition.y / m_scale); return facePos;}void VideoFaceDetector::setTemplateMatchingMaxDuration(const double s){ m_templateMatchingMaxDuration = s;}double VideoFaceDetector::templateMatchingMaxDuration() const{ return m_templateMatchingMaxDuration;}VideoFaceDetector::~VideoFaceDetector(){ if (m_faceCascade != NULL) { delete m_faceCascade; }}cv::Rect VideoFaceDetector::doubleRectSize(const cv::Rect &inputRect, const cv::Rect &frameSize) const{ cv::Rect outputRect; // Double rect size outputRect.width = inputRect.width * 2; outputRect.height = inputRect.height * 2; // Center rect around original center outputRect.x = inputRect.x - inputRect.width / 2; outputRect.y = inputRect.y - inputRect.height / 2; // Handle edge cases if (outputRect.x < frameSize.x) { outputRect.width += outputRect.x; outputRect.x = frameSize.x; } if (outputRect.y < frameSize.y) { outputRect.height += outputRect.y; outputRect.y = frameSize.y; } if (outputRect.x + outputRect.width > frameSize.width) { outputRect.width = frameSize.width - outputRect.x; } if (outputRect.y + outputRect.height > frameSize.height) { outputRect.height = frameSize.height - outputRect.y; } return outputRect;}cv::Point VideoFaceDetector::centerOfRect(const cv::Rect &rect) const{ return cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2);}cv::Rect VideoFaceDetector::biggestFace(std::vector<cv::Rect> &faces) const{ assert(!faces.empty()); cv::Rect *biggest = &faces[0]; for (auto &face : faces) { if (face.area() < biggest->area()) biggest = &face; } return *biggest;}/** Face template is small patch in the middle of detected face.*/cv::Mat VideoFaceDetector::getFaceTemplate(const cv::Mat &frame, cv::Rect face){ face.x += face.width / 4; face.y += face.height / 4; face.width /= 2; face.height /= 2; cv::Mat faceTemplate = frame(face).clone(); return faceTemplate;}void VideoFaceDetector::detectFaceAllSizes(const cv::Mat &frame){ // Minimum face size is 1/5th of screen height // Maximum face size is 2/3rds of screen height m_faceCascade->detectMultiScale(frame, m_allFaces, 1.1, 3, 0, cv::Size(frame.rows / 5, frame.rows / 5), cv::Size(frame.rows * 2 / 3, frame.rows * 2 / 3)); if (m_allFaces.empty()) return; m_foundFace = true; // Locate biggest face m_trackedFace = biggestFace(m_allFaces); // Copy face template m_faceTemplate = getFaceTemplate(frame, m_trackedFace); // Calculate roi m_faceRoi = doubleRectSize(m_trackedFace, cv::Rect(0, 0, frame.cols, frame.rows)); // Update face position m_facePosition = centerOfRect(m_trackedFace);}void VideoFaceDetector::detectFaceAroundRoi(const cv::Mat &frame){ // Detect faces sized +/-20% off biggest face in previous search m_faceCascade->detectMultiScale(frame(m_faceRoi), m_allFaces, 1.1, 3, 0, cv::Size(m_trackedFace.width * 8 / 10, m_trackedFace.height * 8 / 10), cv::Size(m_trackedFace.width * 12 / 10, m_trackedFace.width * 12 / 10)); if (m_allFaces.empty()) { // Activate template matching if not already started and start timer m_templateMatchingRunning = true; if (m_templateMatchingStartTime == 0) m_templateMatchingStartTime = cv::getTickCount(); return; } // Turn off template matching if running and reset timer m_templateMatchingRunning = false; m_templateMatchingCurrentTime = m_templateMatchingStartTime = 0; // Get detected face m_trackedFace = biggestFace(m_allFaces); // Add roi offset to face m_trackedFace.x += m_faceRoi.x; m_trackedFace.y += m_faceRoi.y; // Get face template m_faceTemplate = getFaceTemplate(frame, m_trackedFace); // Calculate roi m_faceRoi = doubleRectSize(m_trackedFace, cv::Rect(0, 0, frame.cols, frame.rows)); // Update face position m_facePosition = centerOfRect(m_trackedFace);}void VideoFaceDetector::detectFacesTemplateMatching(const cv::Mat &frame){ // Calculate duration of template matching m_templateMatchingCurrentTime = cv::getTickCount(); double duration = (double)(m_templateMatchingCurrentTime - m_templateMatchingStartTime) / TICK_FREQUENCY; // If template matching lasts for more than 2 seconds face is possibly lost // so disable it and redetect using cascades if (duration > m_templateMatchingMaxDuration) { m_foundFace = false; m_templateMatchingRunning = false; m_templateMatchingStartTime = m_templateMatchingCurrentTime = 0;m_facePosition.x = m_facePosition.y = 0;m_trackedFace.x = m_trackedFace.y = m_trackedFace.width = m_trackedFace.height = 0;return; }// Edge case when face exits frame while if (m_faceTemplate.rows * m_faceTemplate.cols == 0 || m_faceTemplate.rows <= 1 || m_faceTemplate.cols <= 1) {m_foundFace = false;m_templateMatchingRunning = false;m_templateMatchingStartTime = m_templateMatchingCurrentTime = 0;m_facePosition.x = m_facePosition.y = 0;m_trackedFace.x = m_trackedFace.y = m_trackedFace.width = m_trackedFace.height = 0;return;} // Template matching with last known face //cv::matchTemplate(frame(m_faceRoi), m_faceTemplate, m_matchingResult, CV_TM_CCOEFF); cv::matchTemplate(frame(m_faceRoi), m_faceTemplate, m_matchingResult, CV_TM_SQDIFF_NORMED); cv::normalize(m_matchingResult, m_matchingResult, 0, 1, cv::NORM_MINMAX, -1, cv::Mat()); double min, max; cv::Point minLoc, maxLoc; cv::minMaxLoc(m_matchingResult, &min, &max, &minLoc, &maxLoc); // Add roi offset to face position minLoc.x += m_faceRoi.x; minLoc.y += m_faceRoi.y; // Get detected face //m_trackedFace = cv::Rect(maxLoc.x, maxLoc.y, m_trackedFace.width, m_trackedFace.height); m_trackedFace = cv::Rect(minLoc.x, minLoc.y, m_faceTemplate.cols, m_faceTemplate.rows); m_trackedFace = doubleRectSize(m_trackedFace, cv::Rect(0, 0, frame.cols, frame.rows)); // Get new face template m_faceTemplate = getFaceTemplate(frame, m_trackedFace); // Calculate face roi m_faceRoi = doubleRectSize(m_trackedFace, cv::Rect(0, 0, frame.cols, frame.rows)); // Update face position m_facePosition = centerOfRect(m_trackedFace);}cv::Point VideoFaceDetector::getFrameAndDetect(cv::Mat &frame){ *m_videoCapture >> frame; // Downscale frame to m_resizedWidth width - keep aspect ratio m_scale = (double) std::min(m_resizedWidth, frame.cols) / frame.cols; cv::Size resizedFrameSize = cv::Size((int)(m_scale*frame.cols), (int)(m_scale*frame.rows)); cv::Mat resizedFrame; cv::resize(frame, resizedFrame, resizedFrameSize); if (!m_foundFace) detectFaceAllSizes(resizedFrame); // Detect using cascades over whole image else { detectFaceAroundRoi(resizedFrame); // Detect using cascades only in ROI if (m_templateMatchingRunning) { detectFacesTemplateMatching(resizedFrame); // Detect using template matching } } return m_facePosition;}cv::Point VideoFaceDetector::operator>>(cv::Mat &frame){ return this->getFrameAndDetect(frame);}
0 0
- 【OpenCV】OpenCV人脸检测类
- opencv 检测人脸
- opencv检测人脸
- 人脸检测 opencv
- OpenCV人脸检测
- opencv人脸检测
- OpenCV人脸检测
- OpenCv人脸检测
- opencv 人脸检测
- OpenCV人脸检测
- opencv人脸检测
- OpenCV人脸检测
- 人脸检测(opencv)
- opencv人脸检测
- opencv人脸检测
- opencv----人脸检测
- OpenCV人脸检测
- opencv人脸检测
- 慕课网Linux达人养成计划I内容摘记
- url解析
- 服务器/虚拟机重要文件备份
- [Android] EventBus事件总线
- cookie/session总结
- 【OpenCV】OpenCV人脸检测类
- 依存句法分析与语义依存分析的区别
- C++学习笔记
- NB-IoT使用场景
- viewpager中彻底性动态添加、删除Fragment
- gcd 学习总结 (二)
- JS中遇到的问题
- C# Queue使用
- ormlite保存大量数据性能优化