Real Time Template Matching

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.

source

Kitap dolabımda bulunan küpü tespit etmeye çalışacağız. Aşağıda template olarak oluşturduğumuz fotoğraf bulunuyor.

template

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.

result-1

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!

result-2

İşte istediğimiz sonuç, nesneleri algılayabiliyor. Anlayamadığınız yerde, mail atmaktan çekinmeyin, bilgim neticesinde yardımcı olmaya çalışırım. Kolay gelsin! :slight_smile:

8 Beğeni

İyi günler bu konu ile ilgili bir projem var sadece tek farkı dikdörtgen içine almayıp true ya da false değer gönderecek yardımcı olabilir misiniz?

Robotik için gerekli bir uygulama gerçekten. Bir videoda; arabanın, yol çizgilerini, trafik işaretlerini ve lambalarını (renk ayrımı da yapabiliyordu) algılayarak trafik kurallarına otomatik uymasını sağlamışlardı.