代码之家  ›  专栏  ›  技术社区  ›  Azim

使用java 8并行处理图像

  •  2
  • Azim  · 技术社区  · 6 年前

    我正在通过计算图像小块(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 ms
    • 平行:5899毫秒
    1 回复  |  直到 6 年前
        1
  •  2
  •   DHa    6 年前

    此解决方案使用并行流。

    另请参见 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);
        });