661. 图片平滑器(C++)

题目

图像平滑器 是大小为 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

题解

class Solution {
public:
    vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
        int m = img.size();  
    int n = img[0].size();  
    vector<vector<int>> result(m, vector<int>(n, 0));  
  
    // 定义平滑器的边界偏移量  
    int dx[9] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};  
    int dy[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};  
  
    // 遍历图像的每个单元格  
    for (int i = 0; i < m; ++i) {  
        for (int j = 0; j < n; ++j) {  
            int sum = 0;  
            int count = 0;  
  
            // 遍历平滑器内的所有单元格  
            for (int k = 0; k < 9; ++k) {  
                int ni = i + dx[k];  
                int nj = j + dy[k];  
  
                // 检查边界条件  
                if (ni >= 0 && ni < m && nj >= 0 && nj < n) {  
                    sum += img[ni][nj];  
                    ++count;  
                }  
            }  
  
            // 计算平均值并向下取整  
            result[i][j] = sum / count;  
        }  
    }  
  
    return result;  

    }
};

算法原理

代码原理

目标

图像平滑处理的目标是通过计算每个像素(或单元格)及其周围像素的平均值来减少图像的噪声或细节,使图像看起来更加平滑。在这个例子中,我们使用的是一个3x3的平滑器(也称为滤波器或卷积核),它覆盖了目标像素及其最近的8个邻居像素。

变量和数组

  • img:输入图像,一个二维整数矩阵,其中每个元素代表图像中对应位置的像素值(或灰度值)。
  • result:输出图像,同样是一个二维整数矩阵,用于存储平滑处理后的像素值。
  • dxdy:两个整数数组,分别表示在3x3平滑器中,相对于中心像素(即当前正在处理的像素)的x和y方向上的偏移量。这些偏移量用于遍历平滑器内的所有像素位置。
  • mn:分别表示输入图像img的行数和列数。

遍历和处理

  1. 初始化输出图像:首先,我们根据输入图像img的尺寸初始化一个同样大小的二维整数矩阵result,用于存储平滑处理后的结果。
  2. 遍历每个像素:然后,我们使用两层嵌套循环遍历输入图像img中的每个像素(或单元格)。外层循环遍历行(i),内层循环遍历列(j)。
  3. 计算平均值:对于每个像素(i, j),我们初始化两个变量sum和count,分别用于累加平滑器内有效像素的灰度值和计数这些有效像素的数量。接着,我们再次使用两层循环遍历平滑器内的9个位置(通过dx和dy数组加上当前像素的坐标得到)。对于每个位置,我们检查它是否位于图像边界内(即坐标值是否在有效范围内)。如果是,我们将该位置的像素值加到sum中,并增加count。
  4. 赋值结果:最后,我们将sum除以count得到平均值,并使用std::floor函数(尽管在这个特定的例子中,由于sum和count都是整数,且count总是大于0,所以直接整数除法也会得到向下取整的结果)来确保结果是一个整数。然后,我们将这个平均值赋值给输出图像result中对应位置的像素。

注意事项

  • 边界像素的处理:由于平滑器是3x3的,因此图像边界上的像素在平滑处理时无法找到完整的8个邻居像素。但是,由于我们在遍历平滑器位置时检查了边界条件,因此这些像素只会将存在的邻居像素纳入平均值计算中。
  • 整数除法:在这个例子中,由于像素值都是整数,且我们只需要整数结果来更新图像,因此使用整数除法就足够了。如果需要更精确的结果(例如,用于后续处理),则可能需要考虑浮点除法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值