You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言边缘检测函数异常:多数RGB值为255的问题排查

边缘检测函数异常排查:多数像素RGB值变为255

开发边缘检测函数时,自认为逻辑概念无误,但运行结果不符合预期——多数像素的RGB值变为255。尝试过调整数据类型、变更变量声明位置,问题仍未解决;小型测试代码运行正常,但整合后结果异常,恳请帮忙排查原因。

代码实现

typedef struct {
    int Red;
    int Green;
    int Blue;
} GTOTALS;

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    const int MAX = 3;

    // Copy Image
    RGBTRIPLE Copy[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            Copy[i][j] = image[i][j];
        }
    }

    // Gx and Gy Grids 3 x 3
    int Gx[MAX][MAX] = {
        {-1, 0, 1},
        {-2, 0, 2},
        {-1, 0, 1}
    };
    int Gy[MAX][MAX] = {
        {-1, -2, -1},
        {0, 0, 0},
        {1, 2, 1}
    };

    // Loop through each pixel
    for (int Rows = 0; Rows < height; Rows++)
    {
        for (int Cols = 0; Cols < width; Cols++)
        {
            // Hold RGB Values + Refresh Current Pixel RGB
            int CRed = 0, CGreen = 0, CBlue = 0;
            // Store Gx and Gy RGB Values
            GTOTALS X;
            GTOTALS Y;

            // Loop through surrouding pixels
            for (int S_Rows = Rows - 1, R = 0; S_Rows <= Rows + 1; S_Rows++, R++)
            {
                for (int S_Cols = Cols - 1, C = 0; S_Cols <= Cols + 1; S_Cols++, C++)
                {
                    // Check Pixel Validity
                    if ((S_Rows >= 0) && (S_Rows < height) && (S_Cols >= 0) && (S_Cols < width))
                    {
                        // RGB Gx Total Values
                        X.Red += Copy[S_Rows][S_Cols].rgbtRed * Gx[R][C];     // Current Pixel Red * Gx[N][N]
                        X.Green += Copy[S_Rows][S_Cols].rgbtGreen * Gx[R][C]; // Current Pixel Green * Gx[N][N]
                        X.Blue += Copy[S_Rows][S_Cols].rgbtBlue * Gx[R][C];   // Current Pixel Blue * Gx[N][N]

                        // RGB Gy Total Values
                        Y.Red += Copy[S_Rows][S_Cols].rgbtRed * Gy[R][C];     // Current Pixel Red * Gy[N][N]
                        Y.Green += Copy[S_Rows][S_Cols].rgbtGreen * Gy[R][C]; // Current Pixel Green * Gy[N][N]
                        Y.Blue += Copy[S_Rows][S_Cols].rgbtBlue * Gy[R][C];   // Current Pixel Blue * Gy[N][N]
                    }
                }
            }

            // Value = Square Root(Gx^2 + Gy^2)
            CRed = round( sqrt( pow(X.Red, 2.0) + pow(Y.Red, 2.0) ) );
            CGreen = round( sqrt( pow(X.Green, 2.0) + pow(Y.Green, 2.0) ) );
            CBlue = round( sqrt( pow(X.Blue, 2.0) + pow(Y.Blue, 2.0) ) );

            // MAX 255
            Cap(&CRed);
            Cap(&CGreen);
            Cap(&CBlue);

            // Update Target Pixel
            image[Rows][Cols].rgbtRed = CRed;
            image[Rows][Cols].rgbtGreen = CGreen;
            image[Rows][Cols].rgbtBlue = CBlue;
        }
    }

    return;
}


void Cap(int *Value)
{
    if (*Value > 255)
    {
        *Value = 255;
    }
}

核心问题与修复方案

  • 未初始化累加变量:这是导致多数像素变255的根本原因。GTOTALS X和GTOTALS Y声明后,其Red、Green、Blue成员未被初始化,会包含随机垃圾值。累加计算后,这些随机值会导致最终的CRed/CGreen/CBlue结果远大于255,被Cap函数强制设为255。
    修复方式:声明时直接初始化所有成员为0:

    GTOTALS X = {0, 0, 0};
    GTOTALS Y = {0, 0, 0};
    
  • 边界处理补充(非核心但影响精度):处理边缘像素时,超出图像范围的像素被跳过,但对应的卷积权重没有做归一化处理,会导致边缘区域的检测结果强度与非边缘区域不一致。可以在计算完成后,根据有效像素的数量对累加结果进行缩放,或者用镜像/填充0的方式处理边界像素。

  • 溢出风险提示:即使初始化变量后,RGB值(0-255)与权重(最大±2)累加后的范围是-2040到2040,平方后的值远大于255的平方,开根号后结果大概率超过255,因此多数像素仍会被Cap截断,但这是边缘检测的正常现象(边缘区域梯度值高),而非代码错误。

内容的提问来源于stack exchange,提问作者TedSnow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:55:20