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

Здравейте общност на stackoverflow,

Разработвах алгоритъм, използвайки OpenCV библиотека. До сега нямах проблеми с паметта, когато интегрирах алгоритъма в приложение. Не съм много опитен в C++ и "правилното кодиране", така че не знам какво може да причини проблема.

Грешката, която получавам, когато пусна кода, е типичното "повреждане на купчината". В кода по-долу можете да видите функцията, в която получавам точката на прекъсване.

Мисля, че проблемът е свързан с моята Mat frametemp. Това, което правя в тази функция, е да изпратя Mat като параметър, след което копирам този Mat във временен Mat и работя с него (откриване на лица в изображението и маркиране на правоъгълник в тях). Накрая връщам този временен мат. Трябва да има нещо нередно с разпределението/отделянето на паметта на тези 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 class е предварително дефиниран клас в OpenCV библиотеките, така че предполагам, че има подходящ конструктор за копиране (който всъщност не знам какво е...). Разгледах информацията за клас Mat и намерих следното твърдение: Използвайте конструктор за копиране или оператор за присвояване, където може да има масив или израз от дясната страна (вижте по-долу). Както беше отбелязано във въведението, присвояването на масив е операция O(1), защото копира само заглавката и увеличава брояча на препратки. Методът Mat::clone() може да се използва за получаване на пълно (дълбоко) копие на масива, когато имате нужда от него. - person Jaime Mateo; 26.07.2015
comment
Ще се опитам да направя clone() вместо метод frame.copyTo() и може би това е грешката... Ще го проверя и ще публикувам резултата. - person Jaime Mateo; 26.07.2015