位图的平均颜色

Average color of bitmap

我正在寻找一种极其有效和准确的方法来确定位图的平均 RGB 值。我目前有一种带位锁的方法,它逐像素进行,在 30Hz 时占用我 CPU 的大约 25%。

我已经设法通过查看每三个像素将其降低到 ~15%,但是我相信有更好的方法。我也尝试过将计算转移到 GPU (Nvidia CUDA),但由于我在 GPU 编程方面缺乏经验,只花了更长的时间。

我考虑过应用模糊之类的事情,但这不会减少像素数量,因此不会影响计算。

我想听听您对这个有趣话题的看法。

您可以开发一个 c++ dll,使用内部函数与 SIMD optimized/vectorized 代码进行相同的计算。那么 cpu 即使使用百分比相同,使用效率也会更高。处理未对齐的 header 部分,然后使用更快的内函数处理剩余的对齐部分。

如果这还不够,请尝试仅将一半甚至四分之一的图像移动到 GPU,因为 pci-e 是瓶颈。

流水线还有助于隐藏复制到 gpu 的一些延迟,但使用更多 CPU 但完成速度更快,因此使用的总周期更少。

如果位图已经在 cpu 缓存中,它应该能够在 GPU 处理 "mapped" 内存块(另一个位图或同一位图的一部分)时同时处理它,而不会出现 RAM 瓶颈.如果要流式传输数据,请不要复制到 GPU。让 GPU 使用适当的访问函数或标志将其映射到自己的控制器上。

"mapping" 的起点可以是位图字节数组的第一个 4096 地址元素的倍数。

如果你有 integrated-gpu,试试 opencl,因为它更接近 RAM。


对于纯 C# 解决方案,请尝试多个累加器以更好地使用 cpu 管道。在不安全的上下文中使用它们。按 int 或 long 读取,而不是字节。然后使用 bithacks 处理它,除非 C# 已经在进行矢量化。


扫描平均值不使用乘法单位。所以你可以用一些交错的代码或做异步来增加东西。也许你可以同时混合一些其他位图?


c[i]=a[i]+b[i]

与简单的 C# one-liner 相比,完全优化的 gpgpu 方法快 18 倍。我正在使用 Visual Studio 2015 Community Edition(发布模式下的项目和 64 位目标)。这是一款低端笔记本电脑,使用 Intel HD-400 iGPU(600MHz) 和 C3060(1.6GHz)(单通道 RAM),CPU 使用率是 %50ish 而不是纯 C# 的 %70ish。