Template Matching
اهداف
- برای پیدا کردن اشیا 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()
خروجی های متعدد:
می بینید که نتیجه استفاده از 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)
خروجی قطعه کد بالا بر روی نمونه کوچک: