力扣题解661 图片平滑器
题目(简单)
图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。
每个单元格的 平均灰度 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9
个单元格的平均值)。如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。
示例
1. 题目重述
图像平滑器是一个3x3的滤波器,用于处理图像的每个单元格,使得平滑处理后的单元格值为该单元格及其周围8个单元格灰度值的平均值,结果向下取整。如果某些周围单元格缺失,则在计算平均灰度时不考虑这些缺失的单元格。
2. 分析题目
- 输入:一个二维数组,表示灰度图像,每个元素代表该位置的灰度值。
- 输出:一个新的二维数组,表示平滑处理后的图像。
- 处理方式:对于每个单元格,需计算其自身及其周围8个单元格的灰度值的平均值。若某些周围单元格缺失,须在计算时排除这些单元格。
- 特殊情况:需要处理边缘和角落的单元格,因为它们可能没有完整的8个邻居。
3. 解题基本思路
- 遍历图像的每个单元格。
- 对于每个单元格,计算有效的邻居单元格的平均值:
- 检查当前单元格周围的8个方向(上、下、左、右、左上、左下、右上、右下),并收集在边界内的邻居。
- 计算这些有效单元格的平均值,并向下取整。
- 将计算出的值存入新的结果数组中。
4. 示例代码
Python 示例
import numpy as np
def smooth_image(image):
rows, cols = image.shape
smoothed = np.zeros((rows, cols), dtype=int)
for i in range(rows):
for j in range(cols):
total = 0
count = 0
for x in range(-1, 2):
for y in range(-1, 2):
ni, nj = i + x, j + y
if 0 <= ni < rows and 0 <= nj < cols:
total += image[ni][nj]
count += 1
smoothed[i][j] = total // count # 向下取整
return smoothed
# 示例使用
image = np.array([[100, 200, 100],
[100, 200, 100],
[100, 100, 100]])
result = smooth_image(image)
print(result)
C++ 示例
#include <iostream>
#include <vector>
#include <cmath>
std::vector<std::vector<int>> smoothImage(const std::vector<std::vector<int>>& image) {
int rows = image.size();
int cols = image[0].size();
std::vector<std::vector<int>> smoothed(rows, std::vector<int>(cols, 0));
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
int total = 0;
int count = 0;
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
int ni = i + x;
int nj = j + y;
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
total += image[ni][nj];
count++;
}
}
}
smoothed[i][j] = total / count; // 向下取整
}
}
return smoothed;
}
// 示例使用
int main() {
std::vector<std::vector<int>> image = {{100, 200, 100},
{100, 200, 100},
{100, 100, 100}};
std::vector<std::vector<int>> result = smoothImage(image);
for (const auto& row : result) {
for (int value : row) {
std::cout << value << " ";
}
std::cout << std::endl;
}
return 0;
}
Java 示例
public class ImageSmoothing {
public static int[][] smoothImage(int[][] image) {
int rows = image.length;
int cols = image[0].length;
int[][] smoothed = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int total = 0;
int count = 0;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
int ni = i + x;
int nj = j + y;
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
total += image[ni][nj];
count++;
}
}
}
smoothed[i][j] = total / count; // 向下取整
}
}
return smoothed;
}
public static void main(String[] args) {
int[][] image = {{100, 200, 100},
{100, 200, 100},
{100, 100, 100}};
int[][] result = smoothImage(image);
for (int[] row : result) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
}
}
5. 总结分析
在这道题中,涉及的编程思维包括:
- 算法设计能力:明确步骤来计算每个单元的值,考虑边界条件。
- 空间和时间复杂度的理解:对于每个像素点的处理需要遍历周围像素,理解算法的复杂度。
- 数据结构运用:使用二维数组来表示图像及其处理结果,熟悉基本的数据结构运用。
- 条件判断:确保在边缘和角落正确处理缺少的单元格。