Template Matching, sahip olduğumuz templateyi başka bir fotoğraf içerisinde arama olayıdır. Bu yazı elimizdeki template ile gerçek zamanlı nesne tespiti yapmak üzerine olacak.
Her şeyden önce, templateyi ve templatenin aranacağı resmi oluşturmalıyız. Kameradan anlık olarak görüntü almadan önce, bazı şeylerin anlaşılması adına sadece tek fotoğraf üzerinde arama yapalım.
Kitap dolabımda bulunan küpü tespit etmeye çalışacağız. Aşağıda template olarak oluşturduğumuz fotoğraf bulunuyor.
OpenCV ile Template Matching
OpenCV, Python ve C++ ile kullanabileceğiniz bir image processing kütüphanesidir. Kullanmaya çalışmadan önce sisteminize kurmalısınız.
import cv2
def detect(frame, temp, w, h):
"""
@param frame: templatenin içinde aranacağı fotoğraf
@param temp : template
@param w: templatenin genişliği
@param h: templatenin yüksekliği
"""
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(frame, temp, cv2.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
return (max_val, top_left, bottom_right)
if __name__ == '__main__':
image = cv2.imread('temp_1.png')
template = cv2.imread('temp_2.png', 0)
tW, tH = template.shape[::-1]
result = detect(image, template, tW, tH); print(result)
cv2.rectangle(image, *result[1:], (0, 255, 0), 2)
cv2.imshow('match', image)
if cv2.waitKey(0) & 0xFF == ord('q'):
cv2.destroyAllWindows()
Yukarıdaki kodu açıklayalım. Öncelikle OpenCV kütüphanesini içeri aktardık. Hemen aşağısında, frame, temp, w, h
parametrelerini alan detect fonksiyonu bulunuyor. Template ve fotoğrafı, cv2.matchTemplate fonksiyonu ile karşılaştırdık, fonksiyona verdiğimiz üçüncü argüman istatiksel bir metod. OpenCV içerisinde karşılaştırma için altı adet metod bulunuyor. Onlar hakkında detaylı bilgiye buradan ulaşabilirsiniz. Son olarak tespit edilen bölgeyi ve eşleşme oranını döndürüyoruz.
Program başlatıldığında, dosyaları okuyor ve ardından detect fonksiyonunu çalıştırıyor, döndürdüğü değerin belirlediği bölgeyi işaretliyor ve kullanıcıya gösteriyor.
Hemen nasıl çalıştığına bakalım.
Gerçek Zamanlı Template Matching
Şimdi, sürekli kameradan içerisinde templatelerin aranacağı bir program yazalım.
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
#
#
__author__ = '@laszlokuehl'
import os
import cv2
class TemplateMatch:
def __init__(self, templates):
self.cam = cv2.VideoCapture(0)
for temp in templates.keys():
templates[temp] = (templates[temp], *templates[temp].shape[::-1])
self.templates = templates
def detect(self, frame, temp, w, h):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(frame, temp, cv2.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
return (max_val, top_left, bottom_right)
def main(self):
while True:
_, image = self.cam.read()
for name, temp in self.templates.items():
result = self.detect(image, *temp)
if result[0] >= 0.98:
label = '{}: {:.2f}%'.format(name, result[0] * 100)
cv2.putText(image, label, (result[1][0], result[1][1] - 10), cv2.FONT_HERSHEY_COMPLEX, 0.5, (32, 32, 32), 1)
cv2.rectangle(image, *result[1:], (32, 32, 32), 2)
else:
print('{}: {:.2f}%'.format(name, result[0] * 100))
cv2.imshow('temp match', image)
if (cv2.waitKey(5) & 0xFF) == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
app = TemplateMatch(
dict(
[(img.split('.')[0], cv2.imread('templates/' + img, 0)) for img in os.listdir('templates') if 'png' in img]
)
)
app.main()
Mantık yine aynı, her şey detect fonksiyonunda olup bitiyor. Program, templates
klasöründeki tüm dosyaları templates
adlı bir sözlüğe isimleriyle beraber ekliyor, kameradan alınan her fotoğraf içerisinde bu templateleri arıyor. Eğer eşleşme oranı %98’den büyükse, bunları isimleriyle beraber fotoğraf üzerinde işaretleyip kullanıcıya sunuyor.
Hemen çalıştırıp sonucu görelim!
İşte istediğimiz sonuç, nesneleri algılayabiliyor. Anlayamadığınız yerde, mail atmaktan çekinmeyin, bilgim neticesinde yardımcı olmaya çalışırım. Kolay gelsin!