2013-09-04 3 views
0

Мы разрабатываем инструмент для сбора данных с несколькими датчиками, и у нас возникают проблемы с сохранением изображений (с веб-камеры) на жесткий диск.эффективно сохраняет файлы изображений на диск C#

Мы используем три темы для этой цели:

  • Одна нить, которая непрерывно собирает захваченное изображение с веб-камеры.
  • Поток таймера, который собирает последнее изображение и отправляет его в метод сохранения файла.
  • Поток таймера вызывает третий поток для сохранения, чтобы не мешать функциям потока основного таймера.

Это нормально работает для низких частот. Когда мы поднимаем FPS примерно до 30, мы начинаем проигрывать изображения. Обратите внимание, что у нас есть несколько датчиков, а не только веб-камера. Вот почему мы используем эту архитектуру, а не напрямую сохранять файлы с веб-камерой нити (мы должны держать все синхронизируются)

Это текущая реализация метода сохранения:

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); 
       } 
      }); 
     } 
    } 

Мы также пытались без поток задач (для сохранения) и без блокировки. Эти два результата приводят к условиям гонки, поскольку экономия занимает больше времени, чем временной интервал таймера.

Я уверен, что есть лучшие способы сделать это как с точки зрения архитектуры, так и с помощью функций .NET. Любая помощь в повышении эффективности этого будет очень признательна!

+0

Не уверен, что я понимаю поток данных и таймеры. Когда поток веб-камеры собрал экземпляр изображения, почему он не сразу ставит очередь на экземпляр в поток сохранения, скажем, в BlockingCollection и сразу же создает новый для следующего изображения? –

+0

Поскольку у нас есть несколько датчиков (а не только веб-камера), и мы хотели бы, чтобы все они имели один и тот же ключ (в данном случае это FrameID), мы хотим, чтобы все они были сохранены одним основным компонентом, который предоставляет этот ключ. Надеюсь, это уточнит – Omri374

ответ

4

Вполне возможно, что ваш диск просто не достаточно быстро. Очень быстрая дисковая подсистема может поддерживать скорость записи, возможно, 100 мегабайт в секунду, и это если у вас уже открыт файл. Вы пытаетесь создать 30 или более файлов в секунду, что само по себе является довольно большой нагрузкой на систему. Добавьте время, необходимое для записи данных, и вы нажимаете на возможности файловой системы.

Эта проблема будет ухудшаться по мере увеличения количества файлов в папке. Если у вас, скажем, 1000 файлов в папке, все работает довольно быстро. Поместите 10 000 файлов в одну папку, и вы обнаружите, что для создания нового файла в этой папке требуется .

Если вы натыкаясь против ограничений производительности аппаратного обеспечения, у вас есть несколько вариантов действий:

  1. получить быстрее оборудование. Например, второй, очень быстрый, выделенный диск.
  2. Уменьшить количество создаваемых файлов. Возможно, вы можете сохранить несколько изображений в сжатом формате, а затем записать их как отдельный файл на диск (например, zip-файл). Или уменьшите частоту кадров.
  3. Уменьшите объем данных, которые вы пишете (посредством сжатия или уменьшения размера изображения).
+0

Спасибо за советы.Мы рассмотрим это. Что относительно части реализации? есть ли какая-нибудь оптимизация, которую мы можем здесь сделать? мы думали работать с байтовыми массивами вместо растровых изображений и превращать изображения в потоки. Считаете ли вы, что любой из них принесет пользу? – Omri374

Смежные вопросы