CS50 PS4 Filter-less Blur函数计算异常,请求技术排查
CS50 PS4 模糊(Blur)函数修复方案
核心问题分析
你的代码存在两个关键错误,导致所有测试用例失败:
- 边界判断笔误:像素存在性判断条件里写了
j + j < width,这是明显的输入错误,正确应该是j + l < width。这个错误会让列坐标判断完全混乱,要么漏算有效像素,要么错误包含越界像素,直接导致求和与计数逻辑失效。 - 直接修改原图像:遍历过程中直接修改
image数组的像素值,后续像素计算时会用到已经被模糊过的像素(而非原始图像的像素)。比如处理第二行像素时,第一行的像素已经被修改,最终计算出的模糊结果必然不符合要求。必须先创建原始图像的副本,所有求和计算基于副本,最后再将结果写回原图像。
修正后的代码
#include <math.h> #include <stdlib.h> void blur(int height, int width, RGBTRIPLE image[height][width]) { // 创建原始图像的副本 RGBTRIPLE(*copy)[width] = malloc(height * sizeof(RGBTRIPLE[width])); if (copy == NULL) { return; } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { copy[i][j] = image[i][j]; } } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float totalblue = 0.0; float totalgreen = 0.0; float totalred = 0.0; int counter = 0; for (int k = -1; k < 2; k++) { for (int l = -1; l < 2; l++) { // 修正边界判断笔误,临时变量让逻辑更清晰 int x = i + k; int y = j + l; if (x >= 0 && x < height && y >= 0 && y < width) { totalblue += copy[x][y].rgbtBlue; totalgreen += copy[x][y].rgbtGreen; totalred += copy[x][y].rgbtRed; counter++; } } } // 赋值模糊后的像素值 image[i][j].rgbtBlue = round(totalblue / counter); image[i][j].rgbtGreen = round(totalgreen / counter); image[i][j].rgbtRed = round(totalred / counter); } } // 释放内存,避免泄漏 free(copy); return; }
修正说明
- 图像副本:用
malloc创建与原图像尺寸一致的副本,先复制所有原始像素值,后续求和操作均从副本读取,彻底避免修改原图像对计算的干扰。 - 修复边界判断:将错误的
j + j改为j + l,同时用临时变量x、y存储偏移后的坐标,让代码逻辑更清晰,减少重复计算。 - 内存管理:使用完副本后调用
free释放内存,避免内存泄漏问题。
内容的提问来源于stack exchange,提问作者sagostin
相关产品推荐
相关产品推荐

