C# 位图的平均颜色

C# 位图的平均颜色,c#,colors,bitmap,processing-efficiency,C#,Colors,Bitmap,Processing Efficiency,我正在寻找一种非常有效和准确的方法来确定位图的平均RGB值。我目前有一种使用位锁的方法,它逐像素运行,以30Hz的频率占用大约25%的CPU 通过每三分之一像素的观察,我成功地将其降低到15%,但我相信有更好的方法。我也尝试将计算转移到GPU(Nvidia CUDA),但由于我在GPU编程方面缺乏经验,只花了更长的时间 我曾经考虑过一些事情,比如应用模糊,但是这不会减少像素数量,因此不会影响计算 我想听听您对这个有趣的话题的看法。 < P>您可以开发一个C++的DLL,使用SIMD优化/矢量化代

我正在寻找一种非常有效和准确的方法来确定位图的平均RGB值。我目前有一种使用位锁的方法,它逐像素运行,以30Hz的频率占用大约25%的CPU

通过每三分之一像素的观察,我成功地将其降低到15%,但我相信有更好的方法。我也尝试将计算转移到GPU(Nvidia CUDA),但由于我在GPU编程方面缺乏经验,只花了更长的时间

我曾经考虑过一些事情,比如应用模糊,但是这不会减少像素数量,因此不会影响计算


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

< P>您可以开发一个C++的DLL,使用SIMD优化/矢量化代码,使用内联做同样的计算。即使在相同的使用率下,cpu的使用率也会更高。处理未对齐的收割台零件,然后使用更快的内在功能处理剩余的对齐零件

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

流水线也有助于隐藏复制到gpu的一些延迟,但会占用更多CPU,但完成得更快,所以使用的总周期更少

如果位图已经在cpu缓存中,那么它应该能够在GPU处理“映射”内存磁贴(另一个位图或同一位图的一部分)时并发地处理它,而不会阻塞RAM。如果数据是流式传输的,不要复制到GPU。让GPU使用适当的访问函数或标志将其映射到自己的控制器上

“映射”的起点可以是位图字节数组4096寻址元素的第一个倍数

如果你有一个集成的gpu,试试opencl,因为它更接近RAM


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


扫描平均值不使用乘法单位。因此,您可以使用一些交错代码或异步操作来实现乘法。也许你可以同时混合一些其他位图



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

您的问题太宽泛了,而且表述模糊。你说你试着看每3个像素,但那不是平均像素值。构造一个图像,使用该计算结果会产生与真实平均值截然不同的平均值,这很简单。最终,您必须将每个值相加,然后除以总和。这就是平均数。使用CUDA可能改善,也可能不会改善;将字节移动到显卡所需的时间与扫描和添加RAM所需的时间一样长。还要注意,CPU使用年限对效率没有任何影响……它只告诉您在算法运行时使用的可用CPU的比例。使用25%CPU且耗时10秒的算法的效率低于使用25%CPU且仅耗时5秒的算法。重要的是总的计算时间。多线程代码可以通过使用更多的CPU时间来提高吞吐量,但其本身并不一定更高效。如果每3个像素检查一次inly是可以接受的,那么也可以将其缩小到5-10%吗?
c[i]=a[i]+b[i]