我试图用Sobel算子在图像中编写一个边缘检测函数。这是CS50课程中问题集4-过滤器(更多)的一部分.链接这里 (仅边缘部分)。
所编写的函数是正确地过滤图像的中间像素,但没有为边缘和边框像素提供所需的输出,而对于红色像素值(只有)来说,这一点太令人惊讶了,其余的都是正确的。
我已经手动检查了代码,调试了几次,但仍然找不到bug。任何帮助都将不胜感激。
谢谢。
这是边缘函数的代码。
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// Array for storing corresponding gx values of the pixels.
RGBTRIPLE(*gx)[width] = calloc(height, width * sizeof(RGBTRIPLE));
if (gx == NULL)
{
printf("Not enough memory to store blur pixels.\n");
return;
}
// Array for storing corresponding gy values of the pixels.
RGBTRIPLE(*gy)[width] = calloc(height, width * sizeof(RGBTRIPLE));
if (gy == NULL)
{
printf("Not enough memory to store blur pixels.\n");
return;
}
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
Gx(row, col, height, width, image, gx);
Gy(row, col, height, width, image, gy);
}
}
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
image[row][col].rgbtBlue = r_sqrt_sum(gx[row][col].rgbtBlue, gy[row][col].rgbtBlue);
image[row][col].rgbtGreen = r_sqrt_sum(gx[row][col].rgbtGreen, gy[row][col].rgbtGreen);
image[row][col].rgbtRed = r_sqrt_sum(gx[row][col].rgbtRed, gy[row][col].rgbtRed);
}
}
free(gx);
free(gy);
return;
}Gx和Gy功能代码。
void Gx(int row, int col, int height, int width, RGBTRIPLE matrix[height][width], RGBTRIPLE new_matrix[height][width])
// This function will return Gx value of a given pixel.
{
float Blue = 0;
float Green = 0;
float Red = 0;
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
// for rows and columns out of range.
if ((i + row) < 0 || (i + row >= height) || (j + col) < 0 || (j + col >= width))
{
continue;
}
// for (-1,-1) and (1,-1)
else if ((i == -1 && j == -1) || (i == 1 && j == -1))
{
Blue += matrix[i + row][j + col].rgbtBlue * -1;
Green += matrix[i + row][j + col].rgbtGreen * -1;
Red += matrix[i + row][j + col].rgbtRed * -1;
}
// for (0,-1)
else if ((i == 0 && j == -1))
{
Blue += matrix[i + row][j + col].rgbtBlue * -2;
Green += matrix[i + row][j + col].rgbtGreen * -2;
Red += matrix[i + row][j + col].rgbtRed * -2;
}
// for (-1, 0) , (0, 0), (1, 0)
else if ((i == -1 && j == 0) || (i == 0 && j == 0) || (i == 1 && j == 0))
{
Blue += matrix[i + row][j + col].rgbtBlue * 0;
Green += matrix[i + row][j + col].rgbtGreen * 0;
Red += matrix[i + row][j + col].rgbtRed * 0;
}
// for (0, 1)
else if ((i == 0 && j == 1))
{
Blue += matrix[i + row][j + col].rgbtBlue * 2;
Green += matrix[i + row][j + col].rgbtGreen * 2;
Red += matrix[i + row][j + col].rgbtRed * 2;
}
// for (-1,1) and (1,1)
else if ((i == -1 && j == 1) || (i == 1 && j == 1))
{
Blue += matrix[i + row][j + col].rgbtBlue * 1;
Green += matrix[i + row][j + col].rgbtGreen * 1;
Red += matrix[i + row][j + col].rgbtRed * 1;
}
}
}
new_matrix[row][col].rgbtBlue = fabsf(Blue);
new_matrix[row][col].rgbtGreen = fabsf(Green);
new_matrix[row][col].rgbtRed = fabsf(Red);
}
void Gy(int row, int col, int height, int width, RGBTRIPLE matrix[height][width], RGBTRIPLE new_matrix[height][width])
// This function will return Gy value of a given pixel.
{
float Blue = 0;
float Green = 0;
float Red = 0;
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
// for rows and columns out of range.
if ((i + row) < 0 || (i + row >= height) || (j + col) < 0 || (j + col >= width))
{
continue;
}
// for (-1,-1) and (-1,1)
else if ((i == -1 && j == -1) || (i == -1 && j == 1))
{
Blue += matrix[i + row][j + col].rgbtBlue * -1;
Green += matrix[i + row][j + col].rgbtGreen * -1;
Red += matrix[i + row][j + col].rgbtRed * -1;
}
// for (-1, 0)
else if ((i == -1 && j == 0))
{
Blue += matrix[i + row][j + col].rgbtBlue * -2;
Green += matrix[i + row][j + col].rgbtGreen * -2;
Red += matrix[i + row][j + col].rgbtRed * -2;
}
// for (0, -1) , (0, 0), (0, 1)
else if ((i == 0 && j == -1) || (i == 0 && j == 0) || (i == 0 && j == 1))
{
// printf("for (%d, %d) considering (%d, %d) and using -1 \n", row, col, row+i, col+j);
Blue += matrix[i + row][j + col].rgbtBlue * 0;
Green += matrix[i + row][j + col].rgbtGreen * 0;
Red += matrix[i + row][j + col].rgbtRed * 0;
}
// for (1, 0)
else if ((i == 1 && j == 0))
{
Blue += matrix[i + row][j + col].rgbtBlue * 2;
Green += matrix[i + row][j + col].rgbtGreen * 2;
Red += matrix[i + row][j + col].rgbtRed * 2;
}
// for (1,-1) and (1,1)
else if ((i == 1 && j == -1) || (i == 1 && j == 1))
{
Blue += matrix[i + row][j + col].rgbtBlue * 1;
Green += matrix[i + row][j + col].rgbtGreen * 1;
Red += matrix[i + row][j + col].rgbtRed * 1;
}
}
}
new_matrix[row][col].rgbtBlue = fabsf(Blue);
new_matrix[row][col].rgbtGreen = fabsf(Green);
new_matrix[row][col].rgbtRed = fabsf(Red);
}r_sqrt_sum函数的代码。
int r_sqrt_sum(float a, float b)
// Return rounded sqrt of sum of squared a and b.
{
float x = round(sqrt((a*a + b*b)));
if (x > 255) return 255;
else return x;
}发布于 2022-06-15 09:24:43
所以我被困了这么久的问题终于解决了。在上述代码中(在Gx和Gy函数中),我在RGBTRIPLE类型的new_matrix中附加了绿色、蓝色、红色的值。当浮子的值可能大于8位时,它只能占用8位。对于这个问题,我定义了一个新的结构:
typedef struct
{
float rgbtBlu;
float rgbtGree;
float rgbtRe;
} __attribute__((__packed__))
RGBFTRIPLE;并将new_matrix()类型从RGBTRIPLE更改为RGBFTRIPLE,从而使获取更大的值成为可能。这解决了问题。
感谢整个社会对这几个问题的回答,并消除了我的疑虑。
https://stackoverflow.com/questions/72615705
复制相似问题