CS50 Week4 Edges问题:中间像素红色通道计算错误求助
CS50 Edges问题:红色通道计算错误排查
问题概述
处理中间像素时,绿色和蓝色通道计算结果符合预期,但红色通道输出错误,测试报错如下:
:( edges correctly filters middle pixel expected "210 150 60 ", not "192 150 60 "
用户提供的核心代码如下:
void edges(int height, int width, RGBTRIPLE image[height][width]) { int RedGx, GreenGx, BlueGx, GreenGy, BlueGy, RedGy, GreenTemp, BlueTemp, RedTemp; RGBTRIPLE temp[height][width]; for(int i = 0; i < height; i++) { for(int z = 0; z < width; z++) { temp[i][z] = image[i][z]; } } int xmult[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; int ymult[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; //middle pixels for(int y = 1; y < height - 1; y++) { for(int x = 1; x < width - 1; x++) { RedGx = temp[y-1][x-1].rgbtRed * xmult[0] + temp[y][x-1].rgbtRed * xmult[3] + temp[y+1][x-1].rgbtRed * xmult[6] + temp[y-1][x+1].rgbtRed * xmult[2] + temp[y][x+1].rgbtRed * xmult[5] + temp[y+1][x+1].rgbtRed * xmult[8]; GreenGx = temp[y-1][x-1].rgbtGreen * xmult[0] + temp[y][x-1].rgbtGreen * xmult[3] + temp[y+1][x-1].rgbtGreen * xmult[6] + temp[y-1][x+1].rgbtGreen * xmult[2] + temp[y][x+1].rgbtGreen * xmult[5] + temp[y+1][x+1].rgbtGreen * xmult[8]; BlueGx = temp[y-1][x-1].rgbtBlue * xmult[0] + temp[y][x-1].rgbtBlue * xmult[3] + temp[y+1][x-1].rgbtBlue * xmult[6] + temp[y-1][x+1].rgbtBlue * xmult[2] + temp[y][x+1].rgbtBlue * xmult[5] + temp[y+1][x+1].rgbtBlue * xmult[8]; RedGy = temp[y-1][x-1].rgbtRed * ymult[0] + temp[y][x-1].rgbtRed * ymult[3] + temp[y+1][x-1].rgbtRed * ymult[6] + temp[y-1][x+1].rgbtRed * ymult[2] + temp[y][x+1].rgbtRed * ymult[5] + temp[y+1][x+1].rgbtRed * ymult[8]; GreenGy = temp[y-1][x-1].rgbtGreen * ymult[0] + temp[y][x-1].rgbtGreen * ymult[3] + temp[y+1][x-1].rgbtGreen * ymult[6] + temp[y-1][x+1].rgbtGreen * ymult[2] + temp[y][x+1].rgbtGreen * ymult[5] + temp[y+1][x+1].rgbtGreen * ymult[8]; BlueGy = temp[y-1][x-1].rgbtBlue * ymult[0] + temp[y][x-1].rgbtBlue * ymult[3] + temp[y+1][x-1].rgbtBlue * ymult[6] + temp[y-1][x+1].rgbtBlue * ymult[2] + temp[y][x+1].rgbtBlue * ymult[5] + temp[y+1][x+1].rgbtBlue * ymult[8]; GreenTemp = fmin(round(sqrt(GreenGx * GreenGx + GreenGy * GreenGy)),255); BlueTemp = fmin(round(sqrt(BlueGx * BlueGx + BlueGy * BlueGy)),255); RedTemp = fmin(round(sqrt(RedGx * RedGx + RedGy * RedGy)),255); image[y][x].rgbtGreen = GreenTemp; image[y][x].rgbtBlue = BlueTemp; image[y][x].rgbtRed = RedTemp; } } return; }
错误原因
问题出在Sobel Y算子的计算遗漏了关键像素:
- Sobel Y算子的结构要求计算上中(
temp[y-1][x])和下中(temp[y+1][x])像素的贡献,对应权重为ymult[1](-2)和ymult[7](2) - 你的代码在计算所有通道的Gy值时,都漏掉了这两个像素。测试用例中这两个位置的绿蓝值恰好为0,所以绿蓝通道结果不受影响;但红色值不为0,导致红色通道计算结果偏小。
修复方案
补全Sobel算子的所有9个像素计算,修正后的通道计算逻辑如下:
// 修正RedGx计算(补全中间列,权重为0不影响结果,但逻辑完整) RedGx = temp[y-1][x-1].rgbtRed * xmult[0] + temp[y-1][x].rgbtRed * xmult[1] + temp[y-1][x+1].rgbtRed * xmult[2] + temp[y][x-1].rgbtRed * xmult[3] + temp[y][x].rgbtRed * xmult[4] + temp[y][x+1].rgbtRed * xmult[5] + temp[y+1][x-1].rgbtRed * xmult[6] + temp[y+1][x].rgbtRed * xmult[7] + temp[y+1][x+1].rgbtRed * xmult[8]; // 修正RedGy计算(必须补上中和下中像素) RedGy = temp[y-1][x-1].rgbtRed * ymult[0] + temp[y-1][x].rgbtRed * ymult[1] + temp[y-1][x+1].rgbtRed * ymult[2] + temp[y][x-1].rgbtRed * ymult[3] + temp[y][x].rgbtRed * ymult[4] + temp[y][x+1].rgbtRed * ymult[5] + temp[y+1][x-1].rgbtRed * ymult[6] + temp[y+1][x].rgbtRed * ymult[7] + temp[y+1][x+1].rgbtRed * ymult[8];
对GreenGx、GreenGy、BlueGx、BlueGy执行相同的修改,确保所有通道都完整应用Sobel算子。修改后红色通道的计算结果即可符合预期。
内容的提问来源于stack exchange,提问作者Matthew Doig
相关产品推荐
相关产品推荐

