c# - 将位图与自定义算法结合起来的更快方法?

标签 c# .net algorithm image-processing

我正在尝试使用特定算法组合 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/

相关文章:

c# - 如何从*代码隐藏*强制 IE 9 进入 IE8 兼容模式

c# - 将 DataGridColumnHeader 与所选行的属性绑定(bind)

c# - ASP.Net:在后面的代码中添加额外的代码到 Page_Load

c++ - 在 C++ 中通过网格/矩阵找到成本优化路径

algorithm - 分离轴测试,检测旋转矩形是否与另一个平面矩形重叠

c# - 数组到字典

c# - Active Directory 添加用户属性

.net - 查找并替换字符串中的特定字符

.net - 使用 C# 播放流中的音频

objective-c - 在不相交的集合数据结构中实现路径压缩?