当我通过edges
代码运行照片时,除了底部的三行像素(类似于彩虹电视静态像素)外,图像全部返回白色。我尝试调试我的代码,但仍然无法弄清楚:
void edges(int height, int width, RGBTRIPLE image[height][width])
{
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}};
int redx = 0;
int greenx = 0;
int bluex = 0;
int redy = 0;
int greeny = 0;
int bluey = 0;
int finalred = 0;
int finalgreen = 0;
int finalblue = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
for (int k = i - 1; k <= i + 1 && k < height && k >= 0; k++)
{
for (int m = j - 1; m <= j + 1 && m < width && m >= 0; m++)
{
if (k < i)
{
if (m < j)
{
redx += image[k][m].rgbtRed * gx[0][0];
greenx += image[k][m].rgbtGreen * gx[0][0];
bluex += image[k][m].rgbtBlue * gx[0][0];
redy += image[k][m].rgbtRed * gy[0][0];
greeny += image[k][m].rgbtGreen * gy[0][0];
bluey += image[k][m].rgbtBlue * gy[0][0];
// gx[?][0]
}
else if (m > j)
{
redx += image[k][m].rgbtRed * gx[0][2];
greenx += image[k][m].rgbtGreen * gx[0][2];
bluex += image[k][m].rgbtBlue * gx[0][2];
redy += image[k][m].rgbtRed * gy[0][2];
greeny += image[k][m].rgbtGreen * gy[0][2];
bluey += image[k][m].rgbtBlue * gy[0][2];
// gx[?][2]
}
else
{
redx += image[k][m].rgbtRed * gx[0][1];
greenx += image[k][m].rgbtGreen * gx[0][1];
bluex += image[k][m].rgbtBlue * gx[0][1];
redy += image[k][m].rgbtRed * gy[0][1];
greeny += image[k][m].rgbtGreen * gy[0][1];
bluey += image[k][m].rgbtBlue * gy[0][1];
// gx[?][1]
}
// gx[0][?]
}
else if (k > i)
{
if (m < j)
{
redx += image[k][m].rgbtRed * gx[2][0];
greenx += image[k][m].rgbtGreen * gx[2][0];
bluex += image[k][m].rgbtBlue * gx[1][0];
redy += image[k][m].rgbtRed * gy[2][0];
greeny += image[k][m].rgbtGreen * gy[2][0];
bluey += image[k][m].rgbtBlue * gy[2][0];
// gx[?][0]
}
else if (m > j)
{
redx += image[k][m].rgbtRed * gx[2][2];
greenx += image[k][m].rgbtGreen * gx[2][2];
bluex += image[k][m].rgbtBlue * gx[2][2];
redy += image[k][m].rgbtRed * gy[2][2];
greeny += image[k][m].rgbtGreen * gy[2][2];
bluey += image[k][m].rgbtBlue * gy[2][2];
// gx[?][2]
}
else
{
redx += image[k][m].rgbtRed * gx[2][1];
greenx += image[k][m].rgbtGreen * gx[2][1];
bluex += image[k][m].rgbtBlue * gx[2][1];
redy += image[k][m].rgbtRed * gy[2][1];
greeny += image[k][m].rgbtGreen * gy[2][1];
bluey += image[k][m].rgbtBlue * gy[2][1];
// gx[?][1]
}
// gx[2][?]
}
else
{
if (m < j)
{
redx += image[k][m].rgbtRed * gx[1][0];
greenx += image[k][m].rgbtGreen * gx[1][0];
bluex += image[k][m].rgbtBlue * gx[1][0];
redy += image[k][m].rgbtRed * gy[1][0];
greeny += image[k][m].rgbtGreen * gy[1][0];
bluey += image[k][m].rgbtBlue * gy[1][0];
// gx[?][0]
}
else if (m > j)
{
redx += image[k][m].rgbtRed * gx[1][2];
greenx += image[k][m].rgbtGreen * gx[1][2];
bluex += image[k][m].rgbtBlue * gx[1][2];
redy += image[k][m].rgbtRed * gy[1][2];
greeny += image[k][m].rgbtGreen * gy[1][2];
bluey += image[k][m].rgbtBlue * gy[1][2];
// gx[?][2]
}
else
{
redx += image[k][m].rgbtRed * gx[1][1];
greenx += image[k][m].rgbtGreen * gx[1][1];
bluex += image[k][m].rgbtBlue * gx[1][1];
redy += image[k][m].rgbtRed * gy[1][1];
greeny += image[k][m].rgbtGreen * gy[1][1];
bluey += image[k][m].rgbtBlue * gy[1][1];
// gx[?][1]
}
// gx[1][?]
}
}
}
finalred = (redx)^2 + (redy)^2;
finalgreen = (greenx)^2 + (greeny)^2;
finalblue = (bluex)^2 + (bluey)^2;
if (finalred > 255)
{
finalred = 255;
}
if (finalgreen > 255)
{
finalgreen = 255;
}
if (finalblue > 255)
{
finalblue = 255;
}
image[i][j].rgbtRed = finalred;
image[i][j].rgbtGreen = finalgreen;
image[i][j].rgbtBlue = finalblue;
}
}
return;
}
答案 0 :(得分:1)
这些初始化:
int redx = 0;
int greenx = 0;
int bluex = 0;
int redy = 0;
int greeny = 0;
int bluey = 0;
出现在for
和i
的{{1}}语句之前,但是这些变量累积每个像素的总和,因此必须为每个像素初始化它们。在j
的{{1}}语句之内,在for
和j
的{{1}}语句之前。
(由于注释中已指出这一点,因此已对问题中的代码进行了编辑,以在更新每个像素后为这些变量分配零。这是可行的,但这是一个较差的解决方案。只需移动该变量的定义和初始化即可。外部两个for
循环中的变量。)
此语句将失败:
k
考虑当m
为0时会发生什么。然后for
将for (int k = i - 1; k <= i + 1 && k < height && k >= 0; k++)
初始化为-1。然后i
为假,因此测试int k = i - 1
为假,因此永远不会执行循环的主体,并且k
= 0的行中的所有像素均不更新。 / p>
您需要重新考虑代码的设计方式。显然,这是对边缘和拐角的尝试,从概念上讲,这涉及使用数组外部像素进行计算,但是还有其他解决方案。这是此问题的重点,因此,考虑并实施两个或更多个解决方案将是一个很好的练习。
k >= 0
用于尝试k <= i + 1 && k < height && k >= 0
中的取幂。在C中,i
是XOR运算符。在这种情况下,要平方一个数字,只需将自己乘以^
。 C中有一个幂运算符,但是它用于浮点运算,因此不适合此问题,您将在另一课中学习它。
这些行:
(redx)^2
是^
和redx*redx
的内部循环,因此它们在处理每个像素时都会更新图像。这意味着尚未更新的像素将使用为先前更新的像素分配的新值。这是不正确的。计算新像素的值时,应使用原始的预更新值。为此,需要使用一个单独的缓冲区来临时保存新值。 (一个简单的解决方案是使用一个完整的单独数组来保存新值,但还有更多节省空间的解决方案。)
此代码取平方根并将其截断为整数:
image[i][j].rgbtRed = finalred;
image[i][j].rgbtGreen = finalgreen;
image[i][j].rgbtBlue = finalblue;
但是,problem specification说:“并且由于通道值只能采用0到255之间的整数值,因此请确保将结果值舍入为最接近的整数,然后
这样的代码出现多次:
i
根据这些循环的结构,j
只能等于finalred = sqrt((redx)^2 + (redy)^2);
,if (k < i)
{
if (m < j)
{
redx += image[k][m].rgbtRed * gx[0][0];
greenx += image[k][m].rgbtGreen * gx[0][0];
bluex += image[k][m].rgbtBlue * gx[0][0];
redy += image[k][m].rgbtRed * gy[0][0];
greeny += image[k][m].rgbtGreen * gy[0][0];
bluey += image[k][m].rgbtBlue * gy[0][0];
// gx[?][0]
}
或k
。因此,无需使用i-1
语句来选择数组的索引i
,i+1
或if
;我们可以简单地对其进行计算,并且对于0
类似地进行计算,然后对于所有情况,一组代码就足够了:
1
请注意,上面仍然存在处理边缘和拐角的问题。
这些初始化和重置是不必要的:
2
m
相反,只需在需要它们的位置定义这些变量即可;更改:
redx += image[k][m].rgbtRed * gx[k-(i-1)][m-(j-1)];
greenx += image[k][m].rgbtGreen * gx[k-(i-1)][m-(j-1)];
bluex += image[k][m].rgbtBlue * gx[k-(i-1)][m-(j-1)];
redy += image[k][m].rgbtRed * gy[k-(i-1)][m-(j-1)];
greeny += image[k][m].rgbtGreen * gy[k-(i-1)][m-(j-1)];
bluey += image[k][m].rgbtBlue * gy[k-(i-1)][m-(j-1)];
收件人:
int finalred = 0;
int finalgreen = 0;
int finalblue = 0;
仅在需要变量时定义变量会限制变量的范围,从而限制了犯错的机会。这适用于上面的 finalred = 0;
finalgreen = 0;
finalblue = 0;
和相关变量:通过在每个像素代码中定义和初始化它们,它们的使用仅限于单个像素的计算,因此让总和累加到多个像素上的错误将产生无法制造。