From 26d6f24e97583e033c79d8df84b199748fcaa436 Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Tue, 8 Dec 2015 11:32:48 +0100 Subject: Fix and simplify filter convolution --- src/main/java/Filter.java | 61 ++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/main/java/Filter.java b/src/main/java/Filter.java index 7e55f04..d88ea07 100644 --- a/src/main/java/Filter.java +++ b/src/main/java/Filter.java @@ -41,6 +41,32 @@ public final class Filter { return gray[row][col]; } + /** + * Combine neighbour pixels using the given kernel. + * + * @param gray a HxW float array + * @param kernel a MxN float array, with M and N odd + * @param row Y coordinate + * @param col X coordinate + * @return the pixel value + */ + private static float combineNeighbours(float[][] gray, float[][] kernel, int row, int col) { + int kernelWidth = kernel[0].length; + int kernelHeight = kernel.length; + + int rowOffset = row - kernelWidth / 2; // int division + int colOffset = col - kernelHeight / 2; // int division + + float pixelValue = 0; + + for (int kernelRow = 0; kernelRow < kernelHeight; ++kernelRow) + for (int kernelCol = 0; kernelCol < kernelWidth; ++kernelCol) + pixelValue += kernel[kernelRow][kernelCol] + * Filter.at(gray, rowOffset + kernelRow, colOffset + kernelCol); + + return pixelValue; + } + /** * Convolve a single-channel image with specified kernel. * @@ -52,40 +78,11 @@ public final class Filter { int width = gray[0].length; int height = gray.length; - int kernelWidth = kernel[0].length; - int kernelHeight = kernel.length; - - float pixelNeighbors[][] = new float[kernelHeight][kernelWidth]; float[][] filteredImage = new float[height][width]; - for (int row = 0; row < height; ++row) { - for (int col = 0; col < width; ++col) { - - int pixelRow = -kernelHeight / 2; - int pixelCol = -kernelWidth / 2; - - for (int kernelRow = 0; kernelRow < kernelWidth; kernelRow++) { - for (int kernelCol = 0; kernelCol < kernelHeight; kernelCol++) { - pixelNeighbors[kernelRow][kernelCol] = Filter.at(gray, row + pixelRow, col + pixelCol); - - pixelCol += 1; - if (pixelCol > kernelWidth / 2) { - pixelCol = -kernelWidth / 2; - } - } - pixelRow += 1; - if (pixelRow > kernelHeight / 2) { - pixelRow = -kernelHeight / 2; - } - } - - for (int i = 0; i < kernelWidth; i++) { - for (int j = 0; j < kernelHeight; j++) { - filteredImage[row][col] += kernel[i][j] * pixelNeighbors[i][j]; - } - } - } - } + for (int row = 0; row < height; ++row) + for (int col = 0; col < width; ++col) + filteredImage[row][col] = Filter.combineNeighbours(gray, kernel, row, col); return filteredImage; } -- cgit v1.2.3