Computer Vision

[Object Detection] Template Matching

Xin chào, trong bài viết này chúng ta sẽ tìm hiểu về Template Matching để thực hiện Object Detection (phát hiện đối tượng).

Object Detection được hiểu là một quá trình gồm nhiều biện pháp kỹ thuật nhằm tìm ra vị trí (tọa độ) của đối tượng được quan tâm (như là đồ vật, thú cưng, con người,…) trong một bức ảnh.

Template Matching là một kỹ thuật đơn giản và dễ sử dụng nhất để thực hiện Object Detection, tuy nhiên nhược điểm của nó chính là chỉ hoạt động dưới điều kiện ánh sáng lý tưởng.


TEMPLATE MATCHING

Để thực hiện Template Matching chúng ta cần:

  1. Source Image – một bức ảnh chứa đối tượng được quan tâm;
  2. Template Image – một “object patch” được dùng để tìm kiếm trong Source Image.

Template Image sẽ được “slide” từ trái sang phải, từ trên xuống dưới trong Source Image và tại mỗi vị trí, một số liệu sẽ được tính toán để thể hiện mức độ phù hợp của Template.

Trong khi việc thực hiện Template Matching rất đơn giản, thì nó chỉ hữu ích ở vài hoàn cảnh cụ thể. Trong mọi trường hợp, chúng ta cần phải đảm bảo rằng Template Image phải gần giống với đối tượng được quan tâm trong bức ảnh, chỉ một khác biệt nhỏ cũng sẽ làm thay đổi kết quả của Template Matching và khiến nó trở nên vô dụng.


ÁP DỤNG TEMPLATE MATCHING

Để thực hiện Template Matching, OpenCV cung cấp function cv2.matchTemplate():

result = cv2.matchTemplate(source, template, method)

Trong đó:

  • source – hình ảnh chứa đối tượng được quan tâm;
  • template – “object patch” được dùng để tìm kiếm trong source;
  • method – phương pháp so sánh, gồm cv2.TM_CCOEFF, cv2.TM_SQDIFF, CV_TM_CCORR,…;
  • result – ma trận chứa kết quả tính toán tại mỗi vị trí để thể hiện mức độ phù hợp của Template.

Để trích xuất được tọa độ của “Best Match” chúng ta sử dụng function cv2.minMaxLoc()

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(matrix)

Trong đó:

  • minVal, maxVal – giá trị nhỏ nhất và lớn nhất của matrix;
  • minLoc, maxLoc – tọa độ của giá trị minVal và maxVal trong matrix, ở dạng (x, y).

Example:

templateMatching.py

import cv2

def selectROI(event, x, y, flags, param):
	global image, roiPts, inputMode

	if inputMode and event == cv2.EVENT_LBUTTONDOWN and len(roiPts) < 2:
		roiPts.append((x,y))
		cv2.circle(image, (x,y), 2, (0,255,0), -1)

		if len(roiPts) == 2:
			print "2 points"
			cv2.line(image, (roiPts[0][0], roiPts[0][1]), (roiPts[1][0], roiPts[0][1]), (0,255,0), 2)
			cv2.line(image, (roiPts[1][0], roiPts[0][1]), (roiPts[1][0], roiPts[1][1]), (0,255,0), 2)
			cv2.line(image, (roiPts[1][0], roiPts[1][1]), (roiPts[0][0], roiPts[1][1]), (0,255,0), 2)
			cv2.line(image, (roiPts[0][0], roiPts[1][1]), (roiPts[0][0], roiPts[0][1]), (0,255,0), 2)

		cv2.imshow("Image", image)

image = []
roiPts = []
inputMode = False
template = []

def main():
	global image, roiPts, inputMode

	video = cv2.VideoCapture(0)

	cv2.namedWindow("Image")
	cv2.setMouseCallback("Image", selectROI)

	while True:
		grab, image = video.read()
		if not grab:
			continue

		if len(roiPts) == 2:
			cv2.imshow("Template", template)
			result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF)
			(minVal, maxVal, minLoc, (x,y)) = cv2.minMaxLoc(result)
			cv2.rectangle(image, (x,y), (x+template.shape[1],y+template.shape[0]), (0,0,255), 2)

		cv2.imshow("Image", image)

		key = cv2.waitKey(1) & 0xFF
		if key == ord("i") and len(roiPts) < 2:
			inputMode = True
			while len(roiPts) < 2:
				cv2.imshow("Image", image)
				cv2.waitKey(0)

			template = image[roiPts[0][1]:roiPts[1][1], roiPts[0][0]:roiPts[1][0]]

		if key == ord("q"):
			break

if __name__ == "__main__":
	main()

Usage:

Sau khi chạy chương trình, nhấn phím i trên bàn phím và click vào 2 điểm của đối tượng được quan tâm. Sau đó một hình vuông hình chữ nhật được vẽ bao quanh đối tượng, nhấn Enter để bắt đầu Template Matching.

Output:

templateMatching

Bức ảnh nhỏ bên phải chính là Template Image, còn hình chữ nhật màu đỏ trong bức ảnh lớn chính là vị trí của đối tượng được phát hiện.


MULTI-SCALE TEMPLATE MATCHING

(Cập nhật sau)


SUMMARY

Như vậy chúng ta đã tìm hiểu về Template Matching, đây là một kỹ thuật rất đơn giản và dễ sử dụng, tuy nhiên điểm yếu của nó chính là yêu cầu khắt khe về điều kiện ánh sáng cũng như sự tương đồng giữa object và template.

Để xây dựng một bộ Object Detector mạnh mẽ, hiệu quả hơn chúng ta sẽ cần áp dụng các kỹ thuật Computer Vision, Machine Learning cao cấp hơn như image pyramids, sliding windows và non-maxima suppression.

Nhưng trước khi đến với các kỹ thuật nâng cao này chúng ta hãy cứ vui vẻ vọc vạch Template Matching nhé! Cảm ơn các bạn đã theo dõi bài viết.

Thân ái và quyết thắng.

Reference:
[1] Finding the Brightest Spot in an Image using OpenCV.
[2] Multi-scale Template Matching using Python and OpenCV.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s