CS50图像模糊函数仅中间像素计算正确且出现段错误求助
CS50图像模糊函数的段错误与计算错误排查
问题概述
编写了CS50作业中的图像模糊函数,手动处理8种边缘情况,但运行BMP文件时出现段错误(Seg fault),仅中间像素计算结果正确。使用check50测试3x3样本图像时,实际输出与预期差异较大。
原代码
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE blurred[height][width]; int i = 0; int j = 0; int sumred; int sumgreen; int sumblue; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (i == 0 && j == 0) //edge case 1: top left corner { // ([i][j] + [i][j+1] + [i+1][j] + [i+1][j+1])/4 sumred = image[i][j].rgbtRed + image[i][j+1].rgbtRed + image[i+1][j].rgbtRed + image[i+1][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 4.0); sumgreen = image[i][j].rgbtGreen + image[i][j+1].rgbtGreen + image[i+1][j].rgbtGreen + image[i+1][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 4.0); sumblue = image[i][j].rgbtBlue + image[i][j+1].rgbtBlue + image[i+1][j].rgbtBlue + image[i+1][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 4.0); } if (i == 0 && j > 0 && j < (width - 1)) //edgecase 2: top roll { // ([i][j-1] + [i][j] + [i][j+1] + [i+1][j-1] + [i+1][j] + [i+1][j+1])/6 sumred = image[i][j-1].rgbtRed + image[i][j].rgbtRed + image[i][j+1].rgbtRed + image[i+1][j-1].rgbtRed + image[i+1][j].rgbtRed + image[i+1][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 6.0); sumgreen = image[i][j-1].rgbtGreen + image[i][j].rgbtGreen + image[i][j+1].rgbtGreen + image[i+1][j-1].rgbtGreen + image[i+1][j].rgbtGreen + image[i+1][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 6.0); sumblue = image[i][j-1].rgbtBlue + image[i][j].rgbtBlue + image[i][j+1].rgbtBlue + image[i+1][j-1].rgbtBlue + image[i+1][j].rgbtBlue + image[i+1][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 6.0); } if (i == 0 && j == (width - 1)) //edge case 3: top right corner { sumred = image[i][j-1].rgbtRed + image[i][j].rgbtRed + image[i+1][j-1].rgbtRed + image[i+1][j].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 4.0); sumgreen = image[i][j-1].rgbtGreen + image[i][j].rgbtGreen + image[i+1][j-1].rgbtGreen + image[i+1][j].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 4.0); sumblue = image[i][j-1].rgbtBlue + image[i][j].rgbtBlue + image[i+1][j-1].rgbtBlue + image[i+1][j].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 4.0); } if (i > 0 && i < (height - 1) && j == 0) //edge case 4: left most column { sumred = image[i-1][j].rgbtRed + image[i-1][j+1].rgbtRed + image[i][j].rgbtRed + image[i][j+1].rgbtRed + + image[i+1][j].rgbtRed + image[i+1][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 6.0); sumgreen = image[i-1][j].rgbtGreen + image[i-1][j+1].rgbtGreen + image[i][j].rgbtGreen + image[i][j+1].rgbtGreen + image[i+1][j].rgbtGreen + image[i+1][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 6.0); sumblue = image[i-1][j].rgbtBlue + image[i-1][j+1].rgbtBlue + image[i][j].rgbtBlue + image[i][j+1].rgbtBlue + image[i+1][j].rgbtBlue + image[i+1][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 6.0); } if (i == (height - 1) && j == 0) // edge case 5: bottom left corner { sumred = image[i-1][j].rgbtRed + image[i-1][j+1].rgbtRed + image[i][j].rgbtRed + image[i][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 4.0); sumgreen = image[i-1][j].rgbtGreen + image[i-1][j+1].rgbtGreen + image[i][j].rgbtGreen + image[i][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 4.0); sumblue = image[i-1][j].rgbtBlue + image[i-1][j+1].rgbtBlue + image[i][j].rgbtBlue + image[i][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 4.0); } if (i == (height - 1) && j > 0 && j < (width -1)) // edge case 6: bottom roll { sumred = image[i-1][j-1].rgbtRed + image[i-1][j].rgbtRed + image[i-1][j+1].rgbtRed + image[i][j-1].rgbtRed + image[i][j].rgbtRed + image[i][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 6.0); sumgreen = image[i-1][j-1].rgbtGreen + image[i-1][j].rgbtGreen + image[i-1][j+1].rgbtGreen + image[i][j-1].rgbtGreen + image[i][j].rgbtGreen + image[i][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 6.0); sumblue = image[i-1][j-1].rgbtBlue + image[i-1][j].rgbtBlue + image[i-1][j+1].rgbtBlue + image[i][j-1].rgbtBlue + image[i][j].rgbtBlue + image[i][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 6.0); } if (i == (height - 1) && j == (width - 1)) // edge case 7: bottom right corner { sumred = image[i-1][j-1].rgbtRed + image[i-1][j].rgbtRed + image[i][j-1].rgbtRed + image[i][j].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 4.0); sumgreen = image[i-1][j-1].rgbtGreen + image[i-1][j].rgbtGreen + image[i][j-1].rgbtGreen + image[i][j].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 4.0); sumblue = image[i-1][j-1].rgbtBlue + image[i-1][j].rgbtBlue + image[i][j-1].rgbtBlue + image[i][j].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 4.0); } if (i > 0 && i < (height - 1) && j == (width - 1)) // edge case 8: right most column { sumred = image[i-1][j-1].rgbtRed + image[i-1][j].rgbtRed + image[i][j-1].rgbtRed + image[i][j].rgbtRed + image[i+1][j-1].rgbtRed + image[i+1][j].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 6.0); sumgreen = image[i-1][j-1].rgbtGreen + image[i-1][j].rgbtGreen + image[i][j-1].rgbtGreen + image[i][j].rgbtGreen + image[i+1][j-1].rgbtGreen + image[i+1][j].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 6.0); sumblue = image[i-1][j-1].rgbtBlue + image[i-1][j].rgbtBlue + image[i][j-1].rgbtBlue + image[i][j].rgbtBlue + image[i+1][j-1].rgbtBlue + image[i+1][j].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 6.0); } else // everything else srrounded by 8 pixels { sumred = image[i-1][j-1].rgbtRed + image[i-1][j].rgbtRed + image[i-1][j+1].rgbtRed + image[i][j-1].rgbtRed + image[i][j].rgbtRed + image[i][j+1].rgbtRed + image[i+1][j-1].rgbtRed + image[i+1][j].rgbtRed + image[i+1][j+1].rgbtRed; blurred[i][j].rgbtRed = round(sumred / 9.0); sumgreen = image[i-1][j-1].rgbtGreen + image[i-1][j].rgbtGreen + image[i-1][j+1].rgbtGreen + image[i][j-1].rgbtGreen + image[i][j].rgbtGreen + image[i][j+1].rgbtGreen + image[i+1][j-1].rgbtGreen + image[i+1][j].rgbtGreen + image[i+1][j+1].rgbtGreen; blurred[i][j].rgbtGreen = round(sumgreen / 9.0); sumblue = image[i-1][j-1].rgbtBlue + image[i-1][j].rgbtBlue + image[i-1][j+1].rgbtBlue + image[i][j-1].rgbtBlue + image[i][j].rgbtBlue + image[i][j+1].rgbtBlue + image[i+1][j-1].rgbtBlue + image[i+1][j].rgbtBlue + image[i+1][j+1].rgbtBlue; blurred[i][j].rgbtBlue = round(sumblue / 9.0); } } } for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { image[i][j].rgbtRed = blurred[i][j].rgbtRed; image[i][j].rgbtGreen = blurred[i][j].rgbtGreen; image[i][j].rgbtBlue = blurred[i][j].rgbtBlue; } } return; }
测试用3x3图像
- 第一行:(10, 20, 30), (40, 50, 60), (70, 80, 90)
- 第二行:(110, 130, 140), (120, 140, 150), (130, 150, 160)
- 第三行:(200, 210, 220), (220, 230, 240), (240, 250, 255)
问题原因与修复
1. 段错误根源
原代码中所有边缘情况判断都使用独立的if语句,而非else if。这导致边缘像素在执行完对应边缘分支后,会继续判断后续条件,最终进入else分支。以左上角像素(i=0,j=0)为例,进入else分支后会访问image[-1][-1],触发数组越界,直接导致段错误。
2. 计算结果错误根源
边缘像素会先后执行边缘分支和else分支,else分支的计算结果会覆盖之前的正确值,只有中间像素(不触发任何边缘if条件)仅执行else分支,结果正确。
3. 代码笔误
边缘情况4的sumred计算中多了一个加号:+ + image[i+1][j].rgbtRed,这会导致语法错误或错误的数值累加。
修复措施
- 将所有边缘情况的
if改为else if,确保每个像素仅进入一个分支; - 删除边缘情况4中多余的加号。
内容的提问来源于stack exchange,提问作者Butterworth Filter
相关产品推荐
相关产品推荐

