【发布时间】:2013-12-25 23:28:10
【问题描述】:
我正在尝试将 2 张图像与某种算法结合起来。但在目前的状态下,它太慢了。合并两张 512x512 图像大约需要 70 毫秒。这没关系,但是一旦图像变大,合并它们所需的时间就会增加。
这是c#中的代码(Fast work with Bitmaps in C#)
var t = new Vec3f(0);
var u = new Vec3f(0);
var r = new Vec3f(0);
for (int i = 0; i < bData1.Height; ++i)
{
for (int j = 0; j < bData1.Width; ++j)
{
byte* dataBase = bData1Scan0Ptr + i * bData1.Stride + j * m_BitsPerPixel / 8;
byte* dataDetail = bData2Scan0Ptr + i * bData2.Stride + j * m_BitsPerPixel / 8;
byte* dataCombined = bDataCombinedScan0Ptr + i * bDataCombined.Stride + j * m_BitsPerPixel / 8;
t.x = (dataBase[2] / 255.0f) * 2.0f - 1.0f;
t.y = (dataBase[1] / 255.0f) * 2.0f - 1.0f;
t.z = (dataBase[0] / 255.0f) * 2.0f;
u.x = (dataDetail[2] / 255.0f) * -2.0f + 1.0f;
u.y = (dataDetail[1] / 255.0f) * -2.0f + 1.0f;
u.z = (dataDetail[0] / 255.0f) * 2.0f - 1.0f;
r = t * t.Dot(u) - u * t.z;
r.Normalize();
//Write data to our new bitmap
dataCombined[2] = (byte)Math.Round((r.x * 0.5f + 0.5f) * 255.0f);
dataCombined[1] = (byte)Math.Round((r.y * 0.5f + 0.5f) * 255.0f);
dataCombined[0] = (byte)Math.Round((r.z * 0.5f + 0.5f) * 255.0f);
m_VectorImageArray[index, i, j] = t; //base
m_VectorImageArray[index + 1, i, j] = u; //detail
m_VectorImageArray[index + 2, i, j] = r; //Combined
}
}
m_CombinedBitmap.UnlockBits(bDataCombined);
因为我想加快速度,我还尝试制作一个 c++ dll 并使用 DLLImport 将其加载到我的 C# 项目中。我已经实现了这个矢量类 (http://fastcpp.blogspot.co.uk/2011/12/simple-vector3-class-with-sse-support.html),认为它会显着提高速度,但不幸的是它只快了大约 10 毫秒。
我想让这更快,因为我想实时更新图像(循环存储在 m_VectorImageArray 中的向量)。
问题与读取/写入位图无关,而与算法本身有关。我认为我不能使用parallel.for,因为像素需要以完全相同的顺序排列,或者这是否可能?
【问题讨论】:
-
你可以并行化这个..你没有处理不同的数据集。将图像的每一部分分割成块并在它们自己的线程上处理它们。假设您将它们适当地拆分......就算法而言,您不应该遇到任何线程问题。
-
你分析过它吗?你知道瓶颈在哪里吗?
-
你能提供一组图像来测试和适当的代码来做完整的测试吗?
-
@Simon Whitehead 谢谢!我将不得不与所有其他更改一起尝试这个!
-
@acfrancis 我已经对其进行了分析,但因为这是我第一次真正需要优化某些东西,我可能误读了分析器给我的信息。 profiler 我认为这意味着大部分时间都花在了我的 Vec3f 课程上,所以我尝试优化那个。谢谢!
标签: c# .net algorithm image-processing