Canny Edge Detection

Kategori: Computer Vision , 17 Şubat 2020 , JanFranco


Canny Edge Detection algoritmasının detayına inelim. Algoritma Sobel algoritmasına oldukça benziyor. Hatta ilk aşaması hemen hemen aynı. Fakat Canny algoritması, Sobel algoritmasından farklı olarak kenarları inceltme ve linking yöntemlerini kullanıyor. Algoritma 3 önemli aşamadan oluşuyor. Gradient calculation, Non-maximum suppression, hystereris thresholding. Gradient calculation ile başlayalım. Harris Corner Detection, Good Features to Track yazılarında da gördüğümüz, Gradient yazımızda anlattığımızdaki gibi Gradient hesabı yapacağız. Görüntü işlemede problemleri çözerken yüksek oranda gradientlerden faydalanıyoruz. Resmin x ekseninde ve y ekseninde türevleri alınır. Daha sonra bu türevler birbirlerien oranlanarak gradient yönü için bir açı elde edilir:

Canny Edge Detection

Türevin ne olduğunu biliyoruz. Türev değişimdir. Yukarıdaki iki formülü bir örnek üzerinden görelim. Resmin (x, y) pikselindeyiz. x ekseninde türev aldık. Yani x eksenindeki bir sonraki piksel ile bulunduğumuz pikselin farkını aldık. Bu da (x + 1, y) - (x, y). Bu değer örneğin 5 olsun. Resim tabi ki grayscale bir resim. Aynı hesabı y ekseninde de yapalım. (x, y + 1) - (x, y) = 5 olsun. Gradient büyüklüğü karakök(25 + 25) = 5 kök(2). Yönü ise arc tan (5/5) = arc tan(1) = 45 derece. Yani bulunduğumuz pikselden sağa gidersek de aşağı gidersek de değişim aynı, biz de ortadan gitmeyi tercih ediyoruz. x eksenindeki değişim 6, y eksenindeki değişim 8 olsun. Gradient büyüklüğü 10 olur. (6-8-10). Yön ise arc tan(0.75) = 36.8 derece olur. Yani y eksenine yakın bir şekilde gradient yönü aşağı şekildedir. Gradient Calculation adımında değişimleri bulduk, yönleri bulduk.

Non-maximum Supression adımında ince kenarlar elde edeceğiz. Aslında Non-maximum supression da bir çok uygulamada var ve kullanışlı bir yol. Non-maximum supression yönteminde amaç lokal maksimumu elde etmektir. Lokal maksimum elde edildiğinde, maksimumun altında kalan değerler yok sayılır. Aşağıdaki resim üzerinden daha iyi anlatayım:

Canny Edge Detection

Burada 3 nokta görüyoruz. A, B ve C. A noktası kenarımızın üstünde. Gradient yönü x ekseninde sağa doğru. Burada C, A ve B noktaları üzeirinde, gradient büyüklüğü göz önünde bulundurularak bir lokal maksimum bulma işlemi yapılacak. Lokal maksimum tabi ki A çıkacak. Bu durumda C ve B değerlerinin bulunduğu kısımlardaki kenarlar vs. yok sayılacak. Burada amaç kenarları inceltmek, gürültüleri temizlemek.

Son aşama ise Hysteresis Thresholding. Bu yöntemi ben direk resim üzeirinden anlatayım:

Canny Edge Detection

Hatırlarsak cv2.canny methodunda iki threshold değeri veriyorduk. Şimdi resime odaklanalım. Burada iki threshold değeri ve üç kenar mevcut. Biz piksel bazında baktığımızdan 3 kenar mevcut diye düşünüyoruz. Hatırlatayım bu aşamadan önce kenarlar bulundu. Bu aşamada gereksiz kenarları temizliyoruz. Eğer bir kenardaki pikseller maxVal değerinin üstünde ise kesinlikle kenardır kabul ediyoruz. Bu durumda A noktasının bağlı olduğu kısım bir kenardır. minVal değerinin altında kalan piksellerin bağlı olduğu kenar ise kesinlikle kenar değildir. minVal ve maxVal değerleri arasında kalan pikseller için link aranır. Örneğin C pikselinin bulunduğu kısım, kesinlikle kenardır dediğimiz A pikselinin bulunduğu kenara bağlı. Bu nedenle A, C piksellerinin bulunduğu kenarın tamamını kesinlikle kenardır şeklinde kabul ediyoruz. B pikselinin bulunduğu kenarda ise bağlı olduğu bir link yok. Yani minVal değerinin üstünde olması bizi bağlamaz kenar değildir deriz.

Canny algoritmasının son adımı olan Hystereris Thresholding için, threshold değerleri vermek zor olabilir. Bu değerleri bizim için otomatik verecek bir yöntem geliştirelim:


import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('../data/road.jpg')
img2show = img.copy()
img2show = cv2.cvtColor(img2show, cv2.COLOR_RGB2BGR)
plt.figure(1)
plt.title('Img')
plt.imshow(img2show)

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 5)
v = np.median(blurred)
sigma = .33
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(blurred, lower, upper)
plt.figure(2)
plt.title('Canny')
plt.imshow(edged, cmap='gray')
plt.show()
>>

Canny Edge Detection

Canny Edge Detection

Resmi grayscale hale getirip, blur uygulamak zaten standarttır. Bu adımlardan sonra yoğunluk bazında tam ortada olan pikseli alıyoruz. bu değeri 1-sigma ve 1+sigma ile çarpıyoruz. Bu değerler bizim threshold değerlerimiz oluyoruz. Sigma değeri ile oynayabilir farklı sonuçlar elde edebilirsiniz.


Sonraki Yazı: SIFT - Scale Invariant Feature Transform
Yorumlar

Henüz bir yorum bulunmuyor.
Yorum bırakın