如何实现Sobel运营商

时间:2017-08-09 05:55:35

标签: vision

我在垂直方向上实施了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 个答案:

答案 0 :(得分:1)

虽然我只是快速查看,但你的卷积看起来还不错。

检查输出类型。它是未签名的字符。

现在考虑输出像素可能具有的值,如果你有负内核值,并且最好将它们直接存储在uchar中。

如果你将-1存储在一个无符号的字符中,它将被包裹,你的输出是255.如果你想知道所有多余的白色东西来自哪里。这实际上是小的负梯度。

期望的结果看起来像Sobel输出值的绝对值。