CS50 Pset4 Filter(more) blur函数运行结果异常排查
CS50x 2022 Pset4 高难度组Filter模块blur函数故障排查
这是CS50x 2022课程Pset4(更高难度组)Filter板块的练习内容,本次排查对象为完整图像滤镜项目中的blur(模糊)函数,当前实现无法通过测试用例,问题定位与修复如下。
问题代码
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE temp_img[height][width]; // copy original image array for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { temp_img[i][j] = image[i][j]; } } // iterate throughout the image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumBlue = 0; int sumGreen = 0; int sumRed = 0; float count_pix = 0; // obtain value of original colour values around target pixel- red green blue for (int r = -1; r <= 1; r++) { for (int c = -1; c <= 1; c++) { // logic to determine if pixel is existent if ((0 <= i + r && i + r < height) && (0 <= j + c && j + c < width)) { // add all RGB values accordingly, with counter sumBlue += temp_img[i + r][j + r].rgbtBlue; sumGreen += temp_img[i + r][j + r].rgbtGreen; sumRed += temp_img[i + r][j + r].rgbtRed; count_pix ++; //count number of iterations to average out later } } } // average out and add replace values into original image for output image[i][j].rgbtBlue = round(sumBlue / count_pix); image[i][j].rgbtGreen = round(sumGreen / count_pix); image[i][j].rgbtRed = round(sumRed / count_pix); } } return; }
原代码设计逻辑
- 创建
RGBTRIPLE类型的临时二维数组temp_img,完整拷贝原始图像数据,避免计算过程中原图像像素被修改,干扰后续计算结果 - 双重循环遍历图像内每一个像素,初始化蓝、绿、红三通道的求和变量
sumBlue、sumGreen、sumRed,以及有效像素计数器count_pix - 通过双重偏移循环(行偏移
r范围-1到1,列偏移c范围-1到1)遍历当前像素的3x3邻域,判断邻域像素坐标在图像合法范围内(行坐标在0到height-1区间、列坐标在0到width-1区间)时,累加对应像素的三通道值,同时计数器自增 - 将三通道累加值除以有效像素数,通过
round函数取整后赋值给原图像对应像素,完成模糊计算
测试失败表现
- 中间像素模糊测试:预期输出
127 140 149\n,实际输出123 137 145\n - 边缘像素模糊测试:预期输出
80 95 105\n,实际输出85 100 110\n - 角落像素模糊测试:预期输出
70 85 95\n,实际输出65 80 90\n
根因定位
核心错误为邻域像素列索引用错变量:在3x3邻域遍历的像素值累加逻辑中,二维数组的列索引错误使用了行偏移变量r,而非预先定义的列偏移变量c,导致实际参与求和计算的像素并非目标像素周围的完整3x3邻域,仅取到了沿对角线方向的错位像素,所有场景下的求和结果均偏离正确值。
错误代码片段如下:
sumBlue += temp_img[i + r][j + r].rgbtBlue; sumGreen += temp_img[i + r][j + r].rgbtGreen; sumRed += temp_img[i + r][j + r].rgbtRed;
修复方案
将上述三行中的列索引从j + r修改为j + c,修复后的对应逻辑段为:
if ((0 <= i + r && i + r < height) && (0 <= j + c && j + c < width)) { sumBlue += temp_img[i + r][j + c].rgbtBlue; sumGreen += temp_img[i + r][j + c].rgbtGreen; sumRed += temp_img[i + r][j + c].rgbtRed; count_pix ++; }
修复后所有测试用例均可正常通过。
内容的提问来源于stack exchange,提问作者ryanlhy
相关产品推荐
相关产品推荐

