Параллельная обработка изображения с использованием Java 8 - PullRequest
0 голосов
/ 29 апреля 2018

Я обрабатываю большое количество изображений 4k, вычисляя параметр для небольших (64X64 пикселей) участков изображения. Задача теперь выполняется последовательно, по одному патчу за раз. Ниже приведен фрагмент моего кода, чтобы показать вам идею.

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 голосов
/ 29 апреля 2018

В этом решении используется параллельный поток.

См. Также Сколько потоков порождено в parallelStream в 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);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...