【发布时间】:2021-12-31 00:42:23
【问题描述】:
我正在完成 CS50x 课程的作业,经过多次测试,我确信我的代码中的 math 是正确的。但是,嵌入的 else-if 语句正在更改 temp[height][width] 数组的值,该数组存储像素的蓝色、绿色和红色部分的十六进制值(即 temp[][].rgbtBlue , temp[][].rgbtGreen, temp[][].rgbtRed。出于某种原因,this 的值似乎没有其他人遇到过这个令人沮丧的错误。
作为我的代码的序言,作业的目标是以 4 种不同的方式过滤图像,而最终的过滤器是边缘检测。初始化一些数组后,我开始遍历每一行(带有 int i 的 for 循环),然后是该行中的每个像素(嵌入带有 int j 的 for 循环),高度和宽度是输入图像的尺寸。在嵌入的 for 循环中,我放置了一个 if-else 语句来检查 temp[i][j] 像素是否是角/边缘,或者两者都不是,并且我在 if 语句中嵌入了进一步的 if-else-if 语句以确定 temp[i][j] 角/边缘像素是角还是边缘,这会稍微改变边缘的检测方式。
错误发生在 else-if 语句检查像素是否在左下角。例如,当 temp[0][0].rgbtBlue 应该为 4 时,它变为 7。在此 else-if 循环之前,temp[0][0] 为 4。对于父级的其余部分,它保持为 7 if -else 语句(用于检查角/边缘像素的语句,就在嵌入的 for (int j) 循环下方)。然而,一旦这个 if-else 语句结束,temp[0][0].rgbtBlue 又是 4,但是损坏已经造成了。
这个错误对我来说很疯狂,尤其是因为我对编码还很陌生。我完全不知道该怎么做。我最好的猜测是它与记忆有关。
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// Create temp array
RGBTRIPLE temp[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp[i][j] = image[i][j];
}
}
// Sobel operator array
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}};
// Compute Gx & Gy for each channel RGB
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// Reset values to 0 for each pixel
int xB = 0;
int xG = 0;
int xR = 0;
int yB = 0;
int yG = 0;
int yR = 0;
// Check for edge-pixel
if (i == 0 || j == 0 || i == height - 1 || j == height - 1)
{
// Upper left corner
if (i == 0 && j == 0)
{
for (int m = i, g = 1; m < i + 2; m++, g++)
{
for (int n = j, h = 1; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// Lower left corner, THIS IS WHERE THE BUG 'STARTS'
else if (i == height - 1 && j == 0)
{
for (int m = i - 1, g = 0; m < i + 1; m++, g++)
{
for (int n = j, h = 1; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// Upper right corner
else if (i == 0 && j == width - 1)
{
for (int m = i, g = 1; m < i + 2; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 1; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// Lower right corner
else if (i == height - 1 && j == width - 1)
{
for (int m = i - 1, g = 0; m < i + 1; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 1; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// West edge
else if (j == 0 && i != 0 && i != height - 1)
{
for (int m = i - 1, g = 0; m < i + 1; m++, g++)
{
for (int n = j, h = 1; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// East edge
else if (j == width - 1 && i != 0 && i != height - 1)
{
for (int m = i - 1, g = 0; m < i + 1; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 1; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// North edge
else if (i == 0 && j != 0 && j != width - 1)
{
for (int m = i, g = 1; m < i + 2; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// South edge
else if (i == height - 1 && j != 0 && j != width - 1)
{
for (int m = i - 1, g = 0; m < i + 1; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
}
// Pixel is not a corner nor an edge
else
{
for (int m = i - 1, g = 0; m < i + 2; m++, g++)
{
for (int n = j - 1, h = 0; n < j + 2; n++, h++)
{
xB += (temp[m][n].rgbtBlue * Gx[g][h]);
xG += (temp[m][n].rgbtGreen * Gx[g][h]);
xR += (temp[m][n].rgbtRed * Gx[g][h]);
yB += (temp[m][n].rgbtBlue * Gy[g][h]);
yG += (temp[m][n].rgbtGreen * Gy[g][h]);
yR += (temp[m][n].rgbtRed * Gy[g][h]);
}
}
}
// THIS IS WHERE THE BUG 'ENDS'
// Computing new channel values
int GzB = round(sqrt((xB*xB) + (yB*yB)));
int GzG = round(sqrt((xG*xG) + (yG*yG)));
int GzR = round(sqrt((xR*xR) + (yR*yR)));
// Cap at 255
if (GzB > 255)
{
GzB = 255;
}
if (GzG > 255)
{
GzG = 255;
}
if (GzR > 255)
{
GzR = 255;
}
// Assign new channel value to temp array
temp[i][j].rgbtBlue = GzB;
temp[i][j].rgbtGreen = GzG;
temp[i][j].rgbtRed = GzR;
// Assign pixel their channel value via temp array
image[i][j] = temp[i][j];
}
}
return;
}
【问题讨论】:
-
只是样式注释,但
xR += (temp[m][n].rgbtRed * Gx[g][h]);与xR += temp[m][n].rgbtRed * Gx[g][h];相同。额外的括号只是让您的代码更难阅读的噪音。 -
欢迎来到 Stack Overflow。请在minimal complete examples 上查看我们的页面。将您的示例缩减为重现错误的最简单示例不仅是为了我们的方便;这是一项重要的编程技能。它可能会让你发现这个错误,如果不是那么它会让我们的工作更容易。
-
@WeatherVane 这就是问题所在...谢谢!
-
我投票结束这个问题,因为它涉及一个简单的错误,而不是重要的软件原理。它不太可能帮助未来的读者。
标签: c if-statement