正如 emgu 网站所说,主要有两种策略:
安全(慢)方式
假设您正在处理Image<Bgr, Byte>。
您可以通过调用获取第y行第x列的像素
Bgr color = img[y, x];
在第y行第x列设置像素也很简单
img[y,x] = color;
快捷方式
图像像素值存储在 3D 数组的 Data 属性中。
好的,这是真的,但没有说明如何在真实场景中做到这一点。所以让我们看一些工作代码,然后讨论性能和优化:
Image<Bgr, Byte> original = newImage<Bgr, byte>(1024, 768);
Stopwatch evaluator = newStopwatch();
int repetitions = 20;
Bgr color = newBgr(100, 40, 243);
evaluator.Start();
for (int run = 0; run < repetitions; run++)
{
for (int j = 0; j < original.Cols; j++)
{
for (int i = 0; i < original.Rows; i++)
{
original[i, j] = color;
}
}
}
evaluator.Stop();
Console.WriteLine("Average execution time for {0} iteration \n using column per row access: {1}ms\n", repetitions, evaluator.ElapsedMilliseconds / repetitions);
所以这是使用设置图像像素的安全慢速方式运行 20 次后的平均运行时间
在我的机器上需要 1021ms...
因此,循环和设置像素数等于 1024*768 的平均时间为 1021 毫秒。我们可以通过逐行循环来做得更好
所以让我们稍微重构一下我们的代码,让我们使用更快的方式直接使用 Image.Data 属性:
evaluator.Reset();
evaluator.Start();
for (int run = 0; run < repetitions; run++)
{
for (int i = 0; i < original.Rows; i++)
{
for (int j = 0; j < original.Cols; j++)
{
original.Data[i, j, 0] = 100;
original.Data[i, j, 1] = 40;
original.Data[i, j, 2] = 243;
}
}
}
evaluator.Stop();
Console.WriteLine("Average execution time for {0} iterations \n using Data property: {1}ms\n", repetitions, evaluator.ElapsedMilliseconds / repetitions);
在我的机器上需要 519ms。
因此,我们获得了 50% 的性能提升。执行时间减少了两倍。
所以仔细查看代码,记住我们使用的是 C#,我们可以做一个小的改变,这将再次大大提高我们的图像像素设置性能...... 我们不应该在循环中使用 c# 属性! !!
evaluator.Reset();
evaluator.Start();
byte[,,] data = original.Data;
for (int run = repetitions - 1; run >= 0; run--)
{
for (int i = original.Rows - 1; i >= 0; i--)
{
for (int j = original.Cols - 1; j >= 0; j--)
{
data[i, j, 0] = 100;
data[i, j, 1] = 40;
data[i, j, 2] = 243;
}
}
}
evaluator.Stop();
使用这段最新的代码,由于正确使用 C# 语言,您将获得巨大的性能提升(73ms)。