CS50 PSET4图像模糊函数求助:编译正常但输出不符合预期
Fixing Your CS50 PSET4 Blur Function Issues
Hey there! I see you're stuck on the blur function for CS50's PSET4—compiling works, but the output isn't right. Let's walk through what's wrong with your two code versions and get you a working solution.
What's Wrong With Your First Code Version
- Incomplete Neighborhood Coverage: Your approach splits the 3x3 blur area into separate horizontal and vertical checks, which means you're missing diagonal pixels (like
i-1, j-1ori+1, j+1). This gives a partial, incorrect blur effect. - Double-Counting the Current Pixel: You add the current pixel's values at the start, then again at the end of the calculation—plus it might get counted again in the horizontal/vertical loops. This skews the average color values.
- Invalid Pixel Count: The
totalvariable starts at 1 and increments for every valid horizontal/vertical pixel, then you add another 1 at the end. This leads to a wrong denominator when calculating averages.
What's Wrong With Your Second Code Version
- Stuck Loop Variable: The
kvariable is initialized once perjloop. After the first iteration of thelloop,kreaches 2 and never resets, so subsequentliterations won't run the innerkloop. You end up missing most neighborhood pixels. - Incomplete Boundary Checks: You only verify if
x >= 0andy >= 0, but don't check ifx < heightory < width. This means you might try to access pixels outside the image (like wheniis the last row,x = i - lcould equalheight, which is out of bounds). - Overwriting Original Pixels: You modify the original
imagearray while calculating the blur. Later pixels end up using already blurred values instead of the original ones, leading to a distorted result.
The Correct Approach
To fix this, we need to:
- Create a copy of the original image: This ensures we always use unmodified pixel values for our blur calculations.
- Properly iterate over the full 3x3 neighborhood: For each pixel, check all 8 surrounding pixels plus itself, making sure each is within the image bounds.
- Calculate averages accurately: Sum valid neighbor values, divide by the number of valid neighbors, then round to set the new pixel value.
Working Blur Function Code
#include <math.h> #include "helpers.h" // Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { // Create a copy of the original image to preserve unmodified values RGBTRIPLE copy[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { copy[i][j] = image[i][j]; } } // Iterate over each pixel in the original image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { double sum_red = 0; double sum_green = 0; double sum_blue = 0; int valid_neighbors = 0; // Loop through all 3x3 surrounding pixels for (int di = -1; di <= 1; di++) { for (int dj = -1; dj <= 1; dj++) { int x = i + di; int y = j + dj; // Check if the neighbor is within image boundaries if (x >= 0 && x < height && y >= 0 && y < width) { sum_red += copy[x][y].rgbtRed; sum_green += copy[x][y].rgbtGreen; sum_blue += copy[x][y].rgbtBlue; valid_neighbors++; } } } // Calculate and assign blurred values to the original image image[i][j].rgbtRed = round(sum_red / valid_neighbors); image[i][j].rgbtGreen = round(sum_green / valid_neighbors); image[i][j].rgbtBlue = round(sum_blue / valid_neighbors); } } return; }
Key Notes About This Code
- Image Copy: The
copyarray stores the original pixel data, so we never modify the values we're using to compute the blur. - Full 3x3 Coverage: The
dianddjloops cover all 9 possible positions around the current pixel (from-1to1in both directions). - Strict Boundary Checks: The
ifstatement ensures we only process pixels that exist within the image's height and width. - Accurate Averaging: We sum only valid neighbors, divide by the exact count of those neighbors, and round to get the final integer color values.
内容的提问来源于stack exchange,提问作者PrO-jAn Sha-Kya
相关产品推荐
相关产品推荐

