如何实现Sobel算子

3

我在垂直方向上实现了Sobel算子。但是我得到的结果很差。我在下面附上了我的代码。

int mask_size= 3;

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

void sobel(Mat input_image)
{

/**Padding m-1 and n-1 zeroes to the result where m and n are mask_size**/

Mat result=Mat::zeros(input_image.rows+(mask_size - 1) * 2,input_image.cols+(mask_size - 1) * 2,CV_8UC1);
Mat result1=Mat::zeros(result.rows,result.cols,CV_8UC1);            
int sum= 0;

/*For loop for copying original values to new padded image **/

for(int i=0;i<input_image.rows;i++)
    for(int j=0;j<input_image.cols;j++)
        result.at<uchar>(i+(mask_size-1),j+(mask_size-1))=input_image.at<uchar>(i,j);

GaussianBlur( result, result, Size(5,5), 0, 0, BORDER_DEFAULT );
/**For loop to implement the convolution **/

for(int i=0;i<result.rows-(mask_size - 1);i++)
    for(int j=0;j<result.cols-(mask_size - 1);j++)
    {
        int counter=0;
        int counterX=0,counterY=0;
        sum= 0;
        for(int k= i ; k < i + mask_size ; k++)
        {
            for(int l= j ; l< j + mask_size ; l++)
            {
                sum+=result.at<uchar>(k,l) * mask[counterX][counterY];
                counterY++;
            }
            counterY=0;
            counterX++;
        }
        result1.at<uchar>(i+mask_size/2,j+mask_size/2)=sum/(mask_size * mask_size);
    }

/** Truncating all the extras rows and columns **/

result=Mat::zeros( result1.rows  - (mask_size - 1) * 2, result1.cols - (mask_size - 1) * 2,CV_8UC1);
for(int i=0;i<result.rows;i++)
    for(int j=0;j<result.cols;j++)                      
        result.at<uchar>(i,j)=result1.at<uchar>(i+(mask_size - 1),j+(mask_size - 1));

imshow("Input",result);
imwrite("output2.tif",result);

}

我的算法输入是enter image description here

我的输出是enter image description here

我也尝试在卷积图像之前使用高斯模糊,得到的输出是enter image description here

我期望的输出结果是enter image description here

我使用的指南是:https://www.tutorialspoint.com/dip/sobel_operator.htm


1
老实说,我觉得它看起来不错。在对其运行Sobel之前,尝试在图像上应用高斯模糊。这样可以平滑一些颗粒感。 - ljetibo
我尝试使用高斯模糊,但它对我没有起作用。输出如上所示。 - Abhishek
1
下次请耐心将您的代码输入为代码,而不是图片,这样其他人就可以复制它了。 - Piglet
谢谢 @Piglet。我已经编辑了我的文档。但是我不确定它是如何工作的。 - Abhishek
1个回答

1
你的卷积看起来还不错,尽管我只是快速浏览了一下。
检查一下你的输出类型,它是无符号字符。
现在考虑一下如果你有负的卷积核值,你的输出像素可能会有什么值,并且直接将它们存储在uchar中是否是一个好主意。
如果你把-1存储在无符号字符中,它将被包装并且你的输出将是255。如果你想知道那些多余的白色东西来自哪里,那实际上是小的负梯度。
期望的结果看起来像Sobel输出值的绝对值。

那么,@Piglet,请您建议我该做什么,以及Sobel的绝对值是什么意思? - Abhishek
@Abhishek,如果你的数学技能如此糟糕,就不应该进行图像处理或任何编程。https://en.wikipedia.org/wiki/Absolute_value - Piglet
1
@Abhishek 我并不是有意冒犯。这只是一条建议。你让自己的编程生涯变得比必要的更加困难。这就像你只认识五个字母时阅读一本书。你将无法理解故事,也永远无法完全享受它。你为什么认为我在大学的图像处理学习中花了四年时间学习90%的数学?一个数的绝对值是它的“正向版本”。-1 变成 1,1 保持为 1,0 是 0。-5 是 5 ... 你不能在屏幕上显示负数,所以你必须以某种方式修改它们。例如通过显示它们的绝对值。 - Piglet
你好@Piglet。如果你至少有最基本的常识,不去打击和批评别人,那就太好了。如果你不想回答,那么最好选择不这样做。在像Stack Overflow这样的平台上,仅仅通过辱骂某人告诉他们不要学习编程语言或图像处理课程是一种可耻的罪行。我知道我对你很粗鲁,但我只是觉得你应该站在别人的角度思考并为自己想象。如果你感到不舒服,我很抱歉。顺便说一句,感谢你发布的答案。请查看“友善”链接。https://stackoverflow.com/help/be-nice - Abhishek
1
@Abhishek,如果你在某个地方看到了绝对值(absolute value)一词但不知道它的含义,首先应该做的是在网上搜索这个术语。如果我仅仅给你正确的代码行,你会使用它,然后再也不会想起它,因此你将学不到任何东西。如果你毫无头绪地走进手术室开始乱切患者,然后问医生血压是什么意思,你认为医生会怎么说呢? - Piglet

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