给定一个来自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 ));
}
答案 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;
}