假设:
磁盘上有N个文件需要进行人脸检测。
如果我以“慢”模式进行,一切都很好(面孔是他们的面孔):
for(auto mat : getMyMats()) {
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
vector<Rect> faces;
facer.detectMultiScale(mat, faces);
}
但如果我尝试缓存并重复使用CascadeClassifier - 附近50%的图像被检测到非常错误 - 无效的地方,大小,面孔数量:
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
for(auto mat : getMyMats()) {
vector<Rect> faces;
facer.detectMultiScale(mat, faces);
}
CascadeClassifier重用有什么问题 Windows,OpenCV 3.0都是调试和发布版本。
重复的样本代码:
// compiler - opencv/include referenced
// linker - opencv/lib referenced and
// opencv_core300.lib, opencv_imgproc300.lib, opencv_imgcodecs300.lib, opencv_objdetect300.lib (or world or debug libs) are referenced
// 1.png, 2.png, 3.png,
#include <vector>
#include <string>
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
//count faces in load-every-time call
int no_reuse_call() {
int cnt = 0;
for (auto n : { "1.png","2.png","3.png" }) {
vector<Rect> faces{};
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
for (auto n : { "1.png","2.png","3.png" }) {
vector<Rect> faces{};
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
return cnt;
}
//coutn faces in one-instance call
int reuse_call() {
int cnt = 0;
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
for (auto n : { "1.png","2.png","3.png" }) {
vector<Rect> faces{};
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
for (auto n : { "1.png","2.png","3.png" }) {
vector<Rect> faces{};
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
return cnt;
}
int reuse_call_reverse() {
int cnt = 0;
CascadeClassifier facer("haarcascade_frontalface_alt.xml");
for (auto n : {"3.png" ,"2.png", "1.png"}) {
vector<Rect> faces{};
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
for (auto n : { "3.png" ,"2.png", "1.png" }) {
vector<Rect> faces{};
Mat m = imread(n, CV_LOAD_IMAGE_GRAYSCALE);
facer.detectMultiScale(m, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(50, 50));
cnt += faces.size(); //vector given to detectMultiScale cleared in detectMultiScale
cout << faces[0] << endl;
}
return cnt;
}
int main() {
cout << "Created every image 2*3 files" << endl;
cout << no_reuse_call() << endl;
cout << "Created one time and files in alphabet order 2*3 files" << endl;
cout << reuse_call() << endl;
cout << "Created one time and files in contra - alphabet order 2*3 files" << endl;
cout << reuse_call_reverse() << endl;
cout << "You can see:" << endl;
cout << " if cascade is reused - detection in 3.png file is stabily wrong if it is processed after 1.png and 2.png" << endl;
cout << " it's depend on order - if 3.png is first in row it detected right even in second call after 1.png and 2.png" << endl;
cout << " it's random and based somehow on image - 1.png and 2.png are always detected validly" << endl;
return 0;
}
答案 0 :(得分:0)
查看https://github.com/Itseez/opencv/issues/5475
由于某些原因,opencv 3.0.0中的ocl不稳定? 所以作者建议调用setUseOpenCL(false);在程序中 - 使用此选项一切正常