Sobel 过滤器给出错误的结果 C++

Sobel filter gives wrong result C++

我正在尝试对图像进行 Sobel 运算,但结果总是翻转。这是我一直拥有的结果:

我的代码如下:

void MyMainWindow::clickButtonEdge() {
    int kx[3][3] = {-1, 0 , 1, -2, 0, 2, -1, 0, 1};
    int ky[3][3] = {1, 2, 1, 0, 0, 0, -1, -2, -1};

    QImage img(m_image_path.c_str());

    for(int y=1; y < img.height()-1; y++){
        for(int x = 1; x<img.width()-1; x++){
            int a = (QColor(img.pixel(x-1,y-1)).red() + QColor(img.pixel(x-1,y-1)).blue()
                    + QColor(img.pixel(x-1,y-1)).green())/3;
            int b = (QColor(img.pixel(x,y-1)).red() + QColor(img.pixel(x,y-1)).blue()
                    + QColor(img.pixel(x,y-1)).green())/3;
            int c = (QColor(img.pixel(x+1,y-1)).red() + QColor(img.pixel(x+1,y-1)).green()
                    + QColor(img.pixel(x+1,y-1)).blue())/3;
            int d = (QColor(img.pixel(x-1,y)).blue() + QColor(img.pixel(x-1,y)).green()
                    + QColor(img.pixel(x-1,y)).red())/3;
            int e = (QColor(img.pixel(x,y)).green() + QColor(img.pixel(x,y)).red() + QColor(img.pixel(x,y)).blue())/3;
            int f = (QColor(img.pixel(x+1,y)).blue() + QColor(img.pixel(x+1,y)).red()
                    + QColor(img.pixel(x+1,y)).green())/3;
            int g = (QColor(img.pixel(x-1,y+1)).green() + QColor(img.pixel(x-1,y+1)).red()
                    + QColor(img.pixel(x-1,y+1)).blue())/3;
            int h = (QColor(img.pixel(x,y+1)).blue() + QColor(img.pixel(x,y+1)).green()
                    + QColor(img.pixel(x,y+1)).red())/3;
            int i = (QColor(img.pixel(x+1,y+1)).red() + QColor(img.pixel(x+1,y+1)).green()
                    + QColor(img.pixel(x+1,y+1)).blue())/3;

            int matrix[3][3] = {a,b,c,d,e,f,g,h,i};

            int sumx = 0;
            int sumy = 0;

            for(int s=0; s<3; s++){
                for(int t=0; t<3; t++){
                    sumx = sumx + (matrix[s][t] * kx[s][t]);
                    sumy = sumy + (matrix[s][t] * kx[s][t]);
                }
            }

            int newValue = sqrt(pow(sumx, 2) + pow(sumy, 2));

            if(newValue < 0){
                newValue = 0;
            }
            if(newValue > 255){
                newValue = 255;
            }

            QColor test = QColor(img.pixel(x,y));



            test.setRed(newValue);
            test.setBlue(newValue);
            test.setGreen(newValue);

            img.setPixel(x, y, test.rgb());
        }
    }
    m_label_picture->setPixmap(QPixmap::fromImage(img));
}

我使用 Qt 和 C++

首先我制作了两个内核,分别命名为 kx 和 ky。

然后我加载图像并构建一个 for 循环结构,从我需要的像素周围的像素灰度值生成一个新矩阵(用于内核乘法),然后我也对kx 和 ky。 我真的不知道我的错误,... 感谢您的帮助!

它在哪个轴上翻转?原图是什么?我不确定这是否会解决问题,但您在这一行中乘以了错误的内核:

sumy = sumy + (matrix[s][t] * kx[s][t]);

您正在覆盖输入图像,然后使用覆盖值进行后续计算, 这将导致错误的结果。

为避免这种情况,您可以复制图像并将其用作目标。 (使用副本作为源更好,因为这样做可以减少复制, 但可以通过较少的代码更改来用作目的地)

您还使用 kx 进行 x 和 y 计算。

QImage img(m_image_path.c_str());
QImage out = img.copy(); /* add this */

for(int y=1; y < img.height()-1; y++){
    for(int x = 1; x<img.width()-1; x++){
        /* omitted, same as the original code */

        for(int s=0; s<3; s++){
            for(int t=0; t<3; t++){
                sumx = sumx + (matrix[s][t] * kx[s][t]);
                sumy = sumy + (matrix[s][t] * ky[s][t]); /* use ky, not kx */
            }
        }

        /* omitted, same as the original code */

        QColor test = QColor(img.pixel(x,y));



        test.setRed(newValue);
        test.setBlue(newValue);
        test.setGreen(newValue);

        out.setPixel(x, y, test.rgb()); /* modify out, not img */
    }
}

img = out; /* filter calculation is done, so update img */