使用java 8并行处理图像

时间:2018-04-29 15:39:36

标签: java image-processing parallel-processing

我通过计算图像的小(64X64像素)色块上的参数来处理大量4k图像。该任务现在以顺序方式执行,一次一个补丁。下面复制了我的代码片段,向您展示了这个想法。

for (int i = 0; i < imageW / pSize; i++) {
  for (int j = 0; j < imageH / pSize; j++) {

  thisPatch = MatrixUtil.getSubMatrixAsMatrix(image, i * pSize, j * pSize, pSize);
  results[i][j] = computeParamForPatch(thisPatch);
  }
}

我现在需要将其并行化以节省一些时间。如您所见,每个补丁的过程完全独立于其他补丁。为此,我需要使用Map或使用forEachOrdered()来记住每个补丁的位置。不幸的是,我不认为使用地图,像Map<Point, double[][]>这样的东西会被并行化。所以这是我的问题:除了使用会对性能产生负面影响的forEachOrdered()之外,还有其他方法可以并行处理图像吗?

一个解决方案: 我尝试了以下代码(由@DHa建议),它有了显着的改进:

int outputW = imageW / pSize;
int outputH = imageH / pSize;
IntStream.range(0, outputW * outputH).parallel().forEach(i -> {

 int x = (i % outputW);
 int y = (i / outputH);
 tDirectionalities[x][y] = computeDirectionalityForPatch(
                    MatrixUtil.computeParamForPatch(image, x * pSize, y * pSize, pSize));
});

结果:

  • 顺序:15754毫秒
  • 平行:5899毫秒

1 个答案:

答案 0 :(得分:1)

此解决方案使用并行流。

另请参阅How many threads are spawned in parallelStream in Java 8了解如何同时控制在流上工作的线程数量。

    int patchWidth = (int)Math.ceil((double)imageW / pSize);
    int patchHeight = (int)Math.ceil((double)imageH / pSize);

    IntStream.range(0, patchWidth * patchHeight).parallel().forEach(i -> {
        int x = (i % patchWidth);
        int y = (i / patchWidth);

        thisPatch = MatrixUtil.getSubMatrixAsMatrix(image, x * pSize, y * pSize, pSize);
        results[x][y] = computeParamForPatch(thisPatch);
    });