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);
}
评论