2010-12-02 18 views
3

J'ai été chargé de créer une application qui fonctionne avec des milliers d'images, beaucoup trop à charger dans la RAM en même temps. Je suppose que c'est quelque peu analogue à une visionneuse de photos comme Picassa, en ce qu'à tout moment l'application n'a besoin des données de pixels que d'une poignée des images cataloguées. L'application doit également gérer des images extrêmement volumineuses, où seul un petit sous-ensemble des données de pixels serait réellement requis à un moment donné pour l'analyse ou l'affichage d'images, ce qui, je suppose, est quelque peu analogue à Google Earth. En bref, l'application doit charger de manière dynamique uniquement la partie des données de pixel qui est réellement requise à un moment donné. Ayant traité uniquement avec le chargement d'image statique typique des bibliothèques d'images comme OpenCV, CImg, ou Magick ++, je suis un peu à la perte comment je pourrais le mieux aborder le problème. Ma question est donc la suivante: existe-t-il des modèles de conception standard pour cette exigence, ou des approches pour résoudre ce problème (ou un problème similaire)? Par contre, pour les petites images, je me rends compte que je pouvais simplement retarder le chargement de l'image jusqu'à ce que ce soit nécessaire, mais il y a deux problèmes clés qui me viennent à l'esprit avec cette approche. (1) Cela ne résout pas le problème de grande image. (2) Puisque le déchargement de l'image immédiatement après son utilisation pourrait être inefficace, j'aurais besoin d'un gestionnaire de gestion de mémoire dans l'application qui ne décharge les images que lorsque de nouvelles images sont chargées et qu'un certain seuil de mémoire a été dépassé. Il est clair qu'un problème de gestion de la mémoire similaire reste pour les parties d'une image plus grande chargée en mémoire. Je reconnais clairement qu'un tel outil est au-delà de mes connaissances et de mon expérience, donc si c'est la réponse dominante à cette question, alors j'ai une question complémentaire. Quelqu'un pourrait-il recommandé quelques tutoriels de base sur la gestion de la mémoire?Existe-t-il des modèles standard pour implémenter une classe pour charger dynamiquement des images?

Merci pour votre aide! MISE À JOUR: Pour ceux qui sont curieux, j'ai pensé partager l'approche que j'ai prise. La classe d'image que j'ai créée paresseuse charge les données d'image. Pour résoudre le problème avec le chargement de milliers d'images, j'ai créé une classe qui garderait une trace des handles de fichiers (Windows a une limite - voir _getmaxstdio), et la quantité de mémoire d'image chargée, en déchargeant si nécessaire. Pour gérer de très grandes images, j'ai utilisé la bibliothèque d'images VXL comme back-end, qui est capable de charger une sous-section d'une grande image. Certes, ce n'est pas très efficace pour certaines images (images compressées en particulier), mais comme je travaille principalement avec des images TIFF en mosaïque, cela fonctionne très bien.

+0

Il est connu comme la mise en cache. – ruslik

+0

En fait, la mise en cache est exactement le contraire de ce dont cette personne a besoin. –

+0

La mise en cache utilise peu de mémoire rapide pour accélérer l'accès à une grande quantité de mémoire lente. Dans ce cas, la mémoire principale et lente serait le disque dur, et la RAM serait la plus rapide. Mise en cache est également choisir ce qu'il faut garder à proximité et ce qu'il faut jeter – ruslik

Répondre

1

Si les images les plus grandes sont vraiment grandes, ne s'adaptant pas à l'écran, alors il peut être raisonnable de les diviser en plus petites pièces.

Si vous avez l'habitude d'afficher les images réduites (zoom arrière) alors vous pouvez faciliter votre travail en créant et en stockant les versions réduites des images plus grandes. La cascade entière d'images réduites avec des côtés x 0,707, x 0,5 etc prend au maximum autant de stockage que l'image originale.

Pour le déchargement paresseux, vous pouvez charger des images (ou des fragments ou des versions réduites) et souvenez-vous du moment où ceux-ci ont été affichés et que le dernier lot de la mémoire qu'ils prennent. Une fois que vous atteignez le seuil mais que vous avez besoin de charger plus d'images, vous pouvez décharger en commençant par le plus ancien pour libérer de l'espace.

+0

+1 pour un zoom arrière. On peut aller plus loin en utilisant une simple transformation en ondelettes afin de ne pas gaspiller d'espace. – ruslik

0

La première exigence semble assez facile à satisfaire. Créez simplement une classe qui effectue un chargement paresseux, ce qui signifie qu'elle ne charge ses données que lorsqu'elle en a besoin.

La deuxième exigence SERAIT facile si vous travailliez avec n'importe quel type de données pouvant être traitées par décalage. La plupart des formats d'image utilisent la compression, donc à moins que vous ne souhaitiez vous limiter à ceux qui ne le font pas, votre travail sera coupé pour vous. Une alternative plus facile pourrait être de diviser les plus grandes images en plus petites et de ne charger que les parties visibles/en cours de traitement.

+0

:) Lire un peu paresseux sur le chargement (ici http://www.martinfowler.com/eaaCatalog/lazyLoad.html est un résumé rapide). Je suppose est un peu ce que j'avais à l'esprit (mais pas exprimé), de sorte que les champs comme la hauteur de l'image et la largeur peuvent être accessibles même si les données de pixels ne sont pas chargées de l'approche « fantôme ». Mais y a-t-il un compliment au chargement paresseux à gérer si et quand un objet chargé paresseux (ou les données de l'objet) est déchargé? Plusieurs requêtes séquentielles sur le même objet seraient très inefficaces si vous déchargiez immédiatement après l'utilisation des données à chaque fois. –

0

Partie 2 - quelques formats d'images prennent en charge le chargement d'une section de l'image efficently

Vous allez probablement avoir à pré-traiter les images, de les lire et de les diviser en tuiles dans des fichiers individuels (ou une base de données) .