我正在尝试使用特定算法组合 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 因为像素需要完全相同的顺序,或者这毕竟可能吗?
最佳答案
我减少了每次迭代中执行的乘法和除法的次数,所以我想它应该会更快一些。 未测试。
var t = new Vec3f(0);
var u = new Vec3f(0);
var r = new Vec3f(0);
int xIncr = m_BitsPerPixel / 8;
byte* dataBase = bData1Scan0Ptr;
byte* dataDetail = bData2Scan0Ptr;
byte* nextBase = dataBase + bData1.Stride;
byte* nextDetail = dataDetail + bData2.Stride;
byte* dataCombined = bDataCombinedScan0Ptr;
byte* nextCombined = dataCombined + bDataCombined.Stride;
for (int y = 0; y < bData1.Height; ++y)
{
for (int x = 0; x < bData1.Width; ++x)
{
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, y, x] = t; //base
m_VectorImageArray[index + 1, y, x] = u; //detail
m_VectorImageArray[index + 2, y, x] = r; //Combined
dataBase += xIncr;
dataDetail += xIncr;
dataCombined += xIncr;
}
dataBase = nextBase;
nextBase += bData1.Stride;
dataDetail = nextDetail;
nextDetail += bData2.Stride;
dataCombined = nextCombined;
nextCombined += bDataCombined.Stride;
}
m_CombinedBitmap.UnlockBits(bDataCombined);
关于c# - 将位图与自定义算法结合起来的更快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20460722/