题目描述:
图像平滑器 是大小为 3 x 3
的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。
每个单元格的 平均灰度 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9 个单元格的平均值)。
如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。
给你一个表示图像灰度的 m x n 整数矩阵 img ,返回对图像的每个单元格平滑处理后的图像 。
代码思路:
这个代码实现了一个图像平滑处理的功能。具体来说,它接收一个二维整数数组 img
作为输入,该数组表示一个灰度图像,其中 img[i][j]
表示图像中第 i
行第 j
列的像素值。然后,它生成一个新的二维整数数组,其中每个像素值是原图像中对应像素及其周围8个像素(共9个像素)的平均值。最后,它返回这个新的二维数组以及一个数组,用于表示新数组中每一行的大小。
以下是代码的详细思路:
-
初始化变量:
-
i, j, x, y
:用于循环遍历图像和周围像素的索引。 -
num
:用于记录当前像素周围有效像素的数量(包括当前像素自身)。 -
sum
:用于记录当前像素及其周围像素值的总和。 -
m
和n
:分别表示输入图像的行数和列数。
-
-
分配内存:
- 为返回的新图像数组
ret
分配内存,行数等于输入图像的行数m
。 - 为返回的行大小数组
*returnColumnSizes
分配内存,大小也为m
。 - 对于
ret
的每一行,分配n
个整数的内存空间,并设置*returnColumnSizes[i]
为n
,表示新图像中每一行的大小与输入图像相同。
- 为返回的新图像数组
-
计算平滑后的图像:
- 使用两个嵌套的循环遍历输入图像的每一个像素
(i, j)
。 - 对于每个像素
(i, j)
,使用另外两个嵌套的循环遍历其周围的9个像素(x, y)
(包括自身)。 - 在遍历周围像素时,检查索引
(x, y)
是否在图像的有效范围内内(即没有越界)。如果是,则增加num
(有效像素数量)并累加sum
(像素值总和)。 - 计算当前像素
(i, j)
的新值,即sum / num
,并将这个值存储在ret[i][j]
中。
- 使用两个嵌套的循环遍历输入图像的每一个像素
-
返回结果:
- 设置
*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;
}