Edge detection with Laplacian Operator without using OpenCv laplacian inbuilt function.

Kalpanileo
5 min readAug 9, 2021

--

Edge detection is an image processing technique for finding the boundaries of images. Here we are going to go through the Laplacian method which is quite popular among edge detection methods.

if you are new to OpenCV please refer to the following document for required installation. we are not using the OpenCV inbuilt function for the Laplacian method to better understand this method.

Why do we use the Laplacian method?

When it comes to Images there are ramp edges, step edges, as in the below pictures.

different kinds of edges

It's easy to recognize the step edges, we can use a simple filter like successive difference operator which proceed only the first derivate to get the rate of change in colour levels of pixels.

When it comes to Ramp edges it isn’t easy to identify with the use of the difference of colour values of neighbouring pixels. So we have to find the second derivative to recognize those edges. here we get “the rate of change of rate of change” of the colour levels.

Here As we circled in the above picture, it is negative, zero, positive or positive, zero, negative. So we can easily recognize these kinds of edges. When we use 2nd derivative.

When it comes to the Laplacian filter what we do is finding the 2nd derivative concerning x and y.

Ultimately we can derive metrics as below.

The laplacian function is highly sensitive to noises so that when we are applying this Laplacian filter. It's better if we can reduce the noise .and we can use Zero crossing property to avoid those issues.

When it comes to Laplacian of gaussian, It is an operator which combines the Laplacian operator and the gaussian operator, Here It will process gaussian smoothing first and then computing the Laplacian

By applying the 5 by 5 convolutional kernel below, we can get the results of the Laplacian of Gaussians.

Laplacian of Gaussians Matrics

Now let's see the practical examples of using these matrices for edge detection.

Please refer to the code

Code Explanation

Mat img = imread(argv[1], 1);if (!img.data) {cout << "Could not find the image!" << endl;
return -1;
}
int height = img.rows;int width = img.cols;Mat gr(height, width, CV_8UC1, Scalar(0));cvtColor(img, gr, COLOR_BGR2GRAY);Mat gr2(height, width, CV_8UC1, Scalar(0));
cvtColor(img, gr2, COLOR_BGR2GRAY);

Here we read the image and get the relevant data like the height of the image and width of the image. in the if the condition is used to give a message if the image doesn’t exist.

Then we create grey images gr, gr2

Mat output = gr.clone();Mat output4 = gr.clone();Mat output3(height, width, CV_8UC1, Scalar(0));

Here creating images to display outputs.

for (int i = 1; i < height - 1; i++) {for (int j = 1; j < width - 1; j++) {#laplacian filter without considering diagonal pixels int sum2 = 1 * gr.at<uchar>(i + 1, j) +
1 * gr.at<uchar>(i - 1, j) +
1 * gr.at<uchar>(i, j + 1) +
1 * gr.at<uchar>(i, j - 1) +
(-4 * gr.at<uchar>(i, j));
#laplacian filter with diagonal pixelsint sum = (-1 * gr.at<uchar>(i + 1, j)) +
(-1 * gr.at<uchar>(i - 1, j)) +
(-1 * gr.at<uchar>(i, j + 1)) +
(-1 * gr.at<uchar>(i, j - 1)) +
(-1 * gr.at<uchar>(i - 1, j - 1)) +
(-1 * gr.at<uchar>(i + 1, j + 1)) +
(-1 * gr.at<uchar>(i - 1, j + 1)) +
(-1 * gr.at<uchar>(i + 1, j - 1)) +
(8 * gr.at<uchar>(i, j));
output3.at<uchar>(i, j) = cv::saturate_cast<uchar>
(sum);output.at<uchar>(i, j) = cv::saturate_cast<uchar>(sum2);
}
}

Here, Looping the pixels to apply the Laplacian, and applying Laplacian for orthogonal pixels (sum2), then applying Laplacian for considering both orthogonal and diagonal pixels (sum)

In cv::saturate_cast<uchar>(sum);

What we do is normalizing the data . here when we directly assign the value like below

output.at<uchar>(y, x) = sum;

Then there will be values with

255 + 255 + 255 + 255–4 * 0 = 1020

0 + 0 + 0 + 0–4 * 255 = -1020

To normalize these values between 0 to 255, we use saturate_cast.

#gray picture without laplacian 
namedWindow("Gray Image");
imshow("Gray Image", gr);
#showing and writing the image with Laplacian for orthogonal and diagonal pixels
namedWindow("laplace diagonal");
imshow("laplace diagonal", output3);
imwrite("laplacian_diagonal.png", output3);
#showing and writing the image with Laplacian for orthogonal pixels
namedWindow("laplace orthogonal");
imshow("laplace orthogonal", output);
imwrite("laplacian_orthogonal.png", output);

Here, using the above code we have displayed and saved the images generated.

Output Images

Laplacian applied for orthogonal pixels.
Laplacian applied for orthogonal and diagonal pixels

Laplacian of Gaussians

int sum3 = 0;for (int i = 2; i < height - 2; i++) {   for (int j = 2; j < width - 2;j++) {       // calculate laplacian with guassian smoothing           sum3 = 2 * gr2.at<uchar>(i, j + 1) +
2 * gr2.at<uchar>(i, j - 1) +
2 * gr2.at<uchar>(i + 1, j) +
2 * gr2.at<uchar>(i - 1, j) +
gr2.at<uchar>(i, j + 2) +
gr2.at<uchar>(i, j - 2) +
gr2.at<uchar>(i + 2, j) +
gr2.at<uchar>(i - 2, j) +
gr2.at<uchar>(i - 1, j + 1) +
gr2.at<uchar>(i + 1, j + 1) +
gr2.at<uchar>(i + 1, j - 1) +
gr2.at<uchar>(i - 1, j - 1) -
16 * gr2.at<uchar>(i, j);
output4.at<uchar>(i, j) = cv::saturate_cast<uchar>(sum3);
}
}

Here we start with “i” and “j” from value 2 to avoid errors that occur when the values are out of bounds.

Output Image

Laplacian of Gaussians

Conclusion

Here it's visible that Laplacian of gaussian which is also known as Mexican hat kernel usage can detect edges well than the other two Laplacian kernels.

--

--

Kalpanileo
Kalpanileo

Written by Kalpanileo

I am a enthusiastic IT Graduate of University of Moratuwa . seeking for Knowledge and interested in new Technologies

No responses yet