CS50项目helpers.c的edges函数生成图像正确但check50检测全部失败
问题原因
你的代码存在3处核心错误,导致check50检测不通过:
- 原图像写入临时扩展数组的索引偏移错误:你创建的
height+2行width+2列临时数组,需要将原图像放在临时数组的[1height]行、[1width]列,才能让四周的黑边刚好作为边界计算的填充。你当前用i+2、j+2作为写入索引,相当于把原图像整体偏移了2行2列,填充的黑边完全没有起到作用。 - 计算Sobel梯度时未使用扩展数组:你费了功夫创建带黑边的临时数组,但计算gx、gy时仍然读取原
image数组的像素,不仅扩展数组完全浪费,还会在计算边界像素梯度时访问原数组的越界内存,拿到不确定的脏值。 - 外层遍历范围越界:你当前的循环条件
i < height + 2、j < width + 2会遍历临时数组的所有像素,但你只需要计算对应原图像的height*width个像素即可,多余的遍历会导致你写入原image数组时发生越界,篡改非法内存的值。
修正后的代码
#include <math.h> #include "helpers.h" void edges(int height, int width, RGBTRIPLE image[height][width]) { // 创建扩展数组,四周填充黑边 RGBTRIPLE temporary_image[height + 2][width + 2]; for (int i = 0; i < height + 2; i++) { for (int j = 0; j < width + 2; j++) { temporary_image[i][j].rgbtRed = 0; temporary_image[i][j].rgbtGreen = 0; temporary_image[i][j].rgbtBlue = 0; } } // 修正:原图像写入临时数组的[1~height]行、[1~width]列 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { temporary_image[i + 1][j + 1].rgbtRed = image[i][j].rgbtRed; temporary_image[i + 1][j + 1].rgbtGreen = image[i][j].rgbtGreen; temporary_image[i + 1][j + 1].rgbtBlue = image[i][j].rgbtBlue; } } // Sobel算子内核 const int gx[] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; const int gy[] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; // 修正:只遍历对应原图像的临时数组区域 for (int i = 1; i <= height; i++) { for (int j = 1; j <= width; j++) { int rgx = 0, rgy = 0, ggx = 0, ggy = 0, bgx = 0, bgy = 0, t = 0; for (int k = -1; k < 2; k++) { for (int l = -1; l < 2; l++) { // 修正:从扩展临时数组读取像素计算梯度 rgx += gx[t] * temporary_image[i + k][j + l].rgbtRed; rgy += gy[t] * temporary_image[i + k][j + l].rgbtRed; ggx += gx[t] * temporary_image[i + k][j + l].rgbtGreen; ggy += gy[t] * temporary_image[i + k][j + l].rgbtGreen; bgx += gx[t] * temporary_image[i + k][j + l].rgbtBlue; bgy += gy[t] * temporary_image[i + k][j + l].rgbtBlue; t++; } } image[i - 1][j - 1].rgbtRed = max_at_255(rgx, rgy); image[i - 1][j - 1].rgbtGreen = max_at_255(ggx, ggy); image[i - 1][j - 1].rgbtBlue = max_at_255(bgx, bgy); } } return; } int max_at_255(int gx, int gy) { float g = sqrt(gx * gx + gy * gy); int result = round(g); return result > 255 ? 255 : result; }
内容的提问来源于stack exchange,提问作者user17066215
相关产品推荐
相关产品推荐

