Утечка в процедуре преобразования OpenCV NSImage To IplImage - PullRequest
2 голосов
/ 21 июля 2010

У меня есть утечка в коде, который я поставил ниже. Когда я использовал cvCreateImage вместо cvCreateImageHeader, это было 304Kb и 107b утечки, но когда я изменил это стало только 107 укусов Не могли бы вы помочь мне найти утечку.

+ (IplImage *) nsImageToIplImage:(NSImage *)image {
    // NSImage to IplImage

    NSBitmapImageRep *orig = [[image representations] objectAtIndex: 0];
    // a copy or else the color-channel shift that we do later on will affect the original NSImage!

    NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:[orig representationUsingType:NSTIFFFileType properties:NULL]];
    int depth       = [rep bitsPerSample];
    int channels    = [rep samplesPerPixel];
    int height      = [rep size].height;
    int width       = [rep size].width;

    // note- channels had better be "3", or else the loop down below will act pretty funky...
    // NSTIFFFileType seems to always give three-channel images, so I think it's okay...


    IplImage *to_return = cvCreateImageHeader(cvSize(width, height), depth, channels);
    cvSetImageData(to_return, [rep bitmapData], [rep bytesPerRow]);



    // Reorder BGR to RGB
    // no, I don't know why it's in BGR after cvSetData
    for (int i = 0; i < to_return->imageSize; i += 3) {
        uchar tempR, tempG, tempB;
        tempR = to_return->imageData[i];
        tempG = to_return->imageData[i+1];
        tempB = to_return->imageData[i+2];

        to_return->imageData[i] = tempR;
        to_return->imageData[i+1] =tempG;
        to_return->imageData[i+2] = tempB;

    }




    return to_return;
}

1 Ответ

0 голосов
/ 16 марта 2011

Это ваш вызов cvSetImageData. Когда вы вызываете cvCreateImage, он выделяет как заголовок, так и данные изображения. cvCreateImageHeader выделяет только заголовок изображения.

Когда вы вызываете cvSetImageData, он НЕ копирует данные в структуру. Скорее он просто устанавливает указатель так, чтобы он указывал на любые данные, которые вы указали. Поэтому, если вы вызываете cvCreateImage, а затем cvSetImageData, данные изображения, выделенные cvCreateImage, теряются.

Довольно неприятный побочный эффект того, как вы это делаете, заключается в том, что пользователь потенциально может вызвать cvReleaseImage, который фактически попытается освободить данные в [rep bitmapData]. Гораздо лучшим способом было бы просто вызвать cvCreateImage, а затем скопировать в него все данные из [rep bitmapData].

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...