661图片平滑器
描述
包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。
实例
输入:
[[1,1,1],
[1,0,1],
[1,1,1]]
输出:
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): 平均(3/4) = 平均(0.75) = 0
对于点 (0,1), (1,0), (1,2), (2,1): 平均(5/6) = 平均(0.83333333) = 0
对于点 (1,1): 平均(8/9) = 平均(0.88888889) = 0
注意
- 给定矩阵中的整数范围为 [0, 255]。
- 矩阵的长和宽的范围均为 [1, 150]。
题解
本题属于硬算的,唯一需要注意的是边界情况和深度或者宽度为1时的特殊处理.
代码里使用了查找表,因为灰度的分布是有限的,那么九个元素的sum
也就是有限的,往往图像的像素个数远多于sum的种类,就可以把已经计算过的sum
存起来,需要时进行查找.
static public int[][] imageSmoother(int[][] M) {
int[] findTable = new int[256*9];
int W = M[0].length;
int H = M.length;
int[][] result = new int[H][W];
int sum = 0;
if (Math.max(W,H) <=1)
return M;
if (W == 1){
for (int i = 0; i < H; i++) {
if (i == 0)
result[i][0] = (M[i][0] + M[i+1][0])/2;
else if (i == H-1)
result[i][0] = (M[i][0] + M[i-1][0])/2;
else
result[i][0] = (M[i][0] + M[i-1][0] + M[i+1][0])/3;
}
return result;
}
if (H == 1){
for (int i = 0; i < W; i++) {
if (i == 0)
result[0][i] = (M[0][i] + M[0][i+1])/2;
else if (i == W-1)
result[0][i] = (M[0][i] + M[0][i-1])/2;
else
result[0][i] = (M[0][i] + M[0][i+1] + M[0][i-1])/3;
}
return result;
}
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if ((i == 0)&&(j == 0))
result[i][j] = (M[i][j]+M[i+1][j]+M[i][j+1]+M[i+1][j+1])/4;
else if ((i == 0)&&(j == W-1))
result[i][j] = (M[i][j]+M[i+1][j]+M[i][j-1]+M[i+1][j-1])/4;
else if (i == 0)
result[i][j] = (M[i][j]+M[i][j-1]+M[i][j+1]+M[i+1][j]+M[i+1][j-1]+M[i+1][j+1])/6;
else if ((i == H-1)&&(j == 0))
result[i][j] = (M[i][j]+M[i-1][j]+M[i][j+1]+M[i-1][j+1])/4;
else if ((i == H-1)&&(j == W-1))
result[i][j] = (M[i][j]+M[i-1][j]+M[i][j-1]+M[i-1][j-1])/4;
else if (i == H-1)
result[i][j] = (M[i][j]+M[i][j-1]+M[i][j+1]+M[i-1][j]+M[i-1][j-1]+M[i-1][j+1])/6;
else if (j == 0)
result[i][j] = (M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j+1]+M[i-1][j+1]+M[i+1][j+1])/6;
else if (j == W-1)
result[i][j] = (M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j-1]+M[i-1][j-1]+M[i+1][j-1])/6;
else {
sum = M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j+1]+M[i-1][j+1]+M[i+1][j+1]+M[i][j-1]+M[i-1][j-1]+M[i+1][j-1];
if (findTable[sum] == 0){
findTable[sum] = sum/9;
result[i][j] = findTable[sum];
} else
result[i][j] = findTable[sum];
}
}
}
return result;
}