Thị giác máy tính với OpenCV-Python Bài 5 Phần 3: Tìm đối tượng thông qua so khớp và phép chiếu hình học
09:44 - 18/01/2022
Trong phần này chúng ta sẽ tìm hiểu cách sử dụng thuật toán so khớp đặc điểm và phép chiếu hình học để tìm các đối tượng quan tâm trong một hình ảnh gồm nhiều đối tượng.
Thị giác máy tính với OpenCV-Python Bài 7 Phần 2: Phát hiện người đi bộ trong video
Thị giác máy tính với OpenCV-Python Bài 7 Phần 1: Phát hiện người đi bộ trong hình ảnh
Thị giác máy tính với OpenCV-Python Bài 6 Phần 2: Phép trừ nền
Thị giác máy tính với OpenCV-Python Bài 6 Phần 1: Bắt bám đối tượng với Meanshift và Camshift
Ở phần trước, sử dụng thuật toán so khớp đặc điểm chúng ta đã tìm được vị trí một số bộ phận nổi bật của đối tượng trong hình ảnh gồm nhiều đối tượng. Đây là những thông tin quan trọng để tìm ra đối tượng.
Để thực hiện tìm đối tượng, đầu tiên chúng ta cần sử dụng một hàm từ mô-đun calib3d là cv2.findHomography(). Nếu chúng ta truyền vào hợp các điểm từ cả hai hình ảnh, hàm này sẽ tìm phép biến đổi đối tượng đó. Sau đó, chúng ta có thể sử dụng hàm cv2.perspectiveTransform() để tìm đối tượng. Cần ít nhất bốn điểm chính xác để tìm ra phép biến đổi.
Có thể có một số lỗi xảy ra khi so khớp đối tượng, dẫn đến ảnh hưởng đến kết quả. Để giải quyết vấn đề này, thuật toán sử dụng RANSAC hoặc LEAST_MEDIAN (được quyết định bởi các cờ “flag”). Nhờ vậy, các kết quả phù hợp cung cấp ước tính chính xác được gọi là giá trị nội tại và phần còn lại được gọi là giá trị ngoại lai. Hàm cv2.findHomography() trả về một mặt nạ chỉ định các điểm bên trong và ngoài.
Đầu tiên, như thường lệ, chúng ta hãy tìm các đặc điểm SIFT trong hình ảnh và áp dụng kiểm tra tỷ lệ để tìm ra những kết quả phù hợp nhất:
- import numpy as np
- import cv2
- from matplotlib import pyplot as plt
- MIN_MATCH_COUNT = 10
- img1 = cv2.imread('book.jpg', 0) # queryImage
- img2 = cv2.imread('books.jpg', 0) # trainImage
- # Initiate SIFT detector
- sift = cv2.SIFT_create()
- # find the keypoints and descriptors with SIFT
- kp1, des1 = sift.detectAndCompute(img1, None)
- kp2, des2 = sift.detectAndCompute(img2, None)
- FLANN_INDEX_KDTREE = 0
- index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
- search_params = dict(checks = 50)
- flann = cv2.FlannBasedMatcher(index_params, search_params)
- matches = flann.knnMatch(des1, des2, k=2)
- # store all the good matches as per Lowe's ratio test.
- good = []
- for m,n in matches:
- if m.distance < 0.7*n.distance:
- good.append(m)
Bây giờ chúng ta đặt điều kiện rằng có ít nhất 10 điểm so khớp trùng nhau (được xác định bởi MIN_MATCH_COUNT) để tìm ra đối tượng. Nếu không, chỉ cần hiển thị thông báo cho biết không có đủ kết quả phù hợp.
Nếu tìm thấy đủ kết quả phù hợp, chúng ta trích xuất vị trí của các điểm chính phù hợp trong cả hai hình ảnh. Chúng được truyền vào để tìm ra phép biến đổi (ở đây chính là ma trận biến đổi 3x3), sau đó chúng ta sử dụng nó để biến đổi các góc của hình ảnh đối tượng cần tìm thành các điểm tương ứng trong hình ảnh nhiều đối tượng:
- if len(good)>MIN_MATCH_COUNT:
- src_pts = np.float32([kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
- dst_pts = np.float32([kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
- M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 0)
- matchesMask = mask.ravel().tolist()
- h,w = img1.shape
- pts = np.float32([ [0,0], [0,h-1], [w-1,h-1], [w-1,0] ]).reshape(-1,1,2)
- dst = cv2.perspectiveTransform(pts, M)
- img2 = cv2.polylines(img2, [np.int32(dst)], True, 255,3, cv2.LINE_AA)
- else:
- print("Not enough matches are found - %d/%d" % (len(good), MIN_MATCH_COUNT))
- matchesMask = None
Cuối cùng, chúng tôi vẽ các phần trong của chúng tôi (nếu tìm thấy đối tượng thành công) hoặc các điểm chính phù hợp (nếu không thành công):
- draw_params = dict(matchColor = (0,255,0), # draw matches in green color
- singlePointColor = None,
- matchesMask = matchesMask, # draw only inliers
- flags = 2)
- img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)
- plt.imshow(img3, 'gray'), plt.show()
Kết quả:
Ở phần tiếp theo chúng ta sẽ cùng tìm hiểu các thuật toán bắt bám đối tượng trong video như Meanshift và Camshift.
(Sưu tầm)
VIỆN IMC
Tòa nhà IMC Tower, Số 176 Trường Chinh, Phường Khương
Thượng, Quận Đống Đa, Thành phố Hà Nội, Việt Nam
Tel/Fax : (+84) 24 3566 6232 / 24 3566 6234
Email: contact@imc.org.vn Website: https://imc.org.vn