我已经被这个功能困扰了好几天了。我看了别人的问题,看了YouTube教程视频,但听不清。 该任务是哈佛大学CS50课程(https://cs50.harvard.edu/x/2020/psets/4/filter/less/)的一部分。 任何帮助将不胜感激!我真的不想在不理解问题所在的情况下继续学习该课程。
//check if pixels are valid
bool valid_pixel(int r, int c, int height, int width)
{
return r >= 0 && c >= 0 && r < height && c < width;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
//create a copy of the original image
RGBTRIPLE temp[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp[i][j] = image[i][j];
}
}
int red, green, blue, count;
red = green = blue = count = 0;
//iterate through rows
for (int i = 0; i < height; i++)
{
//iterate through columns
for (int j = 0; j < width; j++)
{
//move one pixel up to one pixel down in the rows
for (int r = i - 1; r <= i + 1; r++)
{
//move one pixel left to one pixel right in the columns
for (int c = j - 1; c <= j + 1; c++)
{
//check if they are unvalid pixels
if (valid_pixel(r, c, height, width))
{
//count every valid pixel
count ++;
//"store" every pixel color
red += image[r][c].rgbtRed;
green += image[r][c].rgbtGreen;
blue += image[r][c].rgbtBlue;
}
}
}
//calculate average values
temp[i][j].rgbtRed = round((float)red / count);
temp[i][j].rgbtGreen = round((float)green / count);
temp[i][j].rgbtBlue = round((float)blue / count);
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j] = temp[i][j];
}
}
return;
答案 0 :(得分:0)
主要问题是,每次外部循环迭代后,您忘记重置red
,blue
和green
变量(您总结)。您应该将此行放入主循环内-
red = green = blue = count = 0;
此外,您还将图像复制到另一个临时图像中,最后再次将该临时图像复制到原始图像中。这是非常低效的。首先,您不应该将像素从原始图像复制到模糊图像。您可以将修改后的值直接放入此临时映像中。最后,使用memmove
一次将整个行有效地移动到原始图像。 (请记住#include <string.h>
)
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE blurred_img[height][width];
//iterate through rows
for (int i = 0; i < height; i++)
{
//iterate through columns
for (int j = 0, red, green, blue, count; j < width; j++)
{
// Reset the variables
red = blue = green = count = 0;
//move one pixel up to one pixel down in the rows
for (int r = i - 1; r <= i + 1; r++)
{
//move one pixel left to one pixel right in the columns
for (int c = j - 1; c <= j + 1; c++)
{
//check if they are unvalid pixels
if (valid_pixel(r, c, height, width))
{
//count every valid pixel
count++;
//"store" every pixel color
red += image[r][c].rgbtRed;
green += image[r][c].rgbtGreen;
blue += image[r][c].rgbtBlue;
}
}
}
//calculate average values
blurred_img[i][j].rgbtRed = round((float)red / count);
blurred_img[i][j].rgbtGreen = round((float)green / count);
blurred_img[i][j].rgbtBlue = round((float)blue / count);
}
}
for (int i = 0; i < height; i++)
{
// Copy the new image over to the original, row by row
memmove(image[i], blurred_img[i], sizeof(RGBTRIPLE) * width);
}
return;
}
这是假设valid_pixel
是正确的。要确定像素位置是否有效,您可以执行以下操作-
if (k > 0 && k < height && l > -1 && l < width))
但是请注意,当r
(行)无效时,最里面的循环(列循环)仍会迭代直到c == width
,即使该循环的整个过程都是无用的,因为{{1} }是无效的,它将一直保持这种状态,直到最内层的循环完成并且r
递增为止。
为了提高效率,只要r
无效,就应该break
-
r