CascadeClassifier::detectMultiScale 不适用于 C++

Posted

技术标签:

【中文标题】CascadeClassifier::detectMultiScale 不适用于 C++【英文标题】:CascadeClassifier::detectMultiScale doesn't work with C++ 【发布时间】:2015-06-10 14:40:04 【问题描述】:

我正在使用 OpenCV 和 CascadeClassifier::detectMultiScale 进行面部检测。我的问题是它似乎会导致输出vector<Rect> 上的内存损坏。向量正确填充了 Rects,但是当向量被释放时会导致崩溃。

这仅在编译调试版本时发生。错误消息是Debug Assertion Failed,这让我想知道Release构建中是否也出现问题,并且根本没有检查断言。

这可能是 OpenCV 的一个错误吗?还是只是我处理向量的方式有问题?

以下代码 sn-p 显示了重现该错误的示例代码:

#include <opencv2/opencv.hpp>
using namespace cv;

int main(array<System::String ^> ^args)

    VideoCapture video(0);
    Mat frame;
    CascadeClassifier classifier("haarcascade_frontalface_default.xml");

    while (waitKey(1000 / 30) != 'q')
    
        video >> frame;

        vector<Rect> faces;
        classifier.detectMultiScale(frame, faces);
        for (int i = 0; i < faces.size(); i++)
            rectangle(frame, faces[i], Scalar(255, 255, 255));

        imshow("Camera", frame);
     // <<< The crash occurs here when the faces vector is released

我收到以下错误消息:

调试断言失败!

程序:MyProgram.exe 文件:minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp 线路:892

表达式:is_block_type_valid(header->_block_use)

【问题讨论】:

这段代码还能用吗?你不需要waitKey(0) 来实际显示 imshow() 吗?另外,也许是因为 imshow() 正在使用 rect 仍在使用的框架之一? 这里没有理由使用new作为向量。 @GPPK:waitKey(1000 / 30) 表示它会等待一个键,它会尝试每秒运行 30 帧。如果我删除 delete faces; 行,一切都会完美运行(当然,除了内存泄漏)。 @crashmstr:你说得对,我选择以这种方式分配它是为了在调用终结器时使其明确。如果我不使用new,它仍然会在循环结束时以相同的方式崩溃。 @MariusUt C++ 没有终结器,但有析构函数,并且当(非指针)变量超出范围时,析构函数无论如何都会在块的末尾被调用。所以不知道你在用new 做什么有什么不同 【参考方案1】:

我也有同样的问题。我通过将取消引用的全局指针传递给函数来解决它。

    std::vector<cv::Rect>* faces = nullptr;

    void init()
    
        faces = new std::vector<cv::Rect>; //never call delete whatever you do
    

    void findSomeFaces()
    
        cascade->detectMultiScale(image_source, *faces);
    

【讨论】:

这不会导致内存泄漏吗? 我问这个问题是因为当我尝试合并两个有自己的内存管理的项目时,我遇到了同样的情况。当我尝试删除分配的内存时,它仍然崩溃。所以现在我根本不删除它,否则它会使我的程序崩溃。 没错,我在我的程序中遇到了同样的问题,这就是为什么我放了厚颜无耻的评论。理论上这是内存泄漏,但是在 cv::Rect 向量上调用 delete (是否为空)会导致问题。必须注意不要连续分配 cv::Rect 向量。程序结束时留下的任何东西都将由操作系统清理。问题出在 OpenCV 的代码中。 并不能真正解决问题。我已经尝试过了,它仍然崩溃。我编译到 Release 并且成功了。

以上是关于CascadeClassifier::detectMultiScale 不适用于 C++的主要内容,如果未能解决你的问题,请参考以下文章