2009-07-25 5 views
1

J'essaye d'itérateur sur certains répertoires contenant environ 3000 images. Je charge l'image. Si l'image est chargée, je la relâche. C'est le plus petit programme que je puisse écrire pour reproduire l'erreur. Après le chargement et la libération de 124 images, le programme cesse de charger les images. Je pense que c'est un problème mémoire mais je ne comprends pas ce qui provoque exactement le programme pour arrêter le chargement des images. J'utilise OpenCV sur mon Mac . Je ne sais pas exactement comment je peux comprendre quelle version j'utilise.Problème avec itération sur beaucoup d'images dans OpenCv avec mac os

Voici le code de mon projet.

bool FaceDetectionStrategy::detectFace(std::string imagePath) { 

    IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR); 
    if (img) { 
     std::cout << "Image loaded " << imagePath << std::endl; 
     cvReleaseImage(&img); 
    } else { 
     std::cout << "Image not loaded " << imagePath << std::endl; 
    } 
return true; 

}

Cette méthode est appelée pour chaque image dans les repertoires j'itérer. Après 124 images, la partie if (img) est évaluée à false et la branche else est exécutée. Si j'essaye de charger des images d'autres parties du programme plus tard, elles ne se chargeront pas non plus.

Modifier ce n'est pas un problème de mémoire. Mac OS standard max fichiers ouverts est de 256 après l'avoir changé en 512, je peux ouvrir 251 images. il semble donc que OpenCV ne ferme pas les fichiers image après les avoir chargés.

Répondre

3

La recherche dans le bugtracker d'OpenCv a montré cette réponse au problème: cvLoadImage with Mac ImageIO leaves file handles open.

Il semble que ce soit un bug dans l'implémentation d'OpenCV mac et la seule façon de le résoudre est d'installer une nouvelle version d'OpenCV. L'installation de la dernière version d'OpenCV à partir du tronc du référentiel permet de résoudre le problème.Il est parfois utile de vérifier le BugTracker des frameworks que vous utilisez ...

+0

Hé, c'est dommage :(Bon de savoir que tu n'étais pas fou quand même, hein? – GManNickG

+0

Oui ça fait du bien de voir que l'erreur n'était pas dans mon code :) – Janusz

2

Comportement concernant la mémoire a rarement à faire avec un nombre cohérent, selon mon expérience. La seule façon de le rendre cohérent est s'il y a une sorte de limite interne dans cvLoadImage qui se trouve être le nombre peu commun 124. Mais votre logique me semble bien, que vos images devraient être libérées.

Plus probablement, puisque je suppose que vos répertoires ne changent pas entre les tests, cette 125e image est mauvaise.

Avez-vous vérifié que l'image que vous essayez de charger existe réellement? Si c'est le cas (ce qui est probablement le cas), vérifiez que le format du fichier d'image est supported by OpenCV. Si cela est également vrai, assurez-vous que le fichier n'est pas corrompu en l'ouvrant avec un autre éditeur. Vous pouvez avoir OpenCV help you out with errors. Utilisez cvGetErrStatus() pour vérifier s'il y avait une erreur, puis utilisez cvErrorStr() pour obtenir une description textuelle. Vous pouvez faire quelque chose comme ceci:

// I would recommend putting this in a file, like CVUtility.h 

#include <exception> 

void check_CV_Error(void) 
{ 
    int errorCode = cvGetErrStatus(); 
    if (errorCode) // I'm assuming 0 means no reportable error 
    { 
     throw std::runtime_error(cvErrorStr(errorCode)); 
     // std::cerr << cvErrorStr(errorCode); 
     //^if you would rather not use exceptions 
    } 
} 

Votre code devient alors:

bool FaceDetectionStrategy::detectFace(std::string imagePath) { 

    IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR); 
    if (img) { 
     std::cout << "Image loaded " << imagePath << std::endl; 
     cvReleaseImage(&img); 
    } else { 
     std::cout << "Image not loaded " << imagePath << std::endl; 
     check_CV_Error(); // find reason for error 
    } 
return true; 

Et qui lancera une exception pour vous attraper et vous connecter, et peut-être réagir. (Ou imprimez l'erreur à la console si vous utilisez la version std::cerr)

+0

Le code d'erreur est zéro. Ainsi, OpenCV ne provoque pas l'erreur ou ne définit pas de code d'erreur. J'ai chargé toutes les images avec OpenCV avant, mais pas tellement à l'intérieur d'une course, donc les images doivent être compatibles avec OpenCV. – Janusz

+0

Essayez de supprimer ou de déplacer l'un des 100 premiers et de voir si le problème se déplace vers un nouveau bitmap, pour être sûr. Cela permettra d'éliminer "c'est une image spécifique" des idées. – GManNickG

+0

Commencer par un autre répertoire a d'abord produit la même erreur. Les images ne sont pas toutes de la même taille entre 20 et 60 K mais le nombre d'images que je peux ouvrir reste le même. Peut-être que je dois faire quelque chose d'autre pour forcer OpenCV à libérer la poignée de fichier? Ce serait une raison pour que le nombre d'images que je peux charger reste le même. – Janusz