Đặc trưng ORB
Khi một robot chạy trong hành lang nhà xưởng, camera của nó không nhìn thế giới như con người nhìn. Với ta, một góc kệ hàng, một mép thùng carton hay vạch nối trên sàn đều là những chi tiết dễ nhận ra. Với máy tính, tất cả chỉ là một ma trận cường độ sáng thay đổi từng frame.
Vấn đề nằm ở đây: ở frame trước, robot thấy một góc kệ tại vị trí . Sang frame sau, góc đó dịch sang chỗ khác vì camera đã di chuyển. Nếu hệ thống tìm lại được cùng góc kệ này trong frame mới, nó có một mảnh thông tin rất quý: camera đã dịch chuyển như thế nào so với cảnh. Nếu tìm được hàng trăm mảnh như vậy, ta bắt đầu ước lượng được chuyển động, dựng được quỹ đạo, và đưa chúng vào visual odometry hoặc SLAM.
ORB được thiết kế cho bài toán đó. Nó không cố hiểu ảnh ở mức ngữ nghĩa. Nó chỉ cố làm một việc thật nhanh: chọn ra những điểm ảnh ổn định, gán cho mỗi điểm một chữ ký nhị phân, rồi so khớp các chữ ký đó giữa hai ảnh.
💡 Info: ORB hữu ích không phải vì nó “thông minh”, mà vì nó biến một bài toán hình học lặp lại hàng nghìn lần mỗi giây thành các phép toán rất rẻ trên bit.
Từ hai frame ảnh đến các cặp điểm tương ứng
Ta bắt đầu bằng một yêu cầu rất thực tế. Camera có hai ảnh liên tiếp, gọi là và . Trong ảnh thứ nhất có một tập điểm đặc trưng:
Ở ảnh kế tiếp, ta cũng phát hiện được một tập điểm:
Điều ta cần không chỉ là hai tập điểm này. Ta cần biết điểm nào ở tương ứng với điểm nào ở :
Trong đó:
- là một điểm đặc trưng ở frame .
- là một điểm đặc trưng ở frame .
- Ký hiệu nói rằng hai điểm nhiều khả năng đến từ cùng một cấu trúc vật lý trong cảnh.
Nếu robot chỉ đi qua một bức tường trắng trơn, bài toán này gần như không có gì để bám. Nhưng trong một nhà kho có cạnh hộp, nhãn hàng, góc kệ, vít, khe nối và các vùng texture nhỏ, ảnh có rất nhiều điểm có thể dùng làm mốc. ORB sinh ra để khai thác đúng những mốc kiểu đó.

Một điểm đặc trưng tốt cần có hai phần. Phần đầu là vị trí keypoint: nó cho biết ta nên nhìn vào đâu trong ảnh. Phần thứ hai là descriptor: một đoạn mã ngắn mô tả vùng ảnh quanh keypoint để sau này có thể nhận ra nó. ORB xử lý cả hai phần này bằng một pipeline khá gọn.
ORB ghép FAST, hướng keypoint và BRIEF xoay
Tên đầy đủ của ORB là Oriented FAST and Rotated BRIEF. Cái tên này gần như đã nói hết thiết kế:
FASTdùng để phát hiện các điểm góc nhanh.Orientednghĩa là mỗi keypoint được gán thêm một hướng chính.Rotated BRIEFnghĩa là descriptor BRIEF được xoay theo hướng đó để bớt nhạy với việc camera quay.
Kết quả cuối cùng của ORB cho mỗi keypoint thường gồm vị trí, scale, hướng và một descriptor nhị phân. Descriptor này hay có độ dài 256 bit. Vì nó là bit vector, việc so khớp hai descriptor chỉ cần XOR và đếm số bit khác nhau.

Cách thiết kế này rất hợp với robot real-time. Trong mỗi frame, hệ thống có thể phải xử lý hàng nghìn keypoint. Nếu mỗi descriptor là một vector float lớn, matching sẽ tốn đáng kể. Với ORB, mỗi descriptor chỉ là một chuỗi bit ngắn, đủ nhẹ để chạy trên CPU phổ thông.
FAST chọn những điểm có cấu trúc góc rõ
FAST nhìn vào một pixel ứng viên và xét 16 pixel nằm trên vòng tròn nhỏ quanh nó. Gọi intensity tại tâm là , intensity tại pixel thứ trên vòng tròn là , và ngưỡng tương phản là .
Một pixel trên vòng tròn được xem là sáng hơn tâm nếu:
và tối hơn tâm nếu:
Trong đó:
- là cường độ sáng tại pixel trung tâm.
- là cường độ sáng tại một pixel trên vòng tròn kiểm tra.
- là ngưỡng để bỏ qua các dao động nhỏ do noise hoặc nén ảnh.
FAST xem là corner nếu trên vòng tròn có một cung liên tiếp đủ dài mà các pixel đều sáng hơn tâm, hoặc đều tối hơn tâm. Với một vùng phẳng, các điểm quanh vòng tròn không tạo ra cấu trúc mạnh như vậy. Với một cạnh thẳng, sự thay đổi thường chỉ rõ theo một phía. Với một góc, vòng tròn cắt qua nhiều vùng sáng tối khác nhau, nên điều kiện FAST dễ được thỏa.

Trong thực tế, FAST thường phát hiện nhiều điểm hơn mức ta muốn giữ. ORB vì vậy dùng thêm Harris score để xếp hạng keypoint. FAST chịu trách nhiệm tìm nhanh, Harris score giúp ưu tiên những góc có cấu trúc ổn định hơn.
Một keypoint cần có hướng, nếu không descriptor sẽ dễ đổi khi ảnh xoay
Nếu chỉ dùng FAST, ta biết keypoint nằm ở đâu, nhưng chưa biết patch quanh nó đang quay theo hướng nào. Điều này gây vấn đề cho BRIEF. BRIEF đo quan hệ sáng tối giữa các cặp điểm cố định trong patch. Khi camera xoay, cùng một cấu trúc vật lý bị xoay trong ảnh, còn các cặp điểm đo vẫn nằm ở vị trí cũ. Descriptor vì thế có thể đổi mạnh dù vật thật không đổi.
ORB xử lý bằng cách tính hướng chính của patch quanh keypoint. Nó dùng moment cường độ:
Trong đó:
- là cường độ sáng tại tọa độ trong patch.
- và là bậc moment theo trục và .
- Tổng được tính trên các pixel quanh keypoint.
Từ đó, trọng tâm cường độ của patch là:
Trong đó:
- là tổng cường độ sáng của patch.
- cho biết phân bố sáng lệch theo trục .
- cho biết phân bố sáng lệch theo trục .
- là vị trí trọng tâm sáng.
Góc của keypoint được lấy từ vector nối tâm patch đến trọng tâm sáng:
Nếu một vùng sáng trong patch lệch sang phải, vector hướng cũng nghiêng sang phải. Khi camera xoay, phân bố sáng trong patch xoay theo, vector này cũng xoay theo. ORB dùng chính góc đó để căn lại mẫu đo BRIEF.

Bước này không làm ORB bất biến tuyệt đối với mọi kiểu xoay. Nó chỉ đưa descriptor về một hệ tọa độ cục bộ hợp lý hơn. Với SLAM và tracking frame-to-frame, mức ổn định đó thường đã đủ hữu dụng.
BRIEF biến một patch thành chuỗi bit
Sau khi đã có vị trí và hướng, ORB cần mô tả patch quanh keypoint. BRIEF làm việc này theo cách gần như tối giản: chọn nhiều cặp điểm trong patch, rồi với mỗi cặp chỉ hỏi một câu: điểm nào sáng hơn?
Với cặp điểm , bit thứ được tính bằng:
Trong đó:
- và là hai vị trí lấy mẫu trong patch.
- và là intensity tại hai vị trí đó.
- là một bit trong descriptor.
Khi có cặp test, descriptor của keypoint là:
Với ORB, thường là 256. Một descriptor 256 bit không chứa nhiều thông tin như một mô tả ảnh dày đặc, nhưng nó đủ để phân biệt nhiều patch cục bộ trong cùng một frame. Quan trọng hơn, nó cực kỳ rẻ để lưu và so khớp.
BRIEF gốc không xử lý tốt rotation. ORB xoay pattern test theo góc keypoint đã tính:
Trong đó:
- là tập tọa độ các cặp điểm test ban đầu.
- là ma trận xoay theo góc .
- là pattern test đã căn theo hướng keypoint.
Nói theo cách gần với triển khai, ta không xoay cả ảnh. Ta xoay vị trí các cặp điểm dùng để đo patch. Nhờ vậy, descriptor vẫn tương đối nhất quán khi cùng một góc ảnh xuất hiện với hướng khác.

Image pyramid giúp ORB chịu được thay đổi kích thước
Camera tiến gần một thùng hàng thì góc nhãn trên thùng sẽ lớn hơn trong ảnh. Nếu chỉ xử lý ở một độ phân giải, một keypoint nhỏ ở frame trước có thể không còn giống chính nó ở frame sau.
ORB dùng image pyramid để giảm vấn đề này. Từ ảnh gốc , ta tạo các ảnh nhỏ hơn:
Trong đó:
- là ảnh ở tầng pyramid thứ .
- là scale factor giữa hai tầng liên tiếp.
- càng lớn thì ảnh càng nhỏ.
FAST được chạy trên nhiều tầng pyramid. Keypoint vì thế không chỉ có tọa độ ảnh, mà còn có scale tương ứng với tầng nơi nó được phát hiện. Đây không phải scale invariance hoàn hảo, nhưng là đánh đổi hợp lý giữa độ ổn định và tốc độ.

Trong nhà kho, điều này có ích khi robot vừa tiến vừa xoay nhẹ. Các chi tiết như góc nhãn, cạnh hộp, khe giữa hai tấm sàn có thể thay đổi kích thước tương đối nhanh. Pyramid cho ORB thêm cơ hội tìm lại chúng ở scale gần đúng.
Matching bằng Hamming distance chỉ là bước đầu
Descriptor của ORB là vector bit, nên khoảng cách tự nhiên giữa hai descriptor là Hamming distance:
Trong đó:
- là bit thứ của descriptor thứ nhất.
- là bit thứ của descriptor thứ hai.
- bằng 1 nếu hai bit khác nhau, bằng 0 nếu giống nhau.
- là số vị trí bit khác nhau.
Trên CPU, phép này thường được triển khai bằng XOR rồi popcount. Nếu hai descriptor giống nhau ở nhiều vị trí, khoảng cách nhỏ. Nếu khác nhau nhiều, khoảng cách lớn.

Không nên hiểu matching ORB là kết luận cuối cùng. Descriptor chỉ nói hai patch trông giống nhau theo mẫu bit. Trong cảnh có nhiều cấu trúc lặp lại như kệ hàng, ô gạch, lỗ vít hoặc nhãn giống nhau, match sai là chuyện bình thường. Pipeline thực tế thường thêm cross-check, ratio test, rồi dùng RANSAC để lọc theo ràng buộc hình học.
Với visual odometry, các match sau khi lọc có thể được dùng để ước lượng essential matrix hoặc pose tương đối. Với image stitching, chúng có thể đi vào homography. ORB làm phần đầu của chuỗi đó: tạo đủ ứng viên tốt, thật nhanh.
Dùng ORB trong OpenCV mà không quên các nút chỉnh
Đoạn code dưới đây là phiên bản tối giản để tìm match giữa hai frame. Nó chưa phải pipeline SLAM hoàn chỉnh, nhưng đủ để kiểm tra chất lượng keypoint và descriptor.
import cv2
img1 = cv2.imread("frame_t.png", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("frame_t1.png", cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create(
nfeatures=1200,
scaleFactor=1.2,
nlevels=8,
fastThreshold=20,
)
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = matcher.match(des1, des2)
matches = sorted(matches, key=lambda m: m.distance)
vis = cv2.drawMatches(
img1, kp1,
img2, kp2,
matches[:120],
None,
flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS,
)
cv2.imwrite("orb_matches.png", vis)nfeatures quyết định số keypoint tối đa giữ lại. fastThreshold cao thì keypoint ít hơn nhưng thường sạch hơn. scaleFactor và nlevels điều khiển pyramid. cv2.NORM_HAMMING là lựa chọn đúng cho descriptor nhị phân; dùng nhầm khoảng cách kiểu Euclidean ở đây là sai bản chất.
Nếu quá ít keypoint, hãy giảm fastThreshold hoặc tăng nfeatures. Nếu quá nhiều match sai, đừng vội tăng số keypoint; hãy kiểm tra blur, ánh sáng, texture, và thêm lọc hình học. Với robot thật, chất lượng ảnh đầu vào thường quan trọng không kém tham số thuật toán.
Khi nào ORB là lựa chọn tốt?
ORB hợp với các bài toán cần hình học cục bộ nhanh: visual odometry cổ điển, SLAM dựa trên feature, image stitching, object matching đơn giản, tracking giữa các frame gần nhau. Nó đặc biệt dễ debug vì ta có thể nhìn trực tiếp keypoint, descriptor distance và match.
ORB yếu khi cảnh ít texture, ảnh bị motion blur mạnh, ánh sáng thay đổi gắt, hoặc vật thể có bề mặt lặp lại quá nhiều. Nó cũng không hiểu ngữ nghĩa. ORB không biết đâu là kệ hàng hay thùng carton; nó chỉ biết các patch nào có mẫu sáng tối tương tự.
Điểm đáng học ở ORB là cách nó chọn đánh đổi. Nó không cố mô tả ảnh thật giàu. Nó chọn mô tả vừa đủ, nhưng đủ nhanh để lặp lại hàng nghìn lần. Trong nhiều hệ robotics, một thuật toán như vậy đôi khi đáng giá hơn một mô hình phức tạp nhưng khó chạy ổn định trên phần cứng thật.
ORB không phải phương pháp mới, nhưng nó vẫn là một ví dụ đẹp về thiết kế thuật toán cho hệ thống thật. Nó biết mình cần làm gì, bỏ qua những thứ không cần, và tối ưu đúng chỗ: phát hiện nhanh, mô tả gọn, so khớp rẻ, dễ đưa vào pipeline lớn hơn.