OpenCV自带人脸检测模型,拿来就能用。所以“人脸检测”这个任务对于OpenCV而言真是太简单了——感叹一下:OpenCV太强大了!相关的介绍文章在网上可以搜到很多,原本我觉得没必要再写一篇了。结果我在写练习代码的时候,还是碰到了一些新问题,值得记录一下。
人脸检测需要用到opencv_objdetect模块。我们在之前介绍OpenCV编译的时候没有用到这个模块,这次就要补充编译一下了。需要注意这几个项目的依赖关系:opencv_objdetect依赖opencv_dnn,而opencv_dnn又依赖libprotobuf。
我们先编译OpenCV自带的libprotobuf(在3rdparty目录里),结果碰到一堆莫名其妙的错误,苦恼了5分钟……
2>D:\Dev\GitHub\opencv\3rdparty\protobuf\src\google\protobuf\arena.cc(108,49): error C2511: “google::protobuf::internal::SerialArena::SerialArena(google::protobuf::internal::SerialArena::Block *,void *)”:“google::protobuf::internal::SerialArena”中没有找到重载的成员函数
2>D:\Dev\GitHub\vcpkg\installed\x64-windows\include\google/protobuf/arena_impl.h(204): message : 参见“google::protobuf::internal::SerialArena”的声明
What?! 怎么会有vcpkg?OpenCV自带了protobuf源码,何必再麻烦vcpkg。王阳明也说了,“吾性自足,不假外求。”赶紧打开libprotobuf的项目属性页,把Use Vcpkg设置成“否”。然后重新编译,顺利通过!接着在编译opencv_dnn项目时也需要做相同的调整。
libprotobuf和opencv_dnn两个项目编译通过后,接着编译opencv_objdetect,不出意外的话就能顺利通过了。然后我们就可以在OpenCVMisc项目中演练起来了。
OpenCVMisc项目设置需要做些小修改:
附加包含目录增加:
..\opencv\modules\objdetect\include
附加依赖项增加:
(Debug版本) ..\opencv\build\lib\Debug\opencv_objdetect4100d.lib
(Release版本) ..\opencv\build\lib\Release\opencv_objdetect4100.lib
并且把opencv_objdetect4100.dll和opencv_objdetect4100d.dll从OpenCV项目中拷贝到OpenCVMisc项目中。
接着,在OpenCVMiscDlg.cpp文件头上增加:
#include <opencv2/objdetect.hpp>
再编写测试代码,如下:
cv::CascadeClassifier faceClassifier;
// 加载级联分类器
if (!faceClassifier.load(".\\assets\\haarcascade_frontalface_alt.xml")) {
std::cout << "Failed to load classifier." << std::endl;
return;
}
Mat srcImage = imread(".\\assets\\ruok.png");
if (srcImage.empty()) return;
// 灰度化处理
Mat gray;
cv::cvtColor(srcImage, gray, COLOR_BGR2GRAY);
// 直方图均衡化,增强对比度
cv::equalizeHist(gray, gray);
std::vector<Rect> faces;
faceClassifier.detectMultiScale(gray, faces);
for each (Rect face in faces) {
cv::rectangle(srcImage, face, Scalar(0, 255, 0));
}
imshow("Face Detection", srcImage);
haarcascade_frontalface_alt.xml是已经训练好的人脸模型,是从OpenCV源码工程中拷贝出来的。(注:OpenCV开源项目的data目录下还有蛮多其他模型,有兴趣的话都可以试试。)上面的代码逻辑过于简单,就不解释了😂