Trước khi đi vào phần chính của bài viết, mình sẽ nói sơ qua về local features.
Giả sử chúng ta được giao nhiệm vụ xây dựng một hệ computer vision để tự động xác định bìa sách. Hệ thống của chúng ta sẽ chụp ảnh bìa sách được chụp từ thiết bị di động như iPhone hoặc Android, trích xuất các tính năng từ hình ảnh và sau đó so sánh các tính năng với một bộ bìa sách trong database.
Mục tiêu của chúng ta ở đây là chụp ảnh này và xác định có phải là bìa của cuốn sách. Với vấn đề này, bạn nghĩ thuật toán image descriptor nào là phù hợp nhất? HOG? LBPs? Haralick texture?
Vấn đề với các mô tả này là tất cả chúng đều là global image descriptor và nếu chúng ta sử dụng chúng, chúng ta sẽ kết thúc việc định lượng các vùng của hình ảnh mà chúng ta không quan tâm, chẳng hạn như vùng bàn phím / máy tính xách tay ở chế độ nền hoặc phần của bàn tay ở phía trước. Bao gồm các khu vực này trong tính toán feature vector của chúng ta có thể loại bỏ đáng kể vectơ tính năng đầu ra - và chúng ta có nguy cơ không thể xác định được cuốn sách!
Giải pháp là thay vào đó là sử dụng các local features, trong đó chúng ta chỉ mô tả các vùng nhỏ, cục bộ của hình ảnh được coi là thú vị của hình ảnh thay vì toàn bộ hình ảnh. Các khu vực này phải là duy nhất, dễ dàng so sánh và lý tưởng mang một số ý nghĩa ngữ nghĩa liên quan đến nội dung của hình ảnh.
Quá trình tìm và mô tả các điểm được coi là thú vị sẽ được chia làm 2 giai đoạn: keypoint detector và feature extraction
Trong bài viết này chúng ta sẽ cùng tìm hiểu phương pháp đầu tiên trong gian đoạn keypoint detector: FAST (Features from Accelerated Segment Test)
FAST (Features from Accelerated Segment Test)
FAST keypoint detector được sử dụng để phát hiện các góc trong hình ảnh, được triển khai trong thư viện OpenCV và được áp dụng nhiều nhất cho các ứng dụng thời gian thực hoặc các thiết bị bị hạn chế tài nguyên, nơi không có nhiều thời gian tính toán hoặc sức mạnh để sử dụng các keypoint detector tiên tiến hơn.
FAST hoạt động như thế nào?
Ý tưởng của FAST keypoint detector là để một pixel được coi là một góc phải có ít nhất n các pixel liền kề dọc theo chu vi hình tròn có bán kính r, tất cả đều sáng hơn hoặc tối hơn pixel trung tâm bởi một ngưỡng t nào đó.
Để hiểu FAST keypoint detector, hãy xem hình dưới đây
Ở đây chúng ta đang xem xét một vòng tròn có 16 pixel (tương ứng với bán kính r = 3) bao quanh pixel trung tâm.
Để pixel trung tâm p này được coi là một điểm then chốt, phải có n pixel liền kề sáng hơn hoặc tối hơn pixel trung tâm theo một số ngưỡng t
Trong thực tế, người ta thường chọn bán kính r = 3, tương ứng với một vòng tròn có 16 pixel. Nó cũng phổ biến để chọn n, số lượng pixel liền kề, là n = 9 hoặc n = 12
Hãy cùng xem một ví dụ:
Ở đây, chúng ta đang xem xét liệu p pixel trung tâm có nên được coi là một điểm then chốt hay không. Pixel trung tâm có giá trị grayscale p = 32. Để pixel này được coi là một điểm then chốt, nó phải có n = 12 pixel liền kề dọc theo đường biên của vòng tròn đều sáng hơn p + t hoặc tối hơn p - t. Hãy giả sử rằng t = 16 cho ví dụ này.
Như chúng ta có thể thấy, chỉ có 8 pixel liền kề tối hơn (được đánh dấu bằng hình chữ nhật màu xanh lá cây, tất cả các pixel khác là hình chữ nhật màu đỏ) so với pixel trung tâm - do đó, pixel trung tâm không phải là keypoint
Hãy cùng xem một ví dụ khác:
Chúng ta thấy có 14 pixel liền kề nhau và sáng hơn pixel trung tâm. Vì thế, pixel p được coi là keypoint
Các bạn có thể thấy được là thuật toán bên trên tuy rất đơn giản, nhưng lại được sử dung rất nhiều trong các ứng dụng computer vision hằng ngày cũng như các ứng dụng real-time, đòi hỏi tốc độ tính toán cao.
FAST keypoint detector trong Python
Thuật toán FAST keypoint detector đã được triển khai trong thư viện OpenCV. Code bên dưới là một ví dụ về cách sử dụng FAST để đi tìm keypoint
** CODE
# import the necessary packages
from __future__ import print_function
import numpy as np
import cv2
import imutils
# load the image and convert it to grayscale
image = cv2.imread("next.png")
orig = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# handle if we are detecting FAST keypoints in the image for OpenCV 2.4
if imutils.is_cv2():
detector = cv2.FeatureDetector_create("FAST")
kps = detector.detect(gray)
else:
detector = cv2.FastFeatureDetector_create()
kps = detector.detect(gray, None)
print("# of keypoints: {}".format(len(kps)))
# 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)
cv2.imshow("Images", np.hstack([orig, image]))
cv2.waitKey(0)
gftt.py
# 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.png")
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)
harrs_keypoint_detector.py
# import the necessary packages
from __future__ import print_function
import numpy as np
import cv2
import imutils
def harris(gray, blockSize=2, apetureSize=3, k=0.1, T=0.02):
# convert our input image to a floating point data type and then
# compute the Harris corner matrix
gray = np.float32(gray)
H = cv2.cornerHarris(gray, blockSize, apetureSize, k)
# for every (x, y)-coordinate where the Harris value is above the
# threshold, create a keypoint (the Harris detector returns
# keypoint size a 3-pixel radius)
kps = np.argwhere(H > T * H.max())
kps = [cv2.KeyPoint(pt[1], pt[0], 3) for pt in kps]
# return the Harris keypoints
return kps
# load the image and convert it to grayscale
image = cv2.imread("next.png")
orig = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# handle if we are detecting Harris keypoints in the image with OpenCV 2.4
if imutils.is_cv2():
detector = cv2.FeatureDetector_create("HARRIS")
kps = detector.detect(gray)
# otherwise we are detecting Harris keypoints with OpenCV 3+ using the function above
else:
kps = harris(gray)
print("# of keypoints: {}".format(len(kps)))
# 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)
# show the image
cv2.imshow("Images", np.hstack([orig, image]))
cv2.waitKey(0)
Chúng ta thấy thuật toán đã tìm được 994 keypoints nơi hầu hết chúng tương ứng với các cạnh và góc của chữ Michael Crichton cùng với hình con khỉ. Chúng ta cũng đã phát hiện rõ ràng bốn góc của cuốn sách - cùng với hầu hết các góc tương ứng với các phím trên bàn phím.
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.