我已经被这个函数卡住好几天了。我看了别人的问题,我看了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;
主要问题是您忘记在每次外循环迭代后重置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
,即使整个循环都是无用的,因为r
是无效的,它将一直保持这种状态,直到最里面的环路完成,r
递增。
为了提高效率,无论何时r
无效,都应该使用break
-
if (r < 0 || r > height - 1)
{
break;
}
if (c > -1 && c < 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;
}