更快的c#图像处理
Faster c# image processing
我有一个相当广泛的c++图像处理库,我一直在做一个c#项目,但我似乎无法让c#的速度接近c++。我的c++需要149ms来处理将整个图像设置为白色的过程,而c#也需要1071ms。
这是我的c++代码
for (int i = 0; i < 100; i++)
{
for (int y = 0; y < image->height; y++)
{
unsigned char * srcPixel = (unsigned char*)image->mImageData + (y * image->width);
for (int x = 0; x < image->width; x++)
{
srcPixel[0] = 255;
srcPixel[1] = 255;
srcPixel[2] = 255;
srcPixel[3] = 255;
srcPixel += 4;
}
}
}
mImageData是无符号字符的结构
struct mImageData
{
unsigned char alpha;
unsigned char red;
unsigned char green;
unsigned char blue;
}
这就是我正在使用的c代码。这是我能拿到的最快的一个。
frame = new Bitmap(3840, 2160);
BitmapData bitmapData12 = frame.LockBits(new Rectangle(0, 0,
frame.Width, frame.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
var stopwatch = Stopwatch.StartNew();
unsafe
{
int pixelBytes = 4;
int paddingBytes = bitmapData12.Stride % pixelBytes;
byte* location1 = (byte*)bitmapData12.Scan0;
for (int i = 0; i < 100; i++)
{
location1 = (byte*)bitmapData12.Scan0;
for (int y = 0; y < bitmapData12.Height; ++y)
{
for (int x = 0; x < bitmapData12.Width; ++x)
{
location1[0] = 255;
location1[1] = 255;
location1[2] = 255;
location1[3] = 255;
location1 += pixelBytes;
}
location1 += paddingBytes;
}
}
}
stopwatch.Stop();
var miliseconds = stopwatch.ElapsedMilliseconds;
frame.UnlockBits(bitmapData12);
我用ResW=3000和ResH=3000运行了您的代码,以获得900ms的处理时间。我在发布模式下运行它,调试器是分离的。
请注意,此图像包含900万像素,每个像素长4字节。这需要36 MB。我们已经填充了100次,所以总共需要设置36亿字节。我的CPU运行频率为4.5 GHz,所以它在40亿个时钟周期内设置了36亿个字节。
我想说,这对任何语言来说都不算太寒酸。如果我关闭我的开发机器上的所有虚拟机、后台进程和服务器(目前消耗的CPU在5%到20%之间)来运行一个更干净的测量,那么每个时钟周期我会得到几乎正好一个字节的设置。当然,CPU可以做得更好——如果您要求它们执行正确的操作。一次设置一个字节肯定会使速度变慢。
因此,C#确实在不修改算法的情况下尽可能快地完成了这项工作。只是C#拒绝优化代码的字面翻译,而C++可以也会这样做。在我自己的测试中,简单地按照AdamF的建议(使用uint
)已经将时间缩短到了300ms。
我不认为你已经指定了你的ResW/ResH是什么(或者我是盲人),所以你仍然有可能没有以最快的方式运行代码,有些东西干扰了测量。
这是一个有点脏的解决方案,但如果图像结构的大小始终相同,那么也许您可以尝试以这种方式进行优化:
在我的测试中,速度从大约1100毫秒提高到750毫秒
unsafe
{
int width = bitmapData12.Width;
for (int y = 0; y < bitmapData12.Height; ++y)
{
UInt32* location1 = (UInt32*) (bitmapData12.Scan0 + y*bitmapData12.Stride);
for (int x = 0; x < width; ++x)
location1[x] = UInt32.MaxValue;
}
}
- Qt中的RGB图像处理
- 有关图像处理应用程序的硬件和软件安全性的建议
- C++灰度图像处理
- CUDA 速度比预期慢 - 图像处理
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- 矢量化图像处理
- OpenGL (ES) 图像处理C++
- C++:灰度位图标题和实时绘画+opencv图像处理
- 在 Unity 中C++使用后台线程进行图像处理会导致崩溃
- 线程会影响树莓派的图像处理性能吗?
- 低性能 – 补丁匹配.GPU 上的图像处理 (CUDA)
- 如何使用OpENCV解决图像处理摄像头IO延迟
- 从单线程到多线程图像处理
- 如何使用win IoT在Raspberry Pi上的相机中显示视频流以及一些图像处理
- C 图像处理(来自单元格的裁剪图像)
- C++中的二进制图像处理
- 实时图像处理:HSV图像中的噪声(openCV)
- C 图像处理数据块进入数组 /指针
- OPENCV图像处理,向量下标超出范围
- C++图像处理 - 将图像文件读入 2D 数组