CS50模糊(blur)滤镜程序调试求助:测试结果不符合预期
CS50 图像模糊滤镜问题修复方案
问题概述
我独立完成了其他所有CS50项目,之前遇到问题会借助ChatGPT提示自行修复,但这次程序可运行却无法通过模糊滤镜测试,推测计算逻辑存在错误。具体测试报错如下:
- :( blur correctly filters middle pixel
expected "127 140 149\n", not "123 135 143\n"
- :( blur correctly filters pixel on edge
expected "80 95 105\n", not "75 88 97\n"
- :( blur correctly filters pixel in corner
expected "70 85 95\n", not "56 68 76\n"
原代码核心问题分析
- 原地修改图像数据:计算当前像素模糊值时直接覆盖原图像的像素,后续处理其他像素会用到已修改的像素,导致计算结果偏差。
- 邻域计数逻辑错误:
calcAv的初始化与累加逻辑混乱,没有准确统计实际参与计算的邻域像素数量,导致平均值分母错误。 - 邻域遍历逻辑复杂易出错:通过
fakeRow、dec等变量的遍历方式不够直观,容易遗漏或重复统计像素。
修复后的代码
#include <math.h> #include "bmp.h" void blur(int height, int width, RGBTRIPLE image[height][width]) { // 创建临时数组保存原始图像数据,避免原地修改干扰计算 RGBTRIPLE temp[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { temp[i][j] = image[i][j]; } } // 遍历每个像素计算模糊值 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { double sumRed = 0, sumGreen = 0, sumBlue = 0; int pixelCount = 0; // 遍历当前像素的3x3邻域范围 for (int rowOffset = -1; rowOffset <= 1; rowOffset++) { for (int colOffset = -1; colOffset <= 1; colOffset++) { int currentRow = i + rowOffset; int currentCol = j + colOffset; // 检查邻域像素是否在图像有效范围内 if (currentRow >= 0 && currentRow < height && currentCol >= 0 && currentCol < width) { sumRed += temp[currentRow][currentCol].rgbtRed; sumGreen += temp[currentRow][currentCol].rgbtGreen; sumBlue += temp[currentRow][currentCol].rgbtBlue; pixelCount++; } } } // 计算平均值并四舍五入后更新图像 image[i][j].rgbtRed = (BYTE)round(sumRed / pixelCount); image[i][j].rgbtGreen = (BYTE)round(sumGreen / pixelCount); image[i][j].rgbtBlue = (BYTE)round(sumBlue / pixelCount); } } return; }
修复要点说明
- 临时数组存储原始数据:所有模糊计算基于未修改的原始像素,彻底避免数据污染问题。
- 直观的邻域遍历:通过偏移量遍历3x3范围内的所有可能像素,仅统计图像边界内的有效像素。
- 准确的计数逻辑:每遍历到一个有效像素就增加计数器,确保平均值的分母是实际参与计算的像素数量。
- 符合要求的四舍五入:使用
round()函数保证平均值计算结果符合CS50测试的整数精度要求。
内容的提问来源于stack exchange,提问作者Dev Tusi_1
相关产品推荐
相关产品推荐

