我的模糊功能表现异常。我已经从check50重新创建了3x3位图,以便从测试中获得更多近似结果,但是由于某些原因,每个右边缘或下边缘像素均无法正常工作。
在调试时,由于某种原因,我发现我的for循环运行不正常。我将在下面显示我的代码和示例。
代码:
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE temp[height][width]; // Declares temporary structure to avoid overwriting of original values while running loops
// For loop to set the value of i, rows or height
for (int i = 0; i < height; i++)
{
// For loop to set the value of j, columns or width
for (int j = 0; j < width; j++)
{
float counter = 0.0;
int sumRed = 0;
int sumGreen = 0;
int sumBlue = 0;
// For loop to set the value of k, to get surrounding pixels
for (int k = -1; k < 2; k++)
{
for (int m = -1; m < 2; m++)
{
if ((i - k) >= 0 && (i - k) < height && (j - m) >= 0 && (j - m) < width)
{
sumRed = sumRed + image[i - k][j - m].rgbtRed; // Adds the value of verified pixel to the sum
sumGreen = sumGreen + image[i - k][j - m].rgbtGreen;
sumBlue = sumBlue + image[i - k][j - m].rgbtBlue;
counter++; // To get the average
}
}
}
temp[i][j].rgbtRed = round(sumRed / counter); // Sets new color based on average of surrounding pixels
temp[i][j].rgbtGreen = round(sumGreen / counter);
temp[i][j].rgbtBlue = round(sumBlue / counter);
}
}
// Start new loops to switch original values with temp values
for (int i = 0; i < height - 1; i++)
{
for (int j = 0; j < width - 1; j++)
{
image[i][j].rgbtRed = temp[i][j].rgbtRed;
image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
}
}
return;
}
这是 output。
作为我在调试过程中发现的示例,我们可以这样说:
i = 0
j = 2
k = 0
m = 0
在这里,不是从sumRed
获取image[0 - 0][2 - 0] (RGB 70, 80, 90)
的值,而是从image[2][2] (RGB 240, 250, 255)
获取值。
我尚未测试其他错误情况,但我想那里正在发生类似的情况。
任何帮助将不胜感激。
答案 0 :(得分:1)
这是我的最高评价的开头:
如果
counter
是int
,可能会更好。然后,执行:round((double) sumRed / counter)
,但是,输出单元只有8位。您可能需要:sumRed = round((double) sumRed / counter); temp[i][j].rgbtRed = (sumRed < 255) ? sumRed : 255;
这是饱和度数学。否则,当您分配给8位单元时,它是模数学,等效于sumRed % 256
。这将产生257 --> 1
(接近黑色)而不是257 --> 255
(明亮的红色)
您最大的问题是卷积内核索引计算不正确。
代替:
(i - k)
(j - m)
您要
(i + k)
(j + m)
此外,您从temp
复制到image
的最终循环的限制为1。
此外,我将使用更多描述性变量。而且,您的代码可以简化一些。这是包含错误修复的重构版本:
#include <math.h>
typedef struct {
unsigned char rgbtRed;
unsigned char rgbtGreen;
unsigned char rgbtBlue;
} __attribute__((__packed__)) RGBTRIPLE;
// Blur image
void
blur(int height, int width, RGBTRIPLE image[height][width])
{
// Declares temporary structure to avoid overwriting of original values
// while running loops
RGBTRIPLE temp[height][width];
#if 1
RGBTRIPLE *tmp;
RGBTRIPLE *img;
#endif
// For loop to set the value of yctr, rows or height
for (int yctr = 0; yctr < height; yctr++) {
// For loop to set the value of xctr, columns or width
for (int xctr = 0; xctr < width; xctr++) {
#if 0
float counter = 0.0;
#else
int counter = 0;
#endif
int sumRed = 0;
int sumGreen = 0;
int sumBlue = 0;
// For loop to set the value of yoff, to get surrounding pixels
for (int yoff = -1; yoff < 2; yoff++) {
// NOTE/BUG: this is the main bug
#if 0
int ycur = yctr - yoff;
#else
int ycur = yctr + yoff;
#endif
if (ycur < 0)
continue;
if (ycur >= height)
continue;
for (int xoff = -1; xoff < 2; xoff++) {
// NOTE/BUG: this is the main bug
#if 0
int xcur = xctr - xoff;
#else
int xcur = xctr + xoff;
#endif
if (xcur < 0)
continue;
if (xcur >= width)
continue;
// Adds the value of verified pixel to the sum
tmp = &image[ycur][xcur];
sumRed += tmp->rgbtRed;
sumGreen += tmp->rgbtGreen;
sumBlue += tmp->rgbtBlue;
counter++; // To get the average
}
}
// Sets new color based on average of surrounding pixels
tmp = &temp[yctr][xctr];
#if 0
tmp->rgbtRed = round(sumRed / counter);
tmp->rgbtGreen = round(sumGreen / counter);
tmp->rgbtBlue = round(sumBlue / counter);
#else
sumRed = round((double) sumRed / counter);
tmp->rgbtRed = (sumRed < 255) ? sumRed : 255;
sumGreen = round((double) sumGreen / counter);
tmp->rgbtGreen = (sumGreen < 255) ? sumGreen : 255;
sumBlue = round((double) sumBlue / counter);
tmp->rgbtBlue = (sumBlue < 255) ? sumBlue : 255;
#endif
}
}
// Start new loops to switch original values with temp values
// NOTE/BUG: the for loop ranges are incorrect
#if 0
for (int yctr = 0; yctr < height - 1; yctr++) {
for (int xctr = 0; xctr < width - 1; xctr++) {
image[yctr][xctr].rgbtRed = temp[yctr][xctr].rgbtRed;
image[yctr][xctr].rgbtGreen = temp[yctr][xctr].rgbtGreen;
image[yctr][xctr].rgbtBlue = temp[yctr][xctr].rgbtBlue;
}
}
#endif
#if 0
for (int yctr = 0; yctr < height; yctr++) {
for (int xctr = 0; xctr < width; xctr++) {
image[yctr][xctr] = temp[yctr][xctr];
}
}
#endif
#if 1
tmp = &temp[0][0];
img = &image[0][0];
int idxlim = width * height;
for (int idxcur = 0; idxcur < idxlim; idxcur++)
img[idxcur] = tmp[idxcur];
#endif
}