iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
Software Development

從像素到 Computer Vision:30 天理解數位影像處理系列 第 27

Day 27 | SIFT / ORB:電腦怎麼知道兩張照片拍的是同一個地方?

  • 分享至 

  • xImage
  •  

上一篇介紹了 Harris Corner Detection。

我們知道,Harris 可以找到圖片中的角點。

在昨天結尾時,我們埋了一個伏筆:

如果今天有兩張照片,它們拍的是同一個物體。

只是拍攝角度不同,或是距離遠近不同。

電腦要怎麼知道,兩張圖片中的某個角點,其實代表的是同一個位置?

光知道哪裡有 Corner 似乎不太夠。

因為每個 Corner 看起來都很像。

所以,除了找到特徵點之外,還需要替每個特徵點建立一份屬於自己的 id 。

這就是今天要介紹的 SIFTORB

SIFT 和 ORB 在做什麼?

前面提到,如果只有 Corner 的位置,電腦還是沒辦法知道兩張圖片中的 Corner 是不是同一個地方。

因此,除了找到特徵點之外,還需要替每個特徵點記錄更多資訊,例如周圍的亮度分布、方向或紋理。

這樣即使換了一張圖片,電腦還是可以根據這些資訊,判斷兩個特徵點是不是代表同一個位置。

整個過程可以分成兩個步驟:

第一步,先找到值得觀察的地方。

例如角點、紋理或其他具有特色的位置。

這就是 Feature Detection(特徵點偵測)

第二步,替每個特徵點建立一份 Descriptor,記錄它周圍的特徵資訊。

這就是 Feature Description(特徵描述)

之後,只要比較不同圖片中的 Descriptor。

如果非常相似,電腦就能判斷,它們很可能代表同一個位置。

SIFT 是什麼?

SIFT 的全名是 Scale-Invariant Feature Transform

真正重要的是前面的 Scale-Invariant

它代表,即使圖片放大或縮小,SIFT 仍然有機會找到相同的特徵點。

除此之外,SIFT 對旋轉也有很好的適應能力。

就算圖片旋轉了一個角度,通常還是能找到相同的位置。

因此 SIFT 的辨識能力一直都非常好。

不過它的缺點也很明顯,就是速度比較慢。

ORB 是什麼?

ORB 的全名是 Oriented FAST and Rotated BRIEF

FAST (Features from Accelerated Segment Test):加速分割測試特徵
BRIEF (Binary Robust Independent Elementary Features):二進位特徵描述子

它結合了 FAST 的特徵點偵測以及 BRIEF 的特徵描述。

並加入旋轉不變性的設計。

雖然辨識能力通常沒有 SIFT 那麼強,但是速度快很多,計算量也比較低。

因此,ORB 很適合即時應用,例如機器人、AR 或行動裝置。

SIFT 和 ORB 怎麼選?

如果只是想快速理解它們的差別,可以先記住下面:

SIFT ORB
辨識能力較高 執行速度較快
對縮放、旋轉較穩定 計算量較低
Descriptor 較豐富 Descriptor 較精簡
適合離線分析 適合即時應用

並不是誰一定比較好,是根據應用需求選擇。

如果希望有比較好的匹配效果,通常會考慮 SIFT。

如果希望即時執行,ORB 通常會是更常見的選擇。

實作:使用 ORB

OpenCV 提供了 ORB。

建立 ORB 物件之後,就可以直接偵測特徵點。

import cv2
import matplotlib.pyplot as plt

img = cv2.imread("dog.jpeg", cv2.IMREAD_GRAYSCALE)

orb = cv2.ORB_create()

keypoints, descriptors = orb.detectAndCompute(img, None)

result = cv2.drawKeypoints(
    img,
    keypoints,
    None,
    flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)

接著把結果畫出來。

plt.figure(figsize=(8,6))

plt.imshow(result, cmap="gray")
plt.title("ORB Features")
plt.axis("off")

plt.show()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20260913/20181780AaT8jm1jYB.png

可以看到,圖片中會出現許多圓圈。

每一個圓圈就是一個特徵點。

圓圈越大,通常代表偵測到的尺度越大。

而圓圈上的小線段,則代表這個特徵點的方向。

那 SIFT 呢?

如果使用的是 OpenCV 4.x。

通常只要把建立 ORB 的地方改成:

sift = cv2.SIFT_create()

keypoints, descriptors = sift.detectAndCompute(img, None)

後面的程式幾乎完全相同。

因此,SIFT 和 ORB 的使用方式其實非常接近。

最大的差別,其實就是它們背後使用的演算法。

今天總結

今天介紹了 SIFT 和 ORB。

它們不只是找到圖片中的特徵點,還會替每個特徵點建立一份 Descriptor,方便在不同圖片之間進行匹配。

其中,SIFT 擁有較好的辨識能力,ORB 則擁有較快的速度,因此兩者至今仍然廣泛應用在各種專案中。

一路學到這裡,我們已經介紹了許多經典的影像處理與特徵擷取方法。

不過,如果今天的目標不是找特徵點,而是想直接找出圖片中的直線或圓形,又該怎麼做?

下一篇,我們就來介紹 Hough Transform,看看電腦如何從一張圖片中找出具有規律的幾何形狀。


上一篇
Day 26 | Harris Corner Detection:電腦怎麼找到圖片中的角落?
下一篇
Day 28 | Hough Transform:電腦怎麼從一張圖片中找出直線?
系列文
從像素到 Computer Vision:30 天理解數位影像處理30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言