Template Matching

  • مدرس: علی بیگدلی
  • تاریخ انتشار: Sep 05, 2020

اهداف

  • برای پیدا کردن اشیا in در یک تصویر با استفاده از تطبیق الگو
  • این توابع را مشاهده خواهید کرد: cv.matchTemplate ()، cv.minMaxLoc ()

مقدمه

تطبیق الگو روشی برای جستجو و یافتن مکان تصویر الگو در یک تصویر بزرگتر است. برای این منظور OpenCV دارای یک تابع cv.matchTemplate () است. این به سادگی تصویر الگو را بر روی تصویر ورودی اسلاید می کند (همانند ترکیب 2D) و الگو و پچ تصویر ورودی را در زیر تصویر الگو مقایسه می کند. چندین روش مقایسه در OpenCV اجرا شده است. (برای جزئیات بیشتر می توانید اسناد را بررسی کنید). این یک تصویر در مقیاس خاکستری برمی گرداند ، جایی که هر پیکسل نشان می دهد که همسایگی آن پیکسل چقدر با الگو مطابقت دارد.

اگر اندازه تصویر ورودی (WxH) و اندازه تصویر (wxh) باشد ، تصویر خروجی اندازه (W-w + 1 ، H-h + 1) خواهد داشت. هنگامی که نتیجه را گرفتید ، می توانید از تابع cv.minMaxLoc () استفاده کنید تا مقدار حداکثر / حداقل را پیدا کنید. آن را به عنوان گوشه بالا و سمت چپ مستطیل در نظر بگیرید و (w ، h) را به عنوان عرض و ارتفاع مستطیل بگیرید. این مستطیل منطقه الگوی شماست.

توجه : اگر از cv.TM_SQDIFF به عنوان روش مقایسه استفاده می کنید ، حداقل مقدار بهترین تطابق را دارد.

تطبیق الگو در OpenCV

در اینجا ، به عنوان نمونه ، چهره مسی را در عکس او جستجو خواهیم کرد. بنابراین الگویی را به صورت زیر ایجاد کردم:

 

ما تمام روش های مقایسه را امتحان می کنیم تا ببینیم نتایج آنها چگونه است:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
img2 = img.copy()
template = cv.imread('template.jpg',0)
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
            'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
for meth in methods:
    img = img2.copy()
    method = eval(meth)
    # Apply template Matching
    res = cv.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv.rectangle(img,top_left, bottom_right, 255, 2)
    plt.subplot(121),plt.imshow(res,cmap = 'gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(img,cmap = 'gray')
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()

خروجی های متعدد:

template_ccoeff_1.jpg

 

template_ccoeffn_2.jpg

 

template_ccorr_3.jpg

 

template_ccorrn_4.jpg

 

template_sqdiff_5.jpg

 

template_sqdiffn_6.jpg

 

می بینید که نتیجه استفاده از cv.TM_CCORR همانطور که انتظار داشتیم خوب نیست.

تطبیق الگو با چندین شی

در بخش قبلی ، ما تصویر چهره مسی را جستجو کردیم که فقط یک بار در تصویر رخ می دهد. فرض کنید شما در حال جستجوی شیئی هستید که دارای چندین رویداد باشد ، cv.minMaxLoc () همه مکان ها را به شما نمی دهد. در این صورت ، ما از آستانه استفاده خواهیم کرد. بنابراین در این مثال ، ما از تصویر بازی معروف Mario استفاده خواهیم کرد و سکه های موجود در آن را پیدا خواهیم کرد.

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img_rgb = cv.imread('mario.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('mario_coin.png',0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv.imwrite('res.png',img_rgb)

خروجی قطعه کد بالا بر روی نمونه کوچک:

 

ثبت دیدگاه
نام *
ایمیل*
دیدگاه *
0دیدگاه