Leetcode661:图片平滑器 C语言

时间:2024-11-21 17:27:56

题目描述:

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

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

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

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

代码思路:

这个代码实现了一个图像平滑处理的功能。具体来说,它接收一个二维整数数组 img 作为输入,该数组表示一个灰度图像,其中 img[i][j] 表示图像中第 i 行第 j 列的像素值。然后,它生成一个新的二维整数数组,其中每个像素值是原图像中对应像素及其周围8个像素(共9个像素)的平均值。最后,它返回这个新的二维数组以及一个数组,用于表示新数组中每一行的大小。

以下是代码的详细思路:

  1. 初始化变量
    • i, j, x, y:用于循环遍历图像和周围像素的索引。
    • num:用于记录当前像素周围有效像素的数量(包括当前像素自身)。
    • sum:用于记录当前像素及其周围像素值的总和。
    • m 和 n:分别表示输入图像的行数和列数。
  2. 分配内存
    • 为返回的新图像数组 ret 分配内存,行数等于输入图像的行数 m
    • 为返回的行大小数组 *returnColumnSizes 分配内存,大小也为 m
    • 对于 ret 的每一行,分配 n 个整数的内存空间,并设置 *returnColumnSizes[i] 为 n,表示新图像中每一行的大小与输入图像相同。
  3. 计算平滑后的图像
    • 使用两个嵌套的循环遍历输入图像的每一个像素 (i, j)
    • 对于每个像素 (i, j),使用另外两个嵌套的循环遍历其周围的9个像素 (x, y)(包括自身)。
    • 在遍历周围像素时,检查索引 (x, y) 是否在图像的有效范围内内(即没有越界)。如果是,则增加 num(有效像素数量)并累加 sum(像素值总和)。
    • 计算当前像素 (i, j) 的新值,即 sum / num,并将这个值存储在 ret[i][j] 中。
  4. 返回结果
    • 设置 *returnSize 为 m,表示返回的新图像数组的行数。
    • 返回新图像数组 ret

注意事项

1.代码中使用了 malloc 来动态分配内存,因此调用者需要负责在不再需要这些内存时调用 free 来释放它们,以避免内存泄漏。

2.在计算平均值时,由于 num 总是至少为1(因为包括了当前像素自身),所以不需要担心除以零的情况。

3.代码假设输入图像 img 的每一行都有相同数量的列,即 imgColSize[i] 对于所有 i 都是相同的,这个值被存储在 n 中。

代码实现:

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** imageSmoother(int** img, int imgSize, int* imgColSize, int* returnSize, int** returnColumnSizes){
    int i,j,x,y;
    int num,sum;
    int m=imgSize,n=imgColSize[0];
    int **ret=(int**)malloc(sizeof(int*)*m);//二维数组创建:创建行
    *returnColumnSizes=(int*)malloc(sizeof(int)*m);//数组大小的返回
    for(i=0;i<m;i++){
        ret[i]=(int*)malloc(sizeof(int)*n);//二维数组的创建:每一行的基础上再创建
        (*returnColumnSizes)[i]=n;//每一行大小的返回
    }
    for(i=0;i<m;i++){
        for(j=0;j<n;j++){//以上两个循环用于数组中某一元素的定位
            num=0,sum=0;//初始化
            for(x=i-1;x<=i+1;x++){
                for(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;
}