c-CS50模糊滤波器在小的测试用例中给出了不正确的输出



我正在为CS50中的过滤器任务编写均值模糊过滤器(更舒适的版本(。当我用我的一些照片测试它时,它似乎工作得很好。然而,当我用CS50测试用例测试它时,它给出了小矩阵的错误结果。下面是我的代码

#define KERNEL_HEIGHT 3
#define KERNEL_WIDTH 3
#define KERNEL_SIZE 9
#define CORNER 4
#define EDGE 6
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// height and width are the height and width of the input image.
RGBTRIPLE(*extension)[width + 2] = calloc(height + 2, (width + 2) * sizeof(RGBTRIPLE)); // I will handle edge and corner cases by creating a new 2d array with 0s around 
RGBTRIPLE(*newImage)[width] = calloc(height, width * sizeof(RGBTRIPLE)); //output 
int cof = 0, redSum = 0, greenSum = 0, blueSum = 0;
int kernel[3][3] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; // Kernel for mean blur
if (newImage == NULL || extension == NULL)
{
fprintf(stderr, "Not enough memory to create a new image.n");
return;
}
for(int i = 0; i < height; ++i)
{
memcpy(extension[i + 1], image[i], sizeof(image[i])); // Copy values from original images into extension, note that I intentionally copy at the i + 1 position.
}
for(int i = 1; i < height + 1; ++i)
{
for(int j = 1; j < width + 1; ++j)
{
redSum = 0; greenSum = 0; blueSum = 0; //Reset red, green, blue sum values.
for(int k = 0; k < KERNEL_HEIGHT; ++k)
{
for(int t = 0; t < KERNEL_WIDTH; ++t) 
{
cof = kernel[k][t]; // I will multiply each value in the kernel with the pixel value and its neighbors.
redSum += cof * extension[i - 1 + k][j - 1 + t].rgbtRed;
greenSum += cof * extension[i - 1 + k][j - 1 + t].rgbtGreen;
blueSum += cof * extension[i - 1 + k][j - 1 + t].rgbtBlue;
}
}
if(i == 1 || i == height) // Detecting edge cases and corner
{
if(j == 1 || j == width) // Corner
{
newImage[i - 1][j - 1].rgbtRed = (int) round((float) redSum / (float) CORNER);
newImage[i - 1][j - 1].rgbtGreen = (int) round((float) greenSum / (float) CORNER);
newImage[i - 1][j - 1].rgbtBlue = (int) round((float) blueSum / (float) CORNER);
}
else // Edges
{
newImage[i - 1][j - 1].rgbtRed = (int) round((float) redSum / (float) EDGE);
newImage[i - 1][j - 1].rgbtGreen = (int) round((float) greenSum / (float) EDGE);
newImage[i - 1][j - 1].rgbtBlue = (int) round((float) blueSum / (float) EDGE);
}
}
else //Normal cases
{
newImage[i - 1][j - 1].rgbtRed = (int) round((float) redSum / (float) KERNEL_SIZE);
newImage[i - 1][j - 1].rgbtGreen = (int) round((float) greenSum / (float) KERNEL_SIZE);
newImage[i - 1][j - 1].rgbtBlue = (int) round((float) blueSum / (float) KERNEL_SIZE);
}
}
}
for(int i = 0; i < height; ++i)
{
memcpy(image[i], newImage[i], sizeof(newImage[i])); // Copy back the results into my original image.
}
free(extension);
free(newImage);
return;
}

这是测试用例之一:
使用样本3x3图像进行测试(过滤中间像素(
第一行:(10,20,30(,(40,50,60(,(70,80,90(
第二行:(110,130,140(,(120,140,150(,(130,150,160(
1第三行:(200,210,220(,(220,230,240(,(240,250,255(

预期输出:127 140 149
实际输出:91 100 106

我已经尝试修复这个功能(gg搜索,阅读文档(好几天了,仍然没有结果。我认为这与我如何为扩展矩阵分配内存以及如何遍历它有关。我对动态内存分配很陌生,所以这可能是我错的地方。

我不喜欢这样做,有更多时间会重新访问,但。。。以下内容未经测试且故意不完整,仅用作风格指南。

我将发布BlurPixel((的大部分内容,向您展示如何以逻辑方式处理每个像素。注意,我们没有疯狂的索引,每一次写入都由if语句进行边界检查。

int r=0, g=0, b=0;  // Sums accumulators
int numElements = 0; // Counts number of items accumulated.
// Loop from 1 less to 1 more than the current X and Y position.
for(int xOffset=-1; xOffset<=1; xOffset++)
{
for(int yOffset=-1; yOffset<=1; yOffset++)
{
const int newX = x + xOffset;
const int newY = y + yOffset;
// Bounds check... 
if(newX >= 0 && newX < width &&
newY >= 0 && newY < height) 
{
// In range, add to accumulators and increment element counter.
r += image[newY][newX].red;
g += image[newY][newX].green;
b += image[newY][newX].blue;
numElements++;
}
}
}  
// Assign the rounded values to the new structure.  Could do this with integers
// if we added numElements/2 to list before divide.
newImage[j][i].red = (int)round((float) r / numElements);
newImage[j][i].green = (int)round((float) g / numElements);
newImage[j][i].blue = (int)round((float) b / numElements);

最新更新