public static BufferedImage denoiseImage(BufferedImage originalImage) { int width = originalImage.getWidth(); int height = originalImage.getHeight();
byte[][] imageArray = convertTo2DArray(originalImage);
int patchSize = 3; int searchWindowSize = 11; double smoothingParameter = 10.0; double distanceThreshold = 30.0;
IntStream.range(0, height).parallel().forEach(y -> { IntStream.range(0, width).parallel().forEach(x -> { byte[][] patch = getPatch(imageArray, x, y, patchSize);
double weightSum = 0.0; double result = 0.0;
int halfSearch = searchWindowSize / 2;
for (int i = -halfSearch; i <= halfSearch; i++) { for (int j = -halfSearch; j <= halfSearch; j++) { int newX = x + i; int newY = y + j;
if (isValidCoordinate(newX, newY, width, height)) { byte[][] similarPatch = getPatch(imageArray, newX, newY, patchSize);
double distance = calculateDistance(patch, similarPatch);
if (distance > distanceThreshold) { continue; }
double weight = Math.exp(-distance / (2.0 * smoothingParameter * smoothingParameter)); weightSum += weight;
result += weight * getValue(imageArray, newX, newY); } } }
result /= weightSum;
imageArray[y][x] = (byte) result; }); });
// 将二维数组转换为BufferedImage return convertToBufferedImage(imageArray); }
// 添加一个用于计算距离的辅助方法 private static double calculateDistance(byte[][] patch1, byte[][] patch2) { double sum = 0.0; for (int i = 0; i < patch1.length; i++) { for (int j = 0; j < patch1[0].length; j++) { sum += Math.pow(patch1[i][j] - patch2[i][j], 2); } } return sum / (patch1.length * patch1[0].length); }
评论