【问题标题】:efficiently saving image files to disk c#有效地将图像文件保存到磁盘 c#
【发布时间】:2013-09-04 07:10:15
【问题描述】:

我们正在开发一种多传感器采集工具,但在将图像(来自网络摄像头)保存到硬盘时遇到了问题。

我们为此使用了三个线程:

  • 一个线程不断地从网络摄像头收集捕获的图像。
  • 收集最后一张图像并将其发送到文件保存方法的计时器线程。
  • 定时器线程调用第三个线程进行保存,以免干扰主定时器线程功能。

这适用于低频。当我们将 FPS 提高到 30 左右时,我们开始丢失图像。请注意,我们有多个传感器,而不仅仅是一个网络摄像头。这就是我们使用这种架构而不是直接从网络摄像头线程保存文件的原因(我们需要保持一切同步)

这是 save 方法的当前实现:

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 功能方面都有更好的方法来做到这一点。任何有助于提高性能的帮助将不胜感激!

【问题讨论】:

  • 不确定我是否了解数据流和计时器。当网络摄像头线程组装了一个图像实例时,为什么它不立即将该实例排队到保存线程上,例如 BlockingCollection 并立即为下一张图像创建一个新实例?
  • 由于我们有多个传感器(不仅仅是网络摄像头)并且我们希望它们都具有相同的密钥(在这种情况下是 FrameID),我们希望它们都由一个主要组件保存提供此密钥。希望这可以澄清

标签: c# multithreading bitmap save sensor-fusion


【解决方案1】:

很可能是您的磁盘不够快。一个非常快的磁盘子系统可以维持每秒 100 兆字节的写入速度,前提是您已经打开了文件。您尝试每秒创建 30 个或更多文件,这本身对系统来说是一个相当大的负载。加上写入数据所需的时间,您正在推动文件系统的功能。

随着文件夹中文件数量的增加,这个问题会变得更糟。例如,如果文件夹中有 1,000 个文件,那么一切都会很快进行。将 10,000 个文件放在一个文件夹中,您会发现在该文件夹中创建一个新文件需要 很长时间

如果您遇到硬件性能限制,您可以采取多种措施:

  1. 获得更快的硬件。例如,第二个非常快速的专用驱动器。
  2. 减少您创建的文件数量。也许您可以以压缩格式保存多个图像,然后将它们作为单个文件写入磁盘(例如 zip 文件)。或者降低帧速率。
  3. 减少写入的数据量(通过压缩或减小图像大小)。

【讨论】:

  • 感谢您的提示。我们会调查的。执行部分呢?我们可以在这里做任何优化吗?我们考虑使用字节数组而不是位图,并将图像转换为流。你认为这些有什么好处吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2012-01-12
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2013-12-19
相关资源
最近更新 更多