avatarChinmay Bhalerao

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

5575

Abstract

images-1.readmedium.com/v2/resize:fit:800/1*xe61MWFm3iFmimcdYFiTIw.png"><figcaption><a href="https://www.google.com/search?q=Sobel+x+and+y+matrix&amp;sxsrf=APq-WBuLx3DF7NMrMxUKwv0MfriLqCjZ-Q:1643608371623&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ved=2ahUKEwiMwY-pptv1AhUIUWwGHQMNDosQ_AUoAXoECAEQAw&amp;biw=1280&amp;bih=520&amp;dpr=1.5">Kernels for X and Y direction</a></figcaption></figure><div id="c5d3"><pre><span class="hljs-comment">#sobel edge detection</span> <span class="hljs-comment">#we can provide minimum and maximum threshold according to our need</span></pre></div><div id="dbd7"><pre><span class="hljs-keyword">import</span> cv2</pre></div><div id="1d43"><pre><span class="hljs-comment"># Read the original image</span></pre></div><div id="45f0"><pre><span class="hljs-attr">img</span> = cv2.imread(<span class="hljs-string">'Enter your image address with extension'</span>)</pre></div><div id="eeec"><pre><span class="hljs-meta"># Display original image</span></pre></div><div id="462d"><pre><span class="hljs-selector-id">#cv2</span><span class="hljs-selector-class">.imshow</span>(<span class="hljs-string">'Original'</span>, img)</pre></div><div id="8663"><pre><span class="hljs-attr">#cv2</span>.waitKey<span class="hljs-comment">(0)</span></pre></div><div id="c2d2"><pre><span class="hljs-meta"># Convert to graycsale</span></pre></div><div id="da1f"><pre><span class="hljs-attr">img_gray</span> = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)</pre></div><div id="cb8e"><pre><span class="hljs-comment"># Blur the image for better edge detection</span></pre></div><div id="de8f"><pre><span class="hljs-attribute">img_blur</span> = cv2.GaussianBlur(img_gray, (<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), <span class="hljs-number">0</span>)</pre></div><div id="7efa"><pre><span class="hljs-meta"># Sobel Edge Detection</span></pre></div><div id="907b"><pre>sobelx = cv2.Sobel(<span class="hljs-attribute">src</span>=img_blur, <span class="hljs-attribute">ddepth</span>=cv2.CV_64F, <span class="hljs-attribute">dx</span>=1, <span class="hljs-attribute">dy</span>=0, <span class="hljs-attribute">ksize</span>=5) # Sobel Edge Detection on the X axis</pre></div><div id="2a66"><pre>sobely = cv2.Sobel(<span class="hljs-attribute">src</span>=img_blur, <span class="hljs-attribute">ddepth</span>=cv2.CV_64F, <span class="hljs-attribute">dx</span>=0, <span class="hljs-attribute">dy</span>=1, <span class="hljs-attribute">ksize</span>=5) # Sobel Edge Detection on the Y axis</pre></div><div id="17f8"><pre>sobelxy = cv2.Sobel(<span class="hljs-attribute">src</span>=img_blur, <span class="hljs-attribute">ddepth</span>=cv2.CV_64F, <span class="hljs-attribute">dx</span>=1, <span class="hljs-attribute">dy</span>=1, <span class="hljs-attribute">ksize</span>=5) # Combined X <span class="hljs-keyword">and</span> Y Sobel Edge Detection</pre></div><div id="54e7"><pre><span class="hljs-comment"># Display Sobel Edge Detection Images</span></pre></div><div id="c423"><pre><span class="hljs-selector-id">#cv2</span><span class="hljs-selector-class">.imshow</span>(<span class="hljs-string">'Sobel X'</span>, sobelx)</pre></div><div id="1ece"><pre><span class="hljs-attr">#cv2</span>.waitKey<span class="hljs-comment">(0)</span></pre></div><div id="9888"><pre><span class="hljs-selector-id">#cv2</span><span class="hljs-selector-class">.imshow</span>(<span class="hljs-string">'Sobel Y'</span>, sobely)</pre></div><div id="408d"><pre><span class="hljs-attr">#cv2</span>.waitKey<span class="hljs-comment">(0)</span></pre></div><div id="cdfc"><pre><span class="hljs-selector-id">#cv2</span><span class="hljs-selector-class">.imshow</span>(<span class="hljs-string">'Sobel X Y using Sobel() function'</span>, sobelxy)</pre></div><div id="ebfb"><pre>#cv2.waitKey(<span class="hljs-number">0</span>) #########################################################</pre></div><div id="6645"><pre><span class="hljs-comment">#If we want to scratch code Sobel edge detection,</span></pre></div><div id="8f31"><pre>import numpy as np import cv2 import matplotlib<span class="hljs-selector-class">.pyplot</span> as plt vertical_filter = <span class="hljs-selector-attr">[[-1,-2,-1]</span>,<span class="hljs-selector-attr">[0,0,0]</span>,<span class="hljs-selector-attr">[1,2,1]</span>] horizontal_filter = <span class="hljs-selector-attr">[[-1,0,1]</span>,<span class="hljs-selector-attr">[-2,0,2]</span>,<span class="hljs-selector-attr">[-1,0,1]</span>] <span class="hljs-selector-tag">img</span> = plt<span class="hljs-selector-class">.imread</span>(<span class="hljs-string">"enter your image address"</span>) n,m,d = <span class="hljs-selector-tag">img</span><span class="hljs-selector-class">.shape</span> edges_img = np<span class="hljs-selector-class">.zeros_like</span>(img)</pre></div><div id="82ac"><pre><span class="hljs-attribute">for</span> row in range(<span class="hljs-number">3</span>,n-<span class="hljs-number">2</span>): <span class="hljs-attribute">for</span> col in range(<span class="hljs-number">3</span>,m-<span class="hljs-number">2</span>): <span class="hljs-attribute">local_pixels</span> = img[row-<span class="hljs-number">1</span>:row+<span class="hljs-number">2</span>,col-<span class="hljs-number">1</span>:col+<span class="hljs-number">2</span>, <span class="hljs-number">0</span>]

    <span class="hljs-attribute">vertical_transformed_pixels</span> = vertical_filter*local_pixels
    <span class="hljs-attribute">vertical_score</span> = vertical_transformed_pixels.sum()/<span class="hljs-number">4</s

Options

pan>

    <span class="hljs-attribute">horizontal_transformed_pixels</span> = horizontal_filter*local_pixels
    <span class="hljs-attribute">horizontal_score</span> = horizontal_transformed_pixels.sum()/<span class="hljs-number">4</span>
    
    <span class="hljs-attribute">edge_score</span> = (vertical_score**<span class="hljs-number">2</span> + horizontal_score**<span class="hljs-number">2</span>)**.<span class="hljs-number">5</span>
    <span class="hljs-attribute">edges_img</span>[row,col] =<span class="hljs-meta"> [edge_score]*3

edges_img = edges_img/edges_img.max()</span></pre></div><div id="498a"><pre>plt.imshow<span class="hljs-comment">(edges_img)</span></pre></div><figure id="9c7e"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*YAyVDj-a3kRPTKJAQ_LXaA.jpeg"><figcaption></figcaption></figure><figure id="c70d"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*b6WX2XPhzv7ilWaZQI-dXg.jpeg"><figcaption></figcaption></figure><figure id="6e51"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*sVAIZxIGJRr6PcMrrlwHew.jpeg"><figcaption>1)Sobel-X 2)Sobel-XY 3)Sobel-Y</figcaption></figure><p id="029e"><b>3) By ROI</b></p><p id="5082"><b>ROI</b> stands for <b>RIGION OF INTREST</b> . As usual we firstly convert image into gray scaled image. Defining and removing boundary is main purpose of code. For recognizing contours, we take advantage of inbuilt function in cv2 that is “<i>cv2.findContours”.</i></p><div id="d185"><pre><span class="hljs-comment">#edge detection on the basis of ROI</span></pre></div><div id="84bb"><pre>bgr = cv2.imread('your image path with extension') gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY) _, roi = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) cv2.imwrite('roi1.png', roi)</pre></div><div id="4f57"><pre><span class="hljs-selector-id">#cv2</span><span class="hljs-selector-class">.imshow</span>(<span class="hljs-string">"roi"</span>,roi) cont = cv2<span class="hljs-selector-class">.findContours</span>(roi, cv2<span class="hljs-selector-class">.RETR_EXTERNAL</span>, cv2.CHAIN_APPROX_SIMPLE) output = np<span class="hljs-selector-class">.zeros</span>(gray<span class="hljs-selector-class">.shape</span>, dtype=np.uint8) cv2<span class="hljs-selector-class">.drawContours</span>(output, cont<span class="hljs-selector-attr">[0]</span>, -<span class="hljs-number">1</span>, (<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>))</pre></div><div id="bd9b"><pre><span class="hljs-comment"># removing boundary</span> <span class="hljs-attribute">boundary</span> = <span class="hljs-number">255</span>*np.ones(gray.shape, dtype=np.uint8) <span class="hljs-attribute">boundary</span>[<span class="hljs-number">1</span>:boundary.shape[<span class="hljs-number">0</span>]-<span class="hljs-number">1</span>, <span class="hljs-number">1</span>:boundary.shape[<span class="hljs-number">1</span>]-<span class="hljs-number">1</span>] = <span class="hljs-number">0</span></pre></div><div id="d989"><pre><span class="hljs-attr">toremove</span> = output & boundary <span class="hljs-attr">output</span> = output ^ toremove</pre></div><p id="58ff"><b>4) Using PIL</b></p><p id="39a1"><b>PIL</b> stands for <b>Python Imaging Library.</b> It adds many image processing features to Python. Pillow is a fork of PIL that adds some user-friendly features. There are many interesting features of PIL for different kind of image manipulation . After importing “<i>ImageFilter</i>” from PIL, we can take advantage of inbuilt PIL feature for edge detection “<i>ImageFilter.FIND_EDGES</i>” . This will give us edges that we want.</p><figure id="1d73"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*w6CVecHZLHoTpdW3dKaIsQ.png"><figcaption>Edges detection Using PIL</figcaption></figure><div id="e62f"><pre><span class="hljs-comment">#Edges detection using PIL library</span></pre></div><div id="09d0"><pre><span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image, ImageFilter
image = Image.<span class="hljs-built_in">open</span>(<span class="hljs-string">r"Your image path"</span>)

<span class="hljs-comment">#In PIL grayscale is denoted by "L"</span> image = image.convert(<span class="hljs-string">"L"</span>)

<span class="hljs-comment"># Detecting Edges on the Image using the argument ImageFilter.FIND_EDGES</span> image = image.<span class="hljs-built_in">filter</span>(ImageFilter.FIND_EDGES)

<span class="hljs-comment"># Saving the Image Under the name Edges.png</span> image.save(<span class="hljs-string">r"Edges.png"</span>)</pre></div><blockquote id="d0a3"><p><b>Conclusion</b></p></blockquote><ol><li>Each algorithms stands by its unique mathematical approach for detecting edges . Single algorithm wont work for every case but you can decide algorithm on the basis of test case you have.</li><li>Edge detection is also dependent on what next steps and processing you want to do for your application so for that more deeper mathematical intuition is needed .</li><li>Drastic ups and drops of intensities in images are termed as edges and all kernels are designed accordingly .</li></ol><p id="c8d1">There are many algorithms for edge detection other than mentioned but I thought above as most common . For writing this blog and understanding concepts , I took inspiration for codes and concepts from many places. I really appreciate efforts of all writers and developers!</p><p id="9ed3"><b>THANK YOU!</b></p></article></body>

Types of Edge detection algorithms

Edge detection

In image processing and pattern recognition, it is always important to find contours and boundaries to understand continuities , discontinuities and overall structure. edges are the portions from which objects are separated .A significant or explicit change in gray scale levels or intensities indicate edges. Edges allow us to identify features from images.

In experiments done by David Hubel and Torsten Wiesel on cortical cells of cats and monkeys in 1950s and 1960s, they found groups of these cells respond differently to different orientation of line shown. They also found that groups of these cells respond differently to direction of motion. From this it can inferred that there is a mechanism in our visual perception that divides an image into different patterns.

the above beautiful explanation of brain and visual perception I got from my class lecture which is extremely informative in the point of view of edge detection .When we consider image as a data then it is important to extract features from it . For that purpose we use different kinds of filters/kernels to do convolution operation with image to get a feature maps. If we start from scratch means if we don’t use any pre-trained model , then model has to learn everything from image, every feature from scratch .Then we have to set kernels which will identify all features from images. On primary basis in initial stage for average image features can be termed as edges, contours . So its always important to identify edges in images. There are few algorithms which are built on purpose of detecting edges. I tried to include as many as possible and as many as I explored while working on edge detection.

1) Canny edge detection

It was developed by John F. Canny in 1986. Canny edge detection uses different steps to give us output as edges. We firstly convert image into gray scale image for ease of processing. Probably, converting all images into grayscale will be the first task in every edge detection algorithm. Then we use gaussian blur filter. Gaussian blur is simply a method of blurring an image with the help of a Gaussian function. Blurring images make edges stronger.

Visualizing gaussian blur

Imagine superimposing this type of distribution on group of pixels. The output we will get is gaussian blur. We use this to smoothen image. After reducing noise from image, finally we use canny filter in which we can specify threshold levels. The pixel intensity less than minimum threshold value will be excluded from final output. Like wise we can arrange different levels according to our needs.

import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread("Your image address with extension")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#plt.imshow(gray, cmap='gray')
blur = cv2.GaussianBlur(gray, (1,1), 0)
#plt.imshow(blur, cmap='gray')
canny = cv2.Canny(blur, 100, 150, 3)
plt.imshow(canny, cmap='gray')

If you uncomment “imshow” for gray and blur then you can see gray and blur converted version of your image to understand its processing .

Original Image
Edges detection by canny

2) Sobel edge detection

It is named after Irwin Sobel and Gary Feldman, colleagues at the Stanford Artificial Intelligence Laboratory (SAIL) .In Sobel edge detection, we have two kernels, horizontal and vertical. Firstly both kernel work separately and then sum-up overall result. Horizontal kernel captures edges in horizontal direction and vertical kernel captures edges in vertical direction.

Kernels for X and Y direction
#sobel edge detection
#we can provide minimum and maximum threshold according to our need
import cv2
# Read the original image
img = cv2.imread('Enter your image address with extension')
# Display original image
#cv2.imshow('Original', img)
#cv2.waitKey(0)
# Convert to graycsale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image for better edge detection
img_blur = cv2.GaussianBlur(img_gray, (3,3), 0)
# Sobel Edge Detection
sobelx = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=0, ksize=5) # Sobel Edge Detection on the X axis
sobely = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=0, dy=1, ksize=5) # Sobel Edge Detection on the Y axis
sobelxy = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=1, ksize=5) # Combined X and Y Sobel Edge Detection
# Display Sobel Edge Detection Images
#cv2.imshow('Sobel X', sobelx)
#cv2.waitKey(0)
#cv2.imshow('Sobel Y', sobely)
#cv2.waitKey(0)
#cv2.imshow('Sobel X Y using Sobel() function', sobelxy)
#cv2.waitKey(0)
#########################################################
#If we want to scratch code Sobel edge detection,
import numpy as np
import cv2
import matplotlib.pyplot as plt
vertical_filter = [[-1,-2,-1],[0,0,0],[1,2,1]]
horizontal_filter = [[-1,0,1],[-2,0,2],[-1,0,1]]
img = plt.imread("enter your image address")
n,m,d = img.shape
edges_img = np.zeros_like(img)
for row in range(3,n-2):
    for col in range(3,m-2):
        local_pixels = img[row-1:row+2,col-1:col+2, 0]
        
        vertical_transformed_pixels = vertical_filter*local_pixels
        vertical_score = vertical_transformed_pixels.sum()/4
        
        horizontal_transformed_pixels = horizontal_filter*local_pixels
        horizontal_score = horizontal_transformed_pixels.sum()/4
        
        edge_score = (vertical_score**2 + horizontal_score**2)**.5
        edges_img[row,col] = [edge_score]*3
    
edges_img = edges_img/edges_img.max()
plt.imshow(edges_img)
1)Sobel-X 2)Sobel-XY 3)Sobel-Y

3) By ROI

ROI stands for RIGION OF INTREST . As usual we firstly convert image into gray scaled image. Defining and removing boundary is main purpose of code. For recognizing contours, we take advantage of inbuilt function in cv2 that is “cv2.findContours”.

#edge detection on the basis of ROI
bgr = cv2.imread('your image path with extension')
gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
_, roi = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
cv2.imwrite('roi1.png', roi)
#cv2.imshow("roi",roi)
cont = cv2.findContours(roi, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
output = np.zeros(gray.shape, dtype=np.uint8)
cv2.drawContours(output, cont[0], -1, (255, 255, 255))
# removing boundary
boundary = 255*np.ones(gray.shape, dtype=np.uint8)
boundary[1:boundary.shape[0]-1, 1:boundary.shape[1]-1] = 0
toremove = output & boundary
output = output ^ toremove

4) Using PIL

PIL stands for Python Imaging Library. It adds many image processing features to Python. Pillow is a fork of PIL that adds some user-friendly features. There are many interesting features of PIL for different kind of image manipulation . After importing “ImageFilter” from PIL, we can take advantage of inbuilt PIL feature for edge detection “ImageFilter.FIND_EDGES” . This will give us edges that we want.

Edges detection Using PIL
#Edges detection using PIL library
from PIL import Image, ImageFilter  
image = Image.open(r"Your image path")
  
#In PIL grayscale is denoted by "L"
image = image.convert("L")
  
# Detecting Edges on the Image using the argument ImageFilter.FIND_EDGES
image = image.filter(ImageFilter.FIND_EDGES)
  
# Saving the Image Under the name Edges.png
image.save(r"Edges.png")

Conclusion

  1. Each algorithms stands by its unique mathematical approach for detecting edges . Single algorithm wont work for every case but you can decide algorithm on the basis of test case you have.
  2. Edge detection is also dependent on what next steps and processing you want to do for your application so for that more deeper mathematical intuition is needed .
  3. Drastic ups and drops of intensities in images are termed as edges and all kernels are designed accordingly .

There are many algorithms for edge detection other than mentioned but I thought above as most common . For writing this blog and understanding concepts , I took inspiration for codes and concepts from many places. I really appreciate efforts of all writers and developers!

THANK YOU!

Computer Vision
Opencv
Edge Detection
Image Processing
Data Science
Recommended from ReadMedium