function - 为什么我的 CS50 过滤器边缘代码不适用于 check50?
问题描述
我的 cs50 过滤器边缘功能不起作用,它可以编译,但是当我运行 check50 时,第一个测试(边缘正确过滤中间像素)我们是正确的,而其他的只是最后一个值不正确,如下所示:
:( 边缘正确过滤边缘上的像素,预期为“213 228 255\n”,而不是“213 228 140\n”
但是,当我单独打印红色、绿色和蓝色的 gx 和 gy 以及平方根的值时,颜色的值都不匹配。
现在,这是我的边缘代码
void edges(int height, int width, RGBTRIPLE image[height][width])
{
int sr = 0;
int sb = 0;
int sg = 0;
int yr = 0;
int yb = 0;
int yg = 0;
struct RGBTRIPle
{
int rgbtRed;
int rgbtGreen;
int rgbtBlue;
};
struct RGBTRIPle copia[height][width];
struct RGBTRIPLe
{
int rgbtRed;
int rgbtGreen;
int rgbtBlue;
};
struct RGBTRIPLe copia2[height][width];
//Implementing Gx
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
sr = 0;
sb = 0;
sg = 0;
for (int m = i - 1; m <= i + 1; m++)
{
for (int c = j - 1; c <= j + 1; c++)
{
if (m >= 0 && m < height && c >= 0 && c < width)
{
if (c == j - 1)
{
if (m == i - 1 || m == i + 1)
{
sr += -1 * image[m][c].rgbtRed;
sb += -1 * image[m][c].rgbtBlue;
sg += -1 * image[m][c].rgbtGreen;
}
else
{
sr += -2 * image[m][c].rgbtRed;
sb += -2 * image[m][c].rgbtBlue;
sg += -2 * image[m][c].rgbtGreen;
}
}
if (c == j + 1)
{
if (m == i - 1 || m == i + 1)
{
sr += image[m][c].rgbtRed;
sb += image[m][c].rgbtBlue;
sg += image[m][c].rgbtGreen;
}
else
{
sr += 2 * image[m][c].rgbtRed;
sb += 2 * image[m][c].rgbtBlue;
sg += 2 * image[m][c].rgbtGreen;
}
}
else //c = j
{
sr += 0 * image[m][c].rgbtRed;
sb += 0 * image[m][c].rgbtBlue;
sg += 0 * image[m][c].rgbtGreen;
}
}
}
}
copia[i][j].rgbtRed = sr;
copia[i][j].rgbtGreen = sg;
copia[i][j].rgbtBlue = sb;
}
}
//Implementing Gy
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
yr = 0;
yb = 0;
yg = 0;
for (int m = i - 1; m <= i + 1; m++)
{
for (int c = j - 1; c <= j + 1; c++)
{
if (m >= 0 && m < height && c >= 0 && c < width)
{
if (m == i - 1)
{
if (c == j - 1 || c == j + 1)
{
yr += -1 * image[m][c].rgbtRed;
yb += -1 * image[m][c].rgbtBlue;
yg += -1 * image[m][c].rgbtGreen;
}
else
{
yr += -2 * image[m][c].rgbtRed;
yb += -2 * image[m][c].rgbtBlue;
yg += -2 * image[m][c].rgbtGreen;
}
}
if (m == i + 1)
{
if (c == j + 1 || c == j - 1)
{
yr += image[m][c].rgbtRed;
yb += image[m][c].rgbtBlue;
yg += image[m][c].rgbtGreen;
}
else
{
yr += 2 * image[m][c].rgbtRed;
yb += 2 * image[m][c].rgbtBlue;
yg += 2 * image[m][c].rgbtGreen;
}
}
else //c = j
{
yr += 0 * image[m][c].rgbtRed;
yb += 0 * image[m][c].rgbtBlue;
yg += 0 * image[m][c].rgbtGreen;
}
}
}
}
copia2[i][j].rgbtRed = yr;
copia2[i][j].rgbtGreen = yg;
copia2[i][j].rgbtBlue = yb;
}
}
//Implementing math operation to calculate resulting color
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int r = 0;
int g = 0;
int b = 0;
image[i][j].rgbtRed = (int) round(sqrt((copia[i][j].rgbtRed * copia[i][j].rgbtRed) + (copia2[i][j].rgbtRed *
copia2[i][j].rgbtRed)));
image[i][j].rgbtGreen = (int) round(sqrt((copia[i][j].rgbtGreen * copia[i][j].rgbtGreen) + (copia2[i][j].rgbtGreen *
copia2[i][j].rgbtGreen)));
image[i][j].rgbtBlue = (int) round(sqrt((copia[i][j].rgbtBlue * copia[i][j].rgbtBlue) + (copia2[i][j].rgbtBlue *
copia2[i][j].rgbtBlue)));
r = image[i][j].rgbtRed;
g = image[i][j].rgbtGreen;
b = image[i][j].rgbtBlue;
if (image[i][j].rgbtRed > 255)
{
image[i][j].rgbtRed = 255;
}
if (image[i][j].rgbtGreen > 255)
{
image[i][j].rgbtGreen = 255;
}
if (image[i][j].rgbtBlue > 255)
{
image[i][j].rgbtBlue = 255;
}
}
}
return;
}
解决方案
round(sqrt((copia[i][j].rgbtRed * copia[i][j].rgbtRed) + (copia2[i][j].rgbtRed *copia2[i][j].rgbtRed)));
当您存储到变量image[i][j].rgbtRed
(或其任何其他变体)中时,就会出现您描述的问题。这是因为在计算 sqrt(gx^2 + gy^2) 时会得到一个大于 255 的数字。例如,四舍五入后可能会得到整数值 395。为了将该值存储到 中image[i][j].rgbtRed
,C 将存储 395 % 255 或 140 的值,因为根据定义,图像不能存储大于 255 的值。
这意味着您的 if 语句是无用的,因为相应的颜色值永远不会大于 255:
if (image[i][j].rgbtRed > 255)
{
image[i][j].rgbtRed = 255;
}
if (image[i][j].rgbtGreen > 255)
{
image[i][j].rgbtGreen = 255;
}
if (image[i][j].rgbtBlue > 255)
{
image[i][j].rgbtBlue = 255;
}
要解决这个问题,您必须在将它们存储到图像之前限制值。一个简单的实现是通过创建一个名为 cap 的函数,如果输入高于 255,则返回 255。:
int cap(int rgb)
{
if (rgb > 255)
{
return 255;
}
else
{
return rgb;
}
}
然后您可以通过以下方式使用此功能,这将彻底解决您的问题:
image[i][j].rgbtRed = cap(round(sqrt((copia[i][j].rgbtRed * copia[i][j].rgbtRed) + (copia2[i][j].rgbtRed * copia2[i][j].rgbtRed))));
image[i][j].rgbtGreen = cap(round(sqrt((copia[i][j].rgbtGreen * copia[i][j].rgbtGreen) + (copia2[i][j].rgbtGreen * copia2[i][j].rgbtGreen))));
image[i][j].rgbtBlue = cap(round(sqrt((copia[i][j].rgbtBlue * copia[i][j].rgbtBlue) + (copia2[i][j].rgbtBlue * copia2[i][j].rgbtBlue))));
这也将缩短您的代码,使其看起来更干净,并避免不必要的重复。
推荐阅读
- sql - 选择分区数据时的巨大差异
- docker-compose - 将变量从 Ansible playbook 传递到 docker_compose 任务
- python - python asyncio aws 承担角色无法异步运行
- python - 如何将其四舍五入到小数点后 4 位
- flutter - 有什么办法可以在下拉菜单中的项目中添加更多项目?
- c++ - 错误:未在此范围内声明“板”(C++)
- regex - 从 XML 中删除特定项目
- database - 在 Windows 10 上下载 MariaDB 列存储
- ios - 推送通知是否在 IOS 上受到限制和定价?
- python - 格式化 dask.diagnostics 进度条