【问题标题】:How to implement Sobel operatorSobel算子如何实现
【发布时间】:2018-01-16 20:50:36
【问题描述】:

我已经实现了垂直方向的 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);

}

我对算法的输入是

我的输出是

在实际卷积图像之前,我也尝试过使用高斯模糊,我得到的输出是

我期待的输出是

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

【问题讨论】:

  • 说实话,我觉得还不错。在运行 Sobel 之前,尝试在图像上应用高斯模糊。这应该可以消除一些颠簸。
  • 我确实尝试过使用高斯模糊,但它对我不起作用。输出在上方突出显示
  • 下次请慢慢来,输入您的代码作为代码,而不是图像,以便其他人可以复制。
  • 谢谢@Piglet。我已经编辑了我的文档。但我不确定它是如何工作的

标签: vision


【解决方案1】:

您的卷积看起来不错,虽然我只是快速浏览了一下。

检查您的输出类型。它是无符号字符。

现在考虑一下如果内核值为负数时输出像素可能具有的值,以及将它们直接存储在 uchar 中是否是个好主意。

如果您将 -1 存储在 unsigned char 中,它将被环绕,并且您的输出为 255。如果您想知道所有多余的白色东西是从哪里来的。这实际上是很小的负梯度。

所需的结果看起来像 Sobel 输出值的绝对值。

【讨论】:

  • 那么你能建议我该怎么做@Piglet 以及你对 sobel 的绝对值有何看法
  • @Abhishek 如果您的数学技能如此糟糕,您不应该进行图像处理或任何编程。 en.wikipedia.org/wiki/Absolute_value
  • @Abhishek 我不是故意粗鲁的。这只是一个建议。你让你的编程生活变得比必要的更难。这就像你只知道5个字母时读一本书。你将无法理解这个故事,也不会完全享受它。你为什么认为我在大学图像处理研究中花了 4 年时间学习了 90% 的数学?一个数字的绝对值是它的“正版本”。 -1 变成 1,1 仍然是 1,0 是 0。 - 5 是 5……你不能在屏幕上显示负数,所以你必须以某种方式修改它们。例如通过显示它们的绝对值。
  • 你好@Piglet。如果您至少可以拥有最低限度的常识,不会使他人失去动力和批评他人,那就太好了。如果您不想回答,那么您最好选择不回答。仅仅通过告诉某人不要在诸如堆栈溢出之类的平台上学习编程语言或图像处理课程来辱骂某人是令人发指的罪行。我知道我对你很粗鲁,但我只是觉得你应该设身处地为自己设想。如果您对此感到难过,请见谅。顺便感谢您发布的答案。查看 Be nice 的链接。 stackoverflow.com/help/be-nice
  • @Abhishek 如果您在某处读到绝对值并且不知道它的含义,那么您应该做的第一件事是在网络上搜索该术语。如果我只是给你正确的代码行,你会使用它并且永远不会再考虑它,因此你不会学到任何东西。如果你走进手术室,开始毫无头绪地切开病人,然后问他们血压是什么意思,你认为医生会怎么说?
猜你喜欢
  • 2018-01-31
  • 1970-01-01
  • 2021-06-02
  • 2022-01-23
  • 2021-08-31
  • 2017-06-20
  • 2017-01-12
  • 2014-04-18
  • 2019-12-04
相关资源
最近更新 更多