开发者

Fastest method to calculate difference between two ARGB ints in Java?

Given an int from a DataBuffer which has ARGB data packed in it with the masks

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

I'm doing the following but wonder if there isn't a faster method in Java?

        DataBuffer db1 = img1.getData(开发者_Python百科).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 ));
        }


If you really need the speed up you might to check the type of DataBuffer and provide optimized code for the concrete type such that you save the calls to getElem(i). This will speed up your code a little bit.

Something like this:

    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));
        }
    }

Edit: Another idea that would bring you a MUCH higher speed up. If this is just a heuristic it might be enough to calculate the difference of a somewhat "downsampled" version of your images. Replace ++i through i+=10 and gain a speed up by factor 10. Of course if this makes sense depends on the types of your images.

Edit: In one comment you mentioned it's a fitness function for a GA ... in this case it might be enough to grab 100 (or just 10?) random locations from your images and compare the pixels at that locations. The gained speed up will most probably outdo the loss in accuracy.


Agree with @Arne.

You could also remove the shift rights

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

You know that abs(XX0000 - YY0000) is only going to be in the range 0-255.

It would help if you could suggest what it is you are trying to determine?

That is, can the pixel information be store more conducively to what you are trying to acheive, for example as chrominance (YUV, YCrCb)?


If calculating the sum of squares is acceptable for you, it is faster:

    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;
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜