多次调用CascadeClassifier(opencv)有什么问题

时间:2015-10-08 12:25:49

标签: c++ opencv

假设:

  1. 磁盘上有N个文件需要进行人脸检测。

  2. 如果我以“慢”模式进行,一切都很好(面孔是他们的面孔):

    for(auto mat : getMyMats()) {
       CascadeClassifier facer("haarcascade_frontalface_alt.xml");
       vector<Rect> faces;
       facer.detectMultiScale(mat, faces);
    }
    
  3. 但如果我尝试缓存并重复使用CascadeClassifier - 附近50%的图像被检测到非常错误 - 无效的地方,大小,面孔数量:

    CascadeClassifier facer("haarcascade_frontalface_alt.xml");
    for(auto mat : getMyMats()) {   
        vector<Rect> faces;
        facer.detectMultiScale(mat, faces);
     }
    
  4. 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;
        }
    

1 个答案:

答案 0 :(得分:0)

查看https://github.com/Itseez/opencv/issues/5475

由于某些原因,opencv 3.0.0中的ocl不稳定? 所以作者建议调用setUseOpenCL(false);在程序中 - 使用此选项一切正常