我是编程新手,目前正在学习CS50x课程.我最近遇到了PSET 4-Filter(更多),其中我必须用C语言编写一个程序来对BMP图片执行一些操作. 在我分享这个问题之前,我想指出,我确实遵循了学术诚实的准则,而且我自己解决了这个问题.它已经提交和计算(我不会分享完整的解决方案,只分享first few lines of each step).话虽如此,我只是想要一些帮助来理解为什么我的更改修复了我的代码,因为我花了几天时间也想不出一个解释.我相信这对我的学习过程很重要.
挑战是使用Sobel算子来识别和过滤图像中的边缘.在制作了图像的副本之后(所以我不会在像素上创建多米诺效应),我创建了一个2D数组来存储内核并初始化了一些变量:
double gxRed = 0, gxBlue = 0, gxGreen = 0;
double gyRed = 0, gyBlue = 0, gyGreen = 0;
int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
然后,我通过取消Gx/y的值来处理边缘情况:
if (i - 1 < 0)
{
gx[0][0] = 0, gx[0][1] = 0, gx[0][2] = 0;
gy[0][0] = 0, gy[0][1] = 0, gy[0][2] = 0;
}
下面,我根据内核数组计算每个 colored颜色 通道:
gxRed += (imageCopy[i - 1][j - 1].rgbtRed * gx[0][0]) + (imageCopy[i - 1][j].rgbtRed * gx[0][1]) +
(imageCopy[i - 1][j + 1].rgbtRed * gx[0][2]);
gxRed += (imageCopy[i][j - 1].rgbtRed * gx[1][0]) + (imageCopy[i][j].rgbtRed * gx[1][1]) +
(imageCopy[i][j + 1].rgbtRed * gx[1][2]);
gxRed += (imageCopy[i + 1][j - 1].rgbtRed * gx[2][0]) + (imageCopy[i + 1][j].rgbtRed * gx[2][1]) +
(imageCopy[i + 1][j + 1].rgbtRed * gx[2][2]);
计算大小并将其应用于原始图片:
image[i][j].rgbtRed = round(sqrt((gxRed * gxRed) + (gyRed * gyRed)));
考虑了255个范围并应用了更正(如果有):
if (image[i][j].rgbtRed > 255)
{
image[i][j].rgbtRed = 255;
}
一切都很好,生成的图像看起来也很好,正如我所预期的那样.然而,在运行课程判断时,绿色通道出现了一些问题,如下所示:
testing with sample 3x3 image
first row: (0, 10, 25), (0, 10, 30), (40, 60, 80)
second row: (20, 30, 90), (30, 40, 100), (80, 70, 90)
third row: (20, 20, 40), (30, 10, 30), (50, 40, 10)
Expected Output:
76 117 255
213 228 255
192 190 255
114 102 255
210 150 60
103 108 255
114 117 255
200 197 255
210 190 255
Actual Output:
76 117 66
213 228 140
192 190 66
114 102 6
210 150 60
103 108 39
114 117 66
200 197 129
210 190 66
As you can see, there was a specific issue with the green channel. My first instinct was, obviously, double check every part of the code responsible for dealing with green, but there was nothing! It was EXACTLY the same code for the other colors, not even a single space different apart from gx/yGreen and .rgbtGreen. Then I went to the edge cases, but again, how can the other channels work fine and only green be off? They are all handled by the same logic, and I made sure of that by defining an array for Gx and Gy. It seemed just impossible to me that only the green channel of the pixel was misbehaving. If there was a problem with the code, the whole RGB values should be off. Well, I could notice, though, that the problem happened when green was 255 in the expected output, even though I treated this case the same way I did for blue and red. After days of headaches and almost giving up (I had already submitted the -less version, so this was optional), I just created a temporary variable to store the computation of Gx/y before addressing the 255 range, as below:
int tempGreen = round(sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen)));
int tempRed = round(sqrt((gxRed * gxRed) + (gyRed * gyRed)));
int tempBlue = round(sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue)));
if (tempGreen > 255)
{
tempGreen = 255;
}
if (tempRed > 255)
{
tempRed = 255;
}
if (tempBlue > 255)
{
tempBlue = 255;
}
image[i][j].rgbtGreen = tempGreen;
image[i][j].rgbtRed = tempRed;
image[i][j].rgbtBlue = tempBlue;
这是相同的代码,我只是添加了变量,问题就解决了.我通过了所有的判断.为什么?如果这就是问题所在,难道蓝色和红色不应该也是这样吗?这一直困扰着我,所以我决定在这里分享.我为这篇超长的帖子道歉,这是我的第一篇,所以也欢迎任何关于如何更好地在这里写作的技巧.
非常提前感谢您!