Повреждение кучи с помощью OpenCV C++ HOG Detector

Привет, сообщество stackoverflow,

Я разрабатываю алгоритм с использованием библиотеки OpenCV. У меня не было проблем с памятью до сих пор, когда я интегрирую алгоритм в приложение. Я не очень хорошо разбираюсь в С++ и "правильно кодирую", поэтому не знаю, что может вызвать проблему.

Ошибка, которую я получаю при выпуске кода, является типичной «повреждением кучи». В приведенном ниже коде вы можете увидеть функцию, в которой я получаю точку останова.

Я думаю, что проблема связана с моей температурой кадра Mat. Что я делаю в этой функции, так это отправляю мат в качестве параметра, затем копирую этот мат во временный мат и работаю с ним (обнаружение людей на изображении и выделение на них прямоугольника). Наконец-то я возвращаю этот временный мат. Должно быть что-то не так с выделением/освобождением памяти этих матов, но я не могу найти на это ответ. Все, что не так в моем коде, обязательно может помочь мне решить точку останова. Заранее спасибо за ответ.

Mat predetection(Mat &frame){

    Mat rois;
    Mat frametemp;
    frame.copyTo(frametemp);

    // HOG for people detections
    HOGDescriptor hog;
    static vector<float> detector = HOGDescriptor::getDefaultPeopleDetector();
    if (!detector.size()) {
        fprintf(stderr, "ERROR: getDefaultPeopleDetector returned NULL\n");     
    }
    hog.setSVMDetector(detector);

    fflush(stdout);
    vector<Rect> found, found_filtered;
    vector<double> foundWeights, foundWeights_filtered;

    // run the detector with default parameters. to get a higher hit-rate
    // (and more false alarms, respectively), decrease the hitThreshold and
    // groupThreshold (set groupThreshold to 0 to turn off the grouping completely).
    hog.detectMultiScale(frametemp, found, foundWeights, 0, Size(8, 8), Size(32, 32), 1.05, 2);


    size_t i, j;
    for (i = 0; i < found.size(); i++)
    {

        Rect r1 = found[i];
        double prescore = foundWeights[i];
        for (j = 0; j < found.size(); j++)
            if (j != i && (r1 & found[j]) == r1)
                break;
        if (j == found.size()){
            found_filtered.push_back(r1);
            foundWeights_filtered.push_back(prescore);
        }
    }


    for (i = 0; i < found_filtered.size(); i++)
    {
        Rect r2 = found_filtered[i];
        double prescore_filtered = foundWeights_filtered[i];
        int x1, y1, x2, y2;
        x1 = r2.x;
        y1 = r2.y;
        x2 = r2.x + r2.width;
        y2 = r2.y + r2.height;

        // the HOG detector returns slightly larger rectangles than the real objects.
        // so we slightly shrink the rectangles to get a nicer output.
        r2.x += cvRound(r2.width*0.1);
        r2.width = cvRound(r2.width*0.8);
        r2.y += cvRound(r2.height*0.07);
        r2.height = cvRound(r2.height*0.8);
        rectangle(frametemp, r2.tl(), r2.br(), cv::Scalar(255, 0, 0), 1);
    }
    return frametemp;
}

А это стек вызовов:

ntdll.dll!_RtlpBreakPointHeap@4()  + 0x19 bytes 
ntdll.dll!RtlpValidateHeapEntry()  + 0x3088c bytes  
ntdll.dll!_RtlDebugFreeHeap@12()  + 0xbf bytes  
ntdll.dll!RtlpFreeHeap()  + 0x44b2f bytes   
ntdll.dll!RtlFreeHeap()  + 0x1ba bytes  
msvcr100.dll!free(void * pBlock)  Line 51   C
DiVA_detector3.exe!predetection(cv::Mat & frame)  Line 70 + 0x9e bytes  C++

person Jaime Mateo    schedule 23.07.2015    source источник


Ответы (1)


Есть ли в вашем классе Mat подходящий и правильный конструктор копирования? Он вызывается, когда вы выполняете return frametemp, и если в нем есть ошибка, вы можете столкнуться с подобными проблемами.

person egrunin    schedule 23.07.2015
comment
Спасибо за ответы. Класс Mat - это предопределенный класс в библиотеках OpenCV, поэтому я думаю, что у него есть соответствующий конструктор копирования (который я действительно не знаю, что это такое...). Я просмотрел информацию о классе Mat и нашел следующее утверждение: используйте конструктор копирования или оператор присваивания, где справа может быть массив или выражение (см. ниже). Как отмечалось во введении, присваивание массива — это операция O(1), поскольку она копирует только заголовок и увеличивает счетчик ссылок. Метод Mat::clone() можно использовать для получения полной (глубокой) копии массива, когда вам это нужно. - person Jaime Mateo; 26.07.2015
comment
Я попытаюсь сделать clone() вместо метода frame.copyTo() и, возможно, это ошибка... Я проверю это и опубликую результат. - person Jaime Mateo; 26.07.2015