0661-图片平滑器

Raphael Liu Lv10

图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。

每个单元格的 ** 平均灰度** 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9
个单元格的平均值)。

如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。

给你一个表示图像灰度的 m x n 整数矩阵 img ,返回对图像的每个单元格平滑处理后的图像 。

示例 1:

**输入:** img = [[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

示例 2:

**输入:** img = [[100,200,100],[200,50,200],[100,200,100]]
**输出:** [[137,141,137],[141,138,141],[137,141,137]]
**解释:**
对于点 (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137
对于点 (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141
对于点 (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138

提示:

  • m == img.length
  • n == img[i].length
  • 1 <= m, n <= 200
  • 0 <= img[i][j] <= 255

方法一:遍历

思路和算法

按照题目的要求,我们直接依次计算每一个位置平滑处理后的结果即可。

具体地,对于位置 (i,j),我们枚举其周围的九个单元是否存在,对于存在的单元格,我们统计其数量 num 与总和 sum,那么该位置平滑处理后的结果即为 \Big\lfloor\dfrac{\textit{sum}}{\textit{num}}\Big\rfloor。

代码

[sol1-C++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
int m = img.size(), n = img[0].size();
vector<vector<int>> ret(m, vector<int>(n));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int num = 0, sum = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < m && y >= 0 && y < n) {
num++;
sum += img[x][y];
}
}
}
ret[i][j] = sum / num;
}
}
return ret;
}
};
[sol1-Java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int[][] imageSmoother(int[][] img) {
int m = img.length, n = img[0].length;
int[][] ret = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int num = 0, sum = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < m && y >= 0 && y < n) {
num++;
sum += img[x][y];
}
}
}
ret[i][j] = sum / num;
}
}
return ret;
}
}
[sol1-C#]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Solution {
public int[][] ImageSmoother(int[][] img) {
int m = img.Length, n = img[0].Length;
int[][] ret = new int[m][];
for (int i = 0; i < m; i++) {
ret[i] = new int[n];
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int num = 0, sum = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < m && y >= 0 && y < n) {
num++;
sum += img[x][y];
}
}
}
ret[i][j] = sum / num;
}
}
return ret;
}
}
[sol1-C]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int** imageSmoother(int** img, int imgSize, int* imgColSize, int* returnSize, int** returnColumnSizes){
int m = imgSize, n = imgColSize[0];
int ** ret = (int **)malloc(sizeof(int *) * m);
*returnColumnSizes = (int *)malloc(sizeof(int) * m);
for (int i = 0; i < m; i ++) {
ret[i] = (int *)malloc(sizeof(int) * n);
memset(ret[i], 0, sizeof(int) * n);
(*returnColumnSizes)[i] = n;
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int num = 0, sum = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < m && y >= 0 && y < n) {
num++;
sum += img[x][y];
}
}
}
ret[i][j] = sum / num;
}
}
*returnSize = m;
return ret;
}
[sol1-JavaScript]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var imageSmoother = function(img) {
const m = img.length, n = img[0].length;
const ret = new Array(m).fill(0).map(() => new Array(n).fill(0));
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
let num = 0, sum = 0;
for (let x = i - 1; x <= i + 1; x++) {
for (let y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < m && y >= 0 && y < n) {
num++;
sum += img[x][y];
}
}
}
ret[i][j] = Math.floor(sum / num);
}
}
return ret;
};
[sol1-Python3]
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def imageSmoother(self, img: List[List[int]]) -> List[List[int]]:
m, n = len(img), len(img[0])
ans = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
tot, num = 0, 0
for x in range(max(i - 1, 0), min(i + 2, m)):
for y in range(max(j - 1, 0), min(j + 2, n)):
tot += img[x][y]
num += 1
ans[i][j] = tot // num
return ans
[sol1-Golang]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func imageSmoother(img [][]int) [][]int {
m, n := len(img), len(img[0])
ans := make([][]int, m)
for i := range ans {
ans[i] = make([]int, n)
for j := range ans[i] {
sum, num := 0, 0
for _, row := range img[max(i-1, 0):min(i+2, m)] {
for _, v := range row[max(j-1, 0):min(j+2, n)] {
sum += v
num++
}
}
ans[i][j] = sum / num
}
}
return ans
}

func max(a, b int) int {
if b > a {
return b
}
return a
}

func min(a, b int) int {
if a > b {
return b
}
return a
}

复杂度分析

  • 时间复杂度:O(mnC^2),其中 m 为给定矩阵的行数,n 为给定矩阵的列数,C=3 为过滤器的宽高。我们需要遍历整个矩阵以计算每个位置的值,计算单个位置的值的时间复杂度为 O(C^2)。

  • 空间复杂度:O(1)。注意返回值不计入空间复杂度。

 Comments
On this page
0661-图片平滑器