开发环境:Ubuntu14.04, Opencv3.4, Clion
CMakeLists.txt编写如下:
cmake_minimum_required(VERSION 3.10)
project(demo)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
add_executable(demo main.cpp)
target_link_libraries(demo ${OpenCV_LIBS})
之前的opencv人脸检测使用的是Haar特征,效果一(la)般(ji),下面直接贴出源码
#include
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
CascadeClassifier faceCascade;
int main() {
/*
//图片人脸检测
faceCascade.load("/home/zzr/opencv-3.4.4/data/haarcascades/haarcascade_frontalface_alt2.xml");//加载分类器
Mat img = imread("/home/zzr/Desktop/me.jpg");
Mat imgGray;
vector faces;
if(img.empty())return 1;
if(img.channels() ==3) {
cvtColor(img, imgGray, CV_RGB2GRAY); // RGB转化为灰度
}
else {imgGray = img;} // 不转化
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
if(faces.size()>0)
{
for(int i =0; i faces;
while(1)
{
capture >> img;// 读取图像至img
if(img.empty())continue;
if(img.channels() == 3)cvtColor(img, imgGray, CV_RGB2GRAY);
else{imgGray = img;}
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
if(faces.size()>0)
{
for(int i =0; i
上面的代码分别包括图片人脸检测和视频人脸检测,代码中的注释也比较清楚了,这边说明几点:
再看一下DNN model的源码
#include
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace cv::dnn;
using namespace std;
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 = "/home/zzr/opencv-3.4.4/samples/dnn/face_detector/deploy.prototxt";
String modelBinary = "/home/zzr/opencv-3.4.4/samples/dnn/face_detector/res10_300x300_ssd_iter_140000_fp16.caffemodel";
//! [Initialize network]
Net net = readNetFromCaffe(modelConfiguration, modelBinary);
//! [Initialize network]
if (net.empty())
{
cerr << "Can't load network by using the following files: " << endl;
cerr << "prototxt: " << modelConfiguration << endl;
cerr << "caffemodel: " << modelBinary << endl;
cerr << "Models are available here:" << endl;
cerr << "/samples/dnn/face_detector" << endl;
cerr << "or here:" << endl;
cerr << "https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector" << endl;
exit(-1);
}
VideoCapture cap(-1);//must be -1
if (!cap.isOpened())
{
cout << "Couldn't open camera : " << endl;
return -1;
}
for (;;)//while(1)
{
Mat frame;
cap >> frame; // get a new frame from camera/video or read image
if (frame.empty())break;
if (frame.channels() == 4)cvtColor(frame, frame, COLOR_BGRA2BGR);
//! [Prepare blob]
Mat inputBlob = blobFromImage(frame, inScaleFactor,
Size(inWidth, inHeight),
meanVal, false, false); //Convert Mat to batch of images
//! [Set input blob]
net.setInput(inputBlob, "data"); //set the network input
//! [Make forward pass]
Mat detection = net.forward("detection_out"); //compute output
vector layersTimings;
double freq = getTickFrequency() / 1000;
double time = net.getPerfProfile(layersTimings) / freq;
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr());
ostringstream ss;
ss << "FPS: " << 1000 / time << " ; time: " << time << " ms";
putText(frame, ss.str(), Point(20, 20), 0, 0.5, Scalar(0, 0, 255));
float confidenceThreshold = min_confidence;
for (int i = 0; i < detectionMat.rows; i++)
{
float confidence = detectionMat.at(i, 2);
if (confidence > confidenceThreshold)
{
auto xLeftBottom = static_cast(detectionMat.at(i, 3) * frame.cols);
auto yLeftBottom = static_cast(detectionMat.at(i, 4) * frame.rows);
auto xRightTop = static_cast(detectionMat.at(i, 5) * frame.cols);
auto yRightTop = static_cast(detectionMat.at(i, 6) * frame.rows);
Rect object(xLeftBottom, yLeftBottom,
(xRightTop - xLeftBottom),
(yRightTop - yLeftBottom));
rectangle(frame, object, Scalar(0, 255, 0));
ss.str("");
ss << confidence;
String conf(ss.str());
String label = "Face: " + conf;
int baseLine = 0;
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),
Size(labelSize.width, labelSize.height + baseLine)),
Scalar(255, 255, 255), CV_FILLED);
putText(frame, label, Point(xLeftBottom, yLeftBottom),
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));
}
}
cv::imshow("detections", frame);
if (waitKey(1)!=-1) break;
}
return 0;
}
上面的代码就是利用SSD检测人脸,首先需要下载SSD的模型文件,模型位于${OPENCV_DIR}\samples\dnn\face_detector,里面有个download_weights.py,执行下就可以自动下载模型了。然后我们直接看结果,哇
!!!
参考:https://blog.csdn.net/minstyrain/article/details/78907425