实现Sobel算子

11

我正在尝试实现Sobel算子在水平和垂直方向上的运算。但是不知何故,我得到了相反的输出结果。我已经附上了以下代码。对于水平掩模:

char mask [3][3]=  {{-1,-2,-1},{0,0,0},{1,2,1}};

void masking(Mat image){

Mat temImage= image.clone();
for (int i = 1; i < image.rows-1; i++)
{
    for (int j = 1; j < image.cols-1; j++)
    {   
        for(int k=0;k<3;k++)
        {
            int pixel1 = image.at<Vec3b>(i-1,j-1)[k] * -1;
            int pixel2 = image.at<Vec3b>(i,j-1)[k] * -2;
            int pixel3 = image.at<Vec3b>(i+1,j-1)[k] * -1;

            int pixel4 = image.at<Vec3b>(i-1,j)[k] * 0;
            int pixel5 = image.at<Vec3b>(i,j)[k] * 0;
            int pixel6 = image.at<Vec3b>(i+1,j)[k] * 0;

            int pixel7 = image.at<Vec3b>(i-1,j+1)[k] * 1;
            int pixel8 = image.at<Vec3b>(i,j+1)[k] * 2;
            int pixel9 = image.at<Vec3b>(i+1,j+1)[k] * 1;

            int sum = pixel1 + pixel2 + pixel3 + pixel4 + pixel5 + pixel6 + pixel7 + pixel8 + pixel9;
            if(sum < 0)
            {
                sum = 0;
            }

            if(sum > 255)
                sum = 255;

            temImage.at<Vec3b>(i,j)[k] = sum;


        }
    }
}
//printf("conter = %d",counter);
imshow( "Display", temImage );
imwrite("output1.png",temImage);

}

我得到的输出是:

enter image description here

至于垂直掩模

char mask [3][3]=  {{-1,0,1},{-2,0,2},{-1,0,1}}; 

void masking(Mat image){

Mat temImage= image.clone();
for (int i = 1; i < image.rows-1; i++)
{
    for (int j = 1; j < image.cols-1; j++)
    {   
        for(int k=0;k<3;k++)
        {
            int pixel1 = image.at<Vec3b>(i-1,j-1)[k] * -1;
            int pixel2 = image.at<Vec3b>(i,j-1)[k] * 0;
            int pixel3 = image.at<Vec3b>(i+1,j-1)[k] * 1;

            int pixel4 = image.at<Vec3b>(i-1,j)[k] * -2;
            int pixel5 = image.at<Vec3b>(i,j)[k] * 0;
            int pixel6 = image.at<Vec3b>(i+1,j)[k] * 2;

            int pixel7 = image.at<Vec3b>(i-1,j+1)[k] * -1;
            int pixel8 = image.at<Vec3b>(i,j+1)[k] * 0;
            int pixel9 = image.at<Vec3b>(i+1,j+1)[k] * 1;

            int sum = pixel1 + pixel2 + pixel3 + pixel4 + pixel5 + pixel6 + pixel7 + pixel8 + pixel9;
            if(sum < 0)
            {
                sum = 0;
            }

            if(sum > 255)
                sum = 255;

            temImage.at<Vec3b>(i,j)[k] = sum;


        }
    }
}
//printf("conter = %d",counter);
imshow( "Display", temImage );
imwrite("output1.png",temImage);

}

我得到的输出是

enter image description here

以下是主要函数:
int main( int argc, char** argv ){
Mat input_image = imread("sobel1.jpg",1);
masking(input_image);
waitKey(0);
return 0;

}

根据https://www.tutorialspoint.com/dip/sobel_operator.htm指南,我应该获得反向输出。有人可以帮我吗?
原始图像为:

enter image description here


2
你说得对,教程是错的 :) 在 x 中应该看到垂直线,在 y 中应该看到水平线。在你的情况下,垂直是 y,水平是 x,请参见 维基百科 以了解我的意思(符号表示)。还可以查看此教程以查看输出。 - api55
您可以使用OpenCV的Sobel算子函数进行比较,其中xorder=1表示水平方向(yorder=0),yorder=1表示垂直方向(xorder=0)。 - api55
他们颠倒了顺序。请参见此处。http://homepages.inf.ed.ac.uk/rbf/HIPR2/sobel.htm - I.Newton
让我们小心使用“inversed”这个术语。对我来说,它暗示着一个大部分黑暗的图片会变成大部分亮度(反之亦然)。 - Yunnosch
@Yunnosch 我的意思是交换...所以垂直的图像应该变成水平的,反之亦然。 - api55
显示剩余8条评论
1个回答

1
不,该教程 没有错,它讨论的是蒙版而不是渐变。该教程的弱点在于它没有提到我们正在使用所谓的垂直蒙版来计算水平渐变。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接