在Java中计算两个ARGB整数差异的最快方法?

时间:2011-04-14 10:19:23

标签: java colors

给定一个来自DataBuffer的int,其中包含带有掩码的ARGB数据

A = 0xFF000000 R = 0xFF0000 G = 0xFF00 B = 0xFF

我正在做以下事情,但想知道Java中是否有更快的方法?

        DataBuffer db1 = img1.getData().getDataBuffer();
        DataBuffer db2 = img2.getData().getDataBuffer();

        int x, y;
        int totalDiff = 0;
        for (int i = 0; i < WIDTH * HEIGHT; ++i) {
            x = db1.getElem(i);
            y = db2.getElem(i);

            totalDiff += Math.abs((x & 0xFF) - (y & 0xFF))
                       + Math.abs(((x & 0xFF00) >> 8) - ((y & 0xFF00) >> 8))
                       + Math.abs(((x & 0xFF0000) >> 16) - ((y & 0xFF0000) >> 16 ));
        }

3 个答案:

答案 0 :(得分:3)

如果您确实需要加速,可以检查DataBuffer的类型并为具体类型提供优化代码,以便将调用保存到getElem(i)。这会稍微加快你的代码。

这样的事情:

    DataBuffer db1 = img1.getData().getDataBuffer();
    DataBuffer db2 = img2.getData().getDataBuffer();

    int totalDiff = 0;
    int x, y;
    if (db1 instanceof DataBufferInt && db2 instanceof DataBufferInt) {
        int[] data1 = ((DataBufferInt) db1).getData();
        int[] data2 = ((DataBufferInt) db2).getData();
        for (int i = 0; i < WIDTH * HEIGHT; ++i) {
            x = data1[i];
            y = data2[i];

            totalDiff += Math.abs((x & 0xFF) - (y & 0xFF))
                + Math.abs(((x & 0xFF00) >> 8) - ((y & 0xFF00) >> 8))
                + Math.abs(((x & 0xFF0000) >> 16) - ((y & 0xFF0000) >> 16));
        }
    } else {
        for (int i = 0; i < WIDTH * HEIGHT; ++i) {
            x = db1.getElem(i);
            y = db2.getElem(i);

            totalDiff += Math.abs((x & 0xFF) - (y & 0xFF))
                    + Math.abs(((x & 0xFF00) >> 8) - ((y & 0xFF00) >> 8))
                    + Math.abs(((x & 0xFF0000) >> 16) - ((y & 0xFF0000) >> 16));
        }
    }

修改 另一个可以为您带来更高速度的想法。如果这只是一种启发式方法,那么计算图像的某种“下采样”版本的差异就足够了。将++i替换为i+=10并将速度提高10倍。当然,如果这有意义取决于图像的类型。

修改 在一条评论中你提到它是GA的适应度函数......在这种情况下,它可能足以从你的图像中获取100个(或仅10个)随机位置并比较那些位置的像素。增加的速度很可能超过准确性的损失。

答案 1 :(得分:1)

同意@Arne。

您还可以删除轮班权

(x & 0xFF0000) >> 16) - ((y & 0xFF0000) >> 16 ). 

你知道abs(XX0000 - YY0000)只会在0-255范围内。

如果您可以建议您要确定的是什么,这将有所帮助?

也就是说,像素信息可以更好地存储到你试图实现的内容,例如作为色度(YUV,YCrCb)吗?

答案 2 :(得分:0)

如果你可以接受计算平方和,那就更快了:

    for (int i = 0; i < WIDTH * HEIGHT; ++i) {
        x = db1.getElem(i);
        y = db2.getElem(i);
        int dr = ((x & 0xFF0000) >> 16) - ((y & 0xFF0000) >> 16 );
        int dg = ((x & 0xFF00) >> 8) - ((y & 0xFF00) >> 8);
        int db = (x & 0xFF) - (y & 0xFF);
        totalDiff += dr*dr + dg*dg + db*db;
    }