2013-09-04 4 views
0

Nous développons un outil d'acquisition multicapteurs et nous rencontrons des problèmes pour enregistrer les images (d'une webcam) sur le disque dur.Enregistrer efficacement les fichiers image sur le disque C#

Nous utilisons trois fils à cette fin:

  • Un fil qui rassemble en permanence l'image capturée de la webcam.
  • Fil d'horloge qui collecte la dernière image et l'envoie dans une méthode d'enregistrement de fichier.
  • Le thread minuteur appelle un troisième thread à enregistrer, afin de ne pas interférer avec la fonctionnalité de thread minuteur principal.

Cela fonctionne très bien pour les basses fréquences. Lorsque nous élevons le FPS à environ 30, nous commençons à perdre des images. Notez que nous avons plusieurs capteurs et pas seulement une webcam. Voilà pourquoi nous utilisons cette architecture et ne pas sauvegarder directement les fichiers à partir du fil de webcam (nous avons besoin de tout garder synchronisé)

C'est la mise en œuvre actuelle de la méthode de sauvegarde:

private void saveImageFrame(Bitmap b, ulong frameID) 
    { 
     string fileSavePath = _path+ "//"; 
     if (b != null) 
     { 
      Task.Factory.StartNew(() => 
      { 
       lock (_lock) 
       { 
        Bitmap toSave = new Bitmap(b); 
        string fileName = fileSavePath + frameID.ToString() + ".bmp"; 
        toSave.Save(fileName); 
       } 
      }); 
     } 
    } 

Nous avons aussi essayé sans le fil de la tâche (pour l'enregistrement) et sans le verrou. Ces deux résultats dans des conditions de course, puisque l'économie prend plus de temps que l'intervalle de temps de la minuterie.

Je suis sûr qu'il existe de meilleures façons de le faire à la fois en termes d'architecture et de fonctions .NET. Toute aide pour améliorer la performance de ce serait grandement appréciée!

+0

Je ne suis pas certain de comprendre le flux de données et les minuteurs. Lorsque le thread de la webcam a assemblé une instance d'image, pourquoi n'effectue-t-il pas une file d'attente immédiate sur le thread de sauvegarde, disons, un BlockingCollection et en crée immédiatement un nouveau pour l'image suivante? –

+0

Puisque nous avons plusieurs capteurs (pas seulement webcam) et que nous aimerions tous avoir la même clé (qui est FrameID dans ce cas), nous voulons qu'ils soient tous sauvés par un composant principal qui fournit cette clé. Espérons que cela clarifie – Omri374

Répondre

4

Il est tout à fait possible que votre disque ne soit pas assez rapide. Un sous-système de disque très rapide peut supporter une vitesse d'écriture de peut-être 100 mégaoctets par seconde, et cela si le fichier est déjà ouvert. Vous essayez de créer 30 fichiers ou plus par seconde, ce qui est en soi une charge assez importante sur le système. Ajoutez le temps requis pour écrire les données et vous augmentez les capacités du système de fichiers.

Ce problème s'aggravera avec l'augmentation du nombre de fichiers dans un dossier. Si vous avez, disons, 1000 fichiers dans le dossier, les choses fonctionnent assez rapidement. Mettez 10 000 fichiers dans un seul dossier et vous constaterez qu'il faut long temps pour créer un nouveau fichier dans ce dossier.

Si vous cognant contre les limites de performance du matériel, vous avez plusieurs moyens d'action:

  1. obtenir plus rapidement le matériel. Un second lecteur dédié, très rapide, par exemple.
  2. Réduisez le nombre de fichiers que vous créez. Peut-être que vous pouvez enregistrer plusieurs images dans un format compressé et ensuite les écrire tous en un seul fichier sur le disque (un fichier zip, par exemple). Ou réduire la fréquence d'images.
  3. Réduisez la quantité de données que vous écrivez (compression ou réduction de la taille de l'image).
+0

Merci pour les conseils.Nous allons regarder dedans. Qu'en est-il de la partie mise en œuvre? Y a-t-il une optimisation que nous pouvons faire ici? nous avons pensé à travailler avec des tableaux d'octets au lieu de Bitmaps et de transformer les images en flux. Pensez-vous que l'un d'entre eux fera du bien? – Omri374

Questions connexes