Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Sobel edge detection Implementation

I am trying to implement sobel edge detection from scratch but my output can't seem to match with OpenCV's sobel function. I performed correlation on the image with the sobel operator in both x and y directions and then computed gradient as square root of sum of squares of magnitudes in both x & y direction. I believe the problem is how I assign the threshold for edge detection.

Code-

#include <iostream>
#include <bits/stdc++.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp" 
#include <opencv2/objdetect/objdetect.hpp>
#include <math.h>

using namespace cv; 
using namespace std; 

int main()
{
// Reading image
Mat img = imread("1.jpg");


// Blurring and Converting to grayscale
Mat img_gray,image_blur;
GaussianBlur( img, image_blur, Size(5,5), 3, 3);
    cvtColor(image_blur,img_gray,CV_RGB2GRAY);

int cols = img_gray.cols;
int rows = img_gray.rows;

// Creating sobel operator in x direction
int sobel_x[3][3] = {-1,0,1,-2,0,2,-1,0,1};
// Creating sobel operator in y direction
int sobel_y[3][3] = {-1,-2,-1,0,0,0,1,2,1};


int radius = 1;

// Handle border issues
Mat _src;
copyMakeBorder(img_gray, _src, radius, radius, radius, radius, BORDER_REFLECT101);

// Create output matrix
Mat gradient_x = img_gray.clone();
Mat gradient_y = img_gray.clone();
Mat gradient_f = img_gray.clone();

int max=0;

// Correlation loop in x direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_x[i + radius][j + radius];
            }
        }
        gradient_x.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}


// Conrrelation loop in y direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_y[i + radius][j + radius];
            }
        }

        gradient_y.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}




//Calculating gradient magnitude
for(int i=0; i<gradient_f.rows; i++)
{
    for(int j=0; j<gradient_f.cols; j++)
    {
        gradient_f.at<uchar>(i,j) = sqrt( pow(gradient_x.at<uchar>(i,j),2) + pow(gradient_y.at<uchar>(i,j),2) );  

         if(gradient_f.at<uchar>(i,j) >240)
            gradient_f.at<uchar>(i,j) = 100;
        else
            gradient_f.at<uchar>(i,j) = 0;
    }
}




imshow("grad magnitude",gradient_f);
waitKey(0);




cv::Mat Gx, Gy; int ksize=3;
Mat abs_grad_x, abs_grad_y;
cv::Sobel(img_gray, Gx, CV_8U, 1, 0, ksize);
convertScaleAbs( Gx, abs_grad_x );
cv::Sobel(img_gray, Gy, CV_8U, 0, 1, ksize);
convertScaleAbs( Gy, abs_grad_y );
Mat grad;
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

imshow("Sobel Image",grad);
waitKey(0);

return 0;

}

Sobel edge detection Implementation

I am trying to implement sobel edge detection from scratch but my output can't seem to match with OpenCV's sobel function. I performed correlation on the image with the sobel operator in both x and y directions and then computed gradient magnitude as square root of sum of squares of magnitudes in both x & y direction. I believe the problem is how I assign the threshold for edge detection.

Code-

#include <iostream>
#include <bits/stdc++.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp" 
#include <opencv2/objdetect/objdetect.hpp>
#include <math.h>

using namespace cv; 
using namespace std; 

int main()
{
// Reading image
Mat img = imread("1.jpg");


// Blurring and Converting to grayscale
Mat img_gray,image_blur;
GaussianBlur( img, image_blur, Size(5,5), 3, 3);
    cvtColor(image_blur,img_gray,CV_RGB2GRAY);

int cols = img_gray.cols;
int rows = img_gray.rows;

// Creating sobel operator in x direction
int sobel_x[3][3] = {-1,0,1,-2,0,2,-1,0,1};
// Creating sobel operator in y direction
int sobel_y[3][3] = {-1,-2,-1,0,0,0,1,2,1};


int radius = 1;

// Handle border issues
Mat _src;
copyMakeBorder(img_gray, _src, radius, radius, radius, radius, BORDER_REFLECT101);

// Create output matrix
Mat gradient_x = img_gray.clone();
Mat gradient_y = img_gray.clone();
Mat gradient_f = img_gray.clone();

int max=0;

// Correlation loop in x direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_x[i + radius][j + radius];
            }
        }
        gradient_x.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}


// Conrrelation loop in y direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_y[i + radius][j + radius];
            }
        }

        gradient_y.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}




//Calculating gradient magnitude
for(int i=0; i<gradient_f.rows; i++)
{
    for(int j=0; j<gradient_f.cols; j++)
    {
        gradient_f.at<uchar>(i,j) = sqrt( pow(gradient_x.at<uchar>(i,j),2) + pow(gradient_y.at<uchar>(i,j),2) );  

         if(gradient_f.at<uchar>(i,j) >240)
            gradient_f.at<uchar>(i,j) = 100;
        else
            gradient_f.at<uchar>(i,j) = 0;
    }
}




imshow("grad magnitude",gradient_f);
waitKey(0);




cv::Mat Gx, Gy; int ksize=3;
Mat abs_grad_x, abs_grad_y;
cv::Sobel(img_gray, Gx, CV_8U, 1, 0, ksize);
convertScaleAbs( Gx, abs_grad_x );
cv::Sobel(img_gray, Gy, CV_8U, 0, 1, ksize);
convertScaleAbs( Gy, abs_grad_y );
Mat grad;
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

imshow("Sobel Image",grad);
waitKey(0);

return 0;

}

Sobel edge detection Implementation

I am trying to implement sobel edge detection from scratch but my output can't seem to match with OpenCV's sobel function. I performed correlation on the image with the sobel operator in both x and y directions and then computed gradient magnitude as square root of sum of squares of magnitudes in both x & y direction. I believe the problem is how I assign the threshold for edge detection.

Code-

#include <iostream>
#include <bits/stdc++.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp" 
#include <opencv2/objdetect/objdetect.hpp>
#include <math.h>

using namespace cv; 
using namespace std; 

int main()
{
// Reading image
Mat img = imread("1.jpg");


// Blurring and Converting to grayscale
Mat img_gray,image_blur;
GaussianBlur( img, image_blur, Size(5,5), 3, 3);
    cvtColor(image_blur,img_gray,CV_RGB2GRAY);

int cols = img_gray.cols;
int rows = img_gray.rows;

// Creating sobel operator in x direction
int sobel_x[3][3] = {-1,0,1,-2,0,2,-1,0,1};
// Creating sobel operator in y direction
int sobel_y[3][3] = {-1,-2,-1,0,0,0,1,2,1};


int radius = 1;

// Handle border issues
Mat _src;
copyMakeBorder(img_gray, _src, radius, radius, radius, radius, BORDER_REFLECT101);

// Create output matrix
Mat gradient_x = img_gray.clone();
Mat gradient_y = img_gray.clone();
Mat gradient_f = img_gray.clone();

int max=0;

// Correlation loop in x direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_x[i + radius][j + radius];
            }
        }
        gradient_x.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}


// Conrrelation loop in y direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_y[i + radius][j + radius];
            }
        }

        gradient_y.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}




//Calculating gradient magnitude
for(int i=0; i<gradient_f.rows; i++)
{
    for(int j=0; j<gradient_f.cols; j++)
    {
        gradient_f.at<uchar>(i,j) = sqrt( pow(gradient_x.at<uchar>(i,j),2) + pow(gradient_y.at<uchar>(i,j),2) );  

         if(gradient_f.at<uchar>(i,j) >240)
            gradient_f.at<uchar>(i,j) = 100;
        else
            gradient_f.at<uchar>(i,j) = 0;
    }
}




imshow("grad magnitude",gradient_f);
waitKey(0);




cv::Mat Gx, Gy; int ksize=3;
Mat abs_grad_x, abs_grad_y;
cv::Sobel(img_gray, Gx, CV_8U, 1, 0, ksize);
convertScaleAbs( Gx, abs_grad_x );
cv::Sobel(img_gray, Gy, CV_8U, 0, 1, ksize);
convertScaleAbs( Gy, abs_grad_y );
Mat grad;
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

imshow("Sobel Image",grad);
waitKey(0);

return 0;

}

Images-

1.Original Image-

image description

2.My implementation of Sobel Edge Detection - image description

3.Opencv Sobel edge function output - image description

Sobel edge detection Implementation

I am trying to implement sobel edge detection from scratch but my output can't seem to match with OpenCV's sobel function. I performed correlation on the image with the sobel operator in both x and y directions and then computed gradient magnitude as square root of sum of squares of magnitudes in both x & y direction. I believe the problem is how I assign the threshold for edge detection.

Images-

1.Original Image-

image description

2.My implementation of Sobel Edge Detection - image description

3.Opencv Sobel edge function output - image description

Code-

#include <iostream>
#include <bits/stdc++.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp" 
#include <opencv2/objdetect/objdetect.hpp>
#include <math.h>

using namespace cv; 
using namespace std; 

int main()
{
// Reading image
Mat img = imread("1.jpg");


// Blurring and Converting to grayscale
Mat img_gray,image_blur;
GaussianBlur( img, image_blur, Size(5,5), 3, 3);
    cvtColor(image_blur,img_gray,CV_RGB2GRAY);

int cols = img_gray.cols;
int rows = img_gray.rows;

// Creating sobel operator in x direction
int sobel_x[3][3] = {-1,0,1,-2,0,2,-1,0,1};
// Creating sobel operator in y direction
int sobel_y[3][3] = {-1,-2,-1,0,0,0,1,2,1};


int radius = 1;

// Handle border issues
Mat _src;
copyMakeBorder(img_gray, _src, radius, radius, radius, radius, BORDER_REFLECT101);

// Create output matrix
Mat gradient_x = img_gray.clone();
Mat gradient_y = img_gray.clone();
Mat gradient_f = img_gray.clone();

int max=0;

// Correlation loop in x direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_x[i + radius][j + radius];
            }
        }
        gradient_x.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}


// Conrrelation loop in y direction 

// Iterate on image 
for (int r = radius; r < _src.rows - radius; ++r)
{
    for (int c = radius; c < _src.cols - radius; ++c)
    {
        int s = 0;

        // Iterate on kernel
        for (int i = -radius; i <= radius; ++i)
        {
            for (int j = -radius; j <= radius; ++j)
            {
                s += _src.at<uchar>(r + i, c + j) * sobel_y[i + radius][j + radius];
            }
        }

        gradient_y.at<uchar>(r - radius, c - radius) = s/30;

        /*if(s>200)
            gradient.at<uchar>(r - radius, c - radius) = 255;
        else
            gradient.at<uchar>(r - radius, c - radius) = 0;
        */    
    }
}




//Calculating gradient magnitude
for(int i=0; i<gradient_f.rows; i++)
{
    for(int j=0; j<gradient_f.cols; j++)
    {
        gradient_f.at<uchar>(i,j) = sqrt( pow(gradient_x.at<uchar>(i,j),2) + pow(gradient_y.at<uchar>(i,j),2) );  

         if(gradient_f.at<uchar>(i,j) >240)
            gradient_f.at<uchar>(i,j) = 100;
        else
            gradient_f.at<uchar>(i,j) = 0;
    }
}




imshow("grad magnitude",gradient_f);
waitKey(0);




cv::Mat Gx, Gy; int ksize=3;
Mat abs_grad_x, abs_grad_y;
cv::Sobel(img_gray, Gx, CV_8U, 1, 0, ksize);
convertScaleAbs( Gx, abs_grad_x );
cv::Sobel(img_gray, Gy, CV_8U, 0, 1, ksize);
convertScaleAbs( Gy, abs_grad_y );
Mat grad;
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

imshow("Sobel Image",grad);
waitKey(0);

return 0;

}

Images-

1.Original Image-

image description

2.My implementation of Sobel Edge Detection - image description

3.Opencv Sobel edge function output - image description