2010-07-21 4 views
2

J'ai une fuite dans le code que j'ai mis ci-dessous. Quand j'ai utilisé cvCreateImage au lieu de cvCreateImageHeader, il y avait une fuite de 304Kb et 107b mais quand j'ai changé, il est devenu 107 bits seulement. Pourriez-vous m'aider à trouver une fuite?Fuite dans OpenCV NSImage Vers la procédure du convertisseur IplImage

+ (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; 
} 
+0

La question semble foiré .. pourriez-vous le formater un peu mieux? –

Répondre

0

C'est votre appel à cvSetImageData. Lorsque vous appelez cvCreateImage, il alloue à la fois l'en-tête et les données d'image. cvCreateImageHeader alloue uniquement l'en-tête de l'image. Lorsque vous appelez cvSetImageData, il ne copie PAS les données dans la structure.

Au contraire, il définit simplement le pointeur sur les données que vous avez fournies. Ainsi, si vous appelez cvCreateImage puis cvSetImageData, les données d'image allouées par cvCreateImage sont perdues.

Un effet secondaire plutôt désagréable de la façon dont vous faites cela, c'est que l'utilisateur pourrait potentiellement appeler cvReleaseImage, qui tenterait en fait de libérer les données dans [rep bitmapData]. Un bien meilleur moyen serait simplement d'appeler cvCreateImage, puis de copier toutes les données de [rep bitmapData] dans celui-ci.

Espérons que cela aide.

Questions connexes