Tiếp tục series về Keypoint Detector, hôm nay mình sẽ giới thiệu một thuật toán mới để xác định keypoint trong một bức ảnh: GFTT - Good Features to Track.
Thuật toán này được giới thiệu trong bài báo khoa học của Shi-Tomasi năm 1994 Good Features to Track. GFTT là một phiên bản chỉnh sửa của thuật toán Harris (để biết thêm về Harris, các bạn hãy xem tại đây)
Cách thức hoạt động của GFTT
Nếu bạn còn nhớ về thuật toán Harris, thì thuật toán này sẽ đi tìm giá trị R để xác định trong vùng đó có góc hay không. Giá trị R được xác định theo công thức sau
Công thức này có thể được phân tích ra như sau:
Tuy nhiên, Shi và Tomasi nhận thấy rằng có lẽ có chức năng ghi điểm tốt hơn mà họ có thể sử dụng. Họ đã đề xuất phép tính R sau đây để chỉ ra một vùng có phải là góc hay không.
Trong trường hợp này, chúng ta chỉ đơn giản là lấy giá trị tối thiểu của các thành phần eigenvalue decomposition. Nếu giá trị R này lớn hơn ngưỡng T, thì chúng ta có thể đánh dấu khu vực là một góc.
Chúng ta có thể hình dung máy dò Shi-Tomasi bằng cách kiểm tra hình sau:
- Trong region #1, cả 2 giá trị lambda1 và lambda2 đề < T, vì vậy đây không phải là keypoint
- Trong vùng #2, lambda1 < T, nên vùng này không phải là keypoint
- Trong vùng #3, lambda < T, vif vậy vùng này không phải là keypoint
- Trong vùng #4, cả 2 đều > T, nên đây đích thị là một corner keypoint
Sự thay đổi nhỏ đối với Harris dẫn đến các corner keypoint ổn định hơn được phát hiện. Nó cũng nhanh hơn một chút bằng cách giảm phép nhân và bổ sung các giá trị riêng.
Vậy bạn nên sử dụng thuật toán nào - Harris hay máy dò Shi-Tomasi / GFTT?
Đối với hầu hết các ứng dụng, bạn (có thể) không nhận thấy sự khác biệt đáng kể giữa hai ứng dụng. Cá nhân tôi vẫn sử dụng Harris vì tôi phải so sánh kết quả của mình với các hệ thống cũ. Nhưng trong trường hợp của bạn, bạn có thể muốn xem xét sử dụng GFTT để phát hiện góc ổn định hơn một chút.
GFTT trong python
Bạn có thể xem code tại đây:
# import the necessary packages
from __future__ import print_function
import numpy as np
import cv2
import imutils
def gftt(gray, maxCorners=0, qualityLevel=0.01, minDistance=1,
mask=None, blockSize=3, useHarrisDetector=False, k=0.04):
# compute GFTT keypoints using the supplied parameters (OpenCV 3 only)
kps = cv2.goodFeaturesToTrack(gray, maxCorners, qualityLevel,
minDistance, mask=mask, blockSize=blockSize,
useHarrisDetector=useHarrisDetector, k=k)
# create and return `KeyPoint` objects
return [cv2.KeyPoint(pt[0][0], pt[0][1], 3) for pt in kps]
# load the image and convert it to grayscale
image = cv2.imread("next.jpg")
orig = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# handle if we're detecting and drawing GFTT keypoints using OpenCV 2.4
if imutils.is_cv2():
detector = cv2.FeatureDetector_create("GFTT")
kps = detector.detect(gray)
# handle if we're detecting and drawing GFTT keypoints using OpenCV 3+
else:
kps = gftt(gray)
# loop over the keypoints and draw them
for kp in kps:
r = int(0.5 * kp.size)
(x, y) = np.int0(kp.pt)
cv2.circle(image, (x, y), r, (0, 255, 255), 2)
print("# of keypoints: {}".format(len(kps)))
# show the image
cv2.imshow("Images", np.hstack([orig, image]))
cv2.waitKey(0)
Sau khi chạy thuật toán, chúng ta tìm được 779 keypoint
Kết luận
Mình đã trình bày cơ bản về cách hoạt động của thuật toán GFTT, thuật toán này là một sự thay đổi cách tính giá trị R so với thuật toán Harris mà mình đã trình bày trước đó
Chúc bạn thành đạt trong công việc và hạnh phúc trong cuộc sống !
Hotline / Zalo: 0903 666 014
Website: https://uniduc.com/vi
-------------////--------------------------------------------////------------
HUMANOID ROBOT CỦA CÔNG TY UNIDUC SẢN XUẤT PHÁT TRIỂN.