首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CS50 PSET4边缘函数不正确过滤边缘和角红像素值

CS50 PSET4边缘函数不正确过滤边缘和角红像素值
EN

Stack Overflow用户
提问于 2022-06-14 10:51:20
回答 1查看 110关注 0票数 0

我试图用Sobel算子在图像中编写一个边缘检测函数。这是CS50课程中问题集4-过滤器(更多)的一部分.链接这里 (仅边缘部分)。

所编写的函数是正确地过滤图像的中间像素,但没有为边缘和边框像素提供所需的输出,而对于红色像素值(只有)来说,这一点太令人惊讶了,其余的都是正确的。

我已经手动检查了代码,调试了几次,但仍然找不到bug。任何帮助都将不胜感激。

谢谢。

这是边缘函数的代码。

代码语言:javascript
复制
// 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功能代码。

代码语言:javascript
复制
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函数的代码。

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

发布于 2022-06-15 09:24:43

所以我被困了这么久的问题终于解决了。在上述代码中(在Gx和Gy函数中),我在RGBTRIPLE类型的new_matrix中附加了绿色、蓝色、红色的值。当浮子的值可能大于8位时,它只能占用8位。对于这个问题,我定义了一个新的结构:

代码语言:javascript
复制
typedef struct
{
    float  rgbtBlu;
    float  rgbtGree;
    float  rgbtRe;
} __attribute__((__packed__))
RGBFTRIPLE;

并将new_matrix()类型从RGBTRIPLE更改为RGBFTRIPLE,从而使获取更大的值成为可能。这解决了问题。

感谢整个社会对这几个问题的回答,并消除了我的疑虑。

代码语言:javascript
复制
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72615705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档