>我使用以下循环来计算两个相同大小的图像之间的差异:
static double calculateError(BufferedImage canvas, BufferedImage ideal) {
double error = 0.0D;
for (int x = 0; x < Polygonizer.WIDTH; x++) {
for (int y = 0; y < Polygonizer.HEIGHT; y++) {
Color c1 = new Color(canvas.getRGB(x, y));
Color c2 = new Color(ideal.getRGB(x, y));
error += Math.abs(c1.getRed() - c2.getRed());
error += Math.abs(c1.getGreen() - c2.getGreen());
error += Math.abs(c1.getBlue() - c2.getBlue());
}
}
return error;
}
它工作得很好,但相当慢,我不知道如何让它走得更快。
我已经尝试使用ExecutorService
没有好处,我可以使用一些建议。
编辑:谢谢大家。这是优化版本:
private static int APPROXIMATION = 1;
private static int[] idealData;
public static final void setIdeal(BufferedImage ideal) {
int[] rawData = ((DataBufferInt)ideal.getRaster().getDataBuffer()).getData();
idealData = new int[rawData.length * 3];
int counter = 0;
for (int i = 0; i < rawData.length * 3; i += 3) {
idealData[i] = (rawData[counter] & 0xFF);
idealData[i + 1] = (rawData[counter] >> 8 & 0xFF);
idealData[i + 2] = (rawData[counter] >> 16 & 0xFF);
counter++;
}
}
static double calculateError(BufferedImage canvas) {
long error = 0;
final int[] canvasData = ((DataBufferInt)canvas.getRaster().getDataBuffer()).getData();
int counter = 0;
for (int i = 0; i < canvasData.length; i += APPROXIMATION) {
error += Math.abs((canvasData[i] & 0xFF) - (idealData[counter]));
error += Math.abs((canvasData[i] >> 8 & 0xFF) - (idealData[counter + 1]));
error += Math.abs((canvasData[i] >> 16 & 0xFF) - (idealData[counter + 2]));
counter += 3 * APPROXIMATION;
}
return error;
}
如果您知道BufferedImage
的格式,例如,因为您使用构造函数实例化了它们,那么还有一种更快的方法。
如果BufferedImage
的类型为 TYPE_3BYTE_BGR
,请执行以下操作:
byte[] canvasData = ((DataBufferByte)canvas.getRaster().getDataBuffer()).getData();
byte[] idealData = ((DataBufferByte)ideal .getRaster().getDataBuffer()).getData();
int error = 0;
for (int i = 0; i < canvasData.length; i++) {
error += Math.abs((canvasData[i] & 0xFF) - (idealData[i] & 0xFF));
}
如果 BufferedImage
的类型为 TYPE_INT_RGB
,请执行以下操作:
int[] canvasData = ((DataBufferInt)canvas.getRaster().getDataBuffer()).getData();
int[] idealData = ((DataBufferInt)ideal .getRaster().getDataBuffer()).getData();
int error = 0;
for (int i = 0; i < canvasData.length; i++) {
error += Math.abs((canvasData[i] & 0xFF) - (idealData[i] & 0xFF));
error += Math.abs((canvasData[i] >> 8 & 0xFF) - (idealData[i] >> 8 & 0xFF));
error += Math.abs((canvasData[i] >> 16 & 0xFF) - (idealData[i] >> 16 & 0xFF));
}
(免责声明:未经测试的代码,但我经常做一些事情,我很有信心(
你为每个点创建两个Color
实例,这是相当多的。有一种更快的方法可以从 int 中提取 RGB(查看 Color
的来源(。
更重要的是,你一个接一个地提取点,这通常非常慢(因为它们在BufferedImage
中可能以不同的方式组织(。调用一个方法,一次将更多提取到int[]
中。
AFAIK有一种方法可以让图像计算结果,这可能仍然更快。
我已经尝试使用
ExecutorService
没有好处,我真的可以使用一些建议。
这也应该有所帮助,但仅限于您拥有的内核数量。但是,使用平行流通常要简单得多。但这是一个不同的故事(问题(。