C语言Sobel边缘检测函数失效求助:输出单一纯色无边缘
Sobel边缘检测代码问题分析与修复
核心问题
未初始化的邻域像素数组
redEdit、greenEdit、blueEdit这三个存储3x3邻域像素值的数组在声明后没有初始化,直接使用+=运算符累加像素值,导致数组初始值是内存中的随机垃圾数据,最终计算出的梯度值完全错误,这是输出纯色的核心原因。冗余的中间数组设计
你创建了redEditgx、redEditgy等多个中间数组存储乘积结果,其实可以直接在计算总和时完成乘积累加,减少内存占用和代码复杂度。另外pow(redSumgx, 2)可以替换为redSumgx * redSumgx,避免不必要的浮点函数调用。语法小瑕疵
matrixgy数组中的- 1存在多余空格,虽然多数编译器会忽略,但建议修正为-1以保持代码规范。
修正后的核心代码片段
void edges(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE edit[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { edit[i][j] = image[i][j]; } } for (int q = 1; q < height - 1; q++) { for (int w = 1; w < width - 1; w++) { // 初始化邻域数组为0,替代未初始化的垃圾值 int redEdit[9] = {0}; int greenEdit[9] = {0}; int blueEdit[9] = {0}; // 直接赋值邻域像素,不用+= for (int top = 0; top < 3; top++) { redEdit[top] = edit[q - 1][w - 1 + top].rgbtRed; greenEdit[top] = edit[q - 1][w - 1 + top].rgbtGreen; blueEdit[top] = edit[q - 1][w - 1 + top].rgbtBlue; } int midctr = 0; for (int mid = 3; mid < 6; mid++) { redEdit[mid] = edit[q][w - 1 + midctr].rgbtRed; greenEdit[mid] = edit[q][w - 1 + midctr].rgbtGreen; blueEdit[mid] = edit[q][w - 1 + midctr].rgbtBlue; midctr++; } int topctr = 0; for (int top = 6; top < 9; top++) { redEdit[top] = edit[q + 1][w - 1 + topctr].rgbtRed; greenEdit[top] = edit[q + 1][w - 1 + topctr].rgbtGreen; blueEdit[top] = edit[q + 1][w - 1 + topctr].rgbtBlue; topctr++; } // 修正matrixgy的空格问题 int matrixgx[] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; int matrixgy[] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; // 直接计算梯度总和,省略中间乘积数组 int redSumgx = 0, greenSumgx = 0, blueSumgx = 0; int redSumgy = 0, greenSumgy = 0, blueSumgy = 0; for (int mtrx = 0; mtrx < 9; mtrx++) { redSumgx += redEdit[mtrx] * matrixgx[mtrx]; greenSumgx += greenEdit[mtrx] * matrixgx[mtrx]; blueSumgx += blueEdit[mtrx] * matrixgx[mtrx]; redSumgy += redEdit[mtrx] * matrixgy[mtrx]; greenSumgy += greenEdit[mtrx] * matrixgy[mtrx]; blueSumgy += blueEdit[mtrx] * matrixgy[mtrx]; } // 用整数乘法替代pow,避免不必要的浮点运算 int finalRed = round(sqrt((double)(redSumgx * redSumgx) + (double)(redSumgy * redSumgy))); int finalGreen = round(sqrt((double)(greenSumgx * greenSumgx) + (double)(greenSumgy * greenSumgy))); int finalBlue = round(sqrt((double)(blueSumgx * blueSumgx) + (double)(blueSumgy * blueSumgy))); // 截断超出255的像素值 finalRed = finalRed > 255 ? 255 : finalRed; finalGreen = finalGreen > 255 ? 255 : finalGreen; finalBlue = finalBlue > 255 ? 255 : finalBlue; image[q][w].rgbtRed = finalRed; image[q][w].rgbtGreen = finalGreen; image[q][w].rgbtBlue = finalBlue; } } return; }
内容的提问来源于stack exchange,提问作者Jourvence
相关产品推荐
相关产品推荐

