CS50作业:C语言实现图像模糊滤镜遇问题求协助
CS50图像模糊滤镜代码修复
正在完成CS50的图像模糊滤镜作业,要求遍历图像二维数组的每个像素,找到其3x3范围内的相邻像素,取RGB平均值替换原像素值,但编写的C代码无法正常运行,对教程提到的"像素相对位置计算"存在困惑,附上原始代码并求助:
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { int red = 0; int green = 0; int blue = 0; int counter_pixel = 0; //I would assume that we would need to tell the computer to free up space for the new imafe with malloc() RGBTRIPLE temporary[height][width]; for (int i = 0; i < height; i++) { // go through every column for (int j = 0; j < width; j++) { temporary[i][j] = image[i][j]; } } // go through every row for (int i = 0; i < height; i++) { // go through every column for (int j = 0; j < width; j++) { //checking if the pixel is inside the image red = green = blue = 0; if (i < 0 || j < 0 || i > height +1 || j > width + 1) { image[i + 1][j].rgbtRed = temporary[i + 1][j].rgbtRed; image[i - 1][j].rgbtRed = temporary[i - 1][j].rgbtRed; image[i][j + 1].rgbtRed = temporary[i][j + 1].rgbtRed; image[i][j - 1].rgbtRed = temporary[i][j - 1].rgbtRed; image[i + 1][j].rgbtGreen = temporary[i + 1][j].rgbtGreen; image[i - 1][j].rgbtGreen = temporary[i - 1][j].rgbtGreen; image[i][j + 1].rgbtGreen = temporary[i][j + 1].rgbtGreen; image[i][j - 1].rgbtGreen = temporary[i][j - 1].rgbtGreen; image[i + 1][j].rgbtBlue = temporary[i + 1][j].rgbtBlue; image[i - 1][j].rgbtBlue = temporary[i - 1][j].rgbtBlue; image[i][j + 1].rgbtBlue = temporary[i][j + 1].rgbtBlue; image[i][j - 1].rgbtBlue = temporary[i][j - 1].rgbtBlue; counter_pixel++; red = round(((temporary[i + 1][j].rgbtRed + temporary[i - 1][j].rgbtRed + temporary[i][j + 1].rgbtRed + temporary[i][j -1].rgbtRed) / counter_pixel)); green = round(((temporary[i + 1][j].rgbtGreen + temporary[i - 1][j].rgbtGreen + temporary[i][j + 1].rgbtGreen + temporary[i][j -1].rgbtGreen) / counter_pixel)); blue = round(((temporary[i + 1][j].rgbtBlue + temporary[i - 1][j].rgbtBlue + temporary[i][j + 1].rgbtBlue + temporary[i][j -1].rgbtBlue) / counter_pixel)); } } } return; }
原始代码的核心问题
- 边界判断逻辑完全错误:外层循环i从0到height-1,j从0到width-1,
if (i < 0 || j < 0 || i > height +1 || j > width + 1)的条件永远不会触发,且判断范围的阈值错误(正确应为x >= height或y >= width)。 - 模糊逻辑偏离要求:代码中没有计算相邻像素的RGB平均值,反而错误地将临时数组的像素直接赋值给原图像,完全不符合模糊滤镜的逻辑。
- 相邻像素范围不全:只考虑了上下左右4个方向,忽略了对角线的相邻像素,正确的模糊应覆盖当前像素周围3x3的所有有效像素(包括自身)。
- 变量初始化与累加错误:
counter_pixel未在每次计算单个像素时重置,RGB值的累加逻辑混乱,没有正确统计有效像素的数量。
修复后的代码及解释
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { // 复制原始图像到临时数组,避免修改时覆盖原始数据 RGBTRIPLE temporary[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { temporary[i][j] = image[i][j]; } } // 遍历每个目标像素 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int red_sum = 0, green_sum = 0, blue_sum = 0; int valid_count = 0; // 遍历当前像素周围3x3的相对位置(偏移量从-1到1) for (int di = -1; di <= 1; di++) { for (int dj = -1; dj <= 1; dj++) { // 计算偏移后的绝对坐标 int x = i + di; int y = j + dj; // 检查坐标是否在图像有效范围内 if (x >= 0 && x < height && y >= 0 && y < width) { // 累加有效像素的RGB值 red_sum += temporary[x][y].rgbtRed; green_sum += temporary[x][y].rgbtGreen; blue_sum += temporary[x][y].rgbtBlue; valid_count++; } } } // 计算平均值并赋值给原图像(转换为浮点型后取整,避免整数除法截断误差) image[i][j].rgbtRed = round((float)red_sum / valid_count); image[i][j].rgbtGreen = round((float)green_sum / valid_count); image[i][j].rgbtBlue = round((float)blue_sum / valid_count); } } return; }
关键逻辑说明
- 像素相对位置计算:用
di(行偏移)和dj(列偏移)表示当前像素与相邻像素的位置关系,范围是-1到1,这样就能遍历当前像素周围3x3的所有区域。 - 边界有效性检查:对每个偏移后的坐标
x和y,判断是否在0 <= x < height、0 <= y < width范围内,确保不会访问数组越界的内存。 - 临时数组的必要性:模糊计算依赖原始像素值,如果直接修改原图像,后续像素的计算会使用已修改的值,导致结果错误,因此必须先保存原始数据到临时数组,所有计算基于临时数组完成后,再将结果赋值给原图像。
内容的提问来源于stack exchange,提问作者Leon de Keller
相关产品推荐
相关产品推荐

