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
相关产品推荐
相关产品推荐

