選擇性搜索算法 (Selective Search)

引言

計(jì)算機(jī)視覺領(lǐng)域有幾個(gè)基本的任務(wù):

  • object recognition:物體識(shí)別,即在給定的圖片中辨認(rèn)出其中的物體種類,例如貓,飛機(jī),行人等。這里的輸入是整個(gè)圖片,輸出是類別標(biāo)簽以及相應(yīng)的概率(自信度)。
  • image classification = object recognition
from [https://github.com/apache/incubator-mxnet/tree/master/example/image-classification]
  • object detection: 物體檢測(cè),不僅要識(shí)別圖片中的物體,還要定位 (localization),即用 bounding box 將物體圈出來。如果圖片中有多個(gè)物體,則每個(gè)物體都要有對(duì)應(yīng)的 bounding box 和識(shí)別出的類型標(biāo)簽。
from https://medium.com/synapse-blog/tech-deep-dive-object-detection-ensembles-as-graph-cliques-a7f7d33b5477

object detection 的基礎(chǔ)是 object recognition,只不過要先將圖片進(jìn)行分割,對(duì)每個(gè)分割之后的子圖區(qū)域 region (也稱為 patch) 進(jìn)行 object recognition.

由于事先并不知道物體在圖片的哪個(gè)位置,為了避免漏檢,我們應(yīng)該對(duì)圖片中盡量多的 region 進(jìn)行搜索。理論上來說,可以有無窮多個(gè) region。這里就需要一種 region proposal 的算法,以比較高效的方式提出圖片劃分 region 的方式,從而加速整個(gè) object detection 的過程并且提高準(zhǔn)確率。

本文將要介紹的 selective search 算法,是比較經(jīng)典的,也是 R-CNN 中使用的 region proposal 算法。

參考文獻(xiàn):

  1. original paper by Uijlings et al
  2. https://www.learnopencv.com/selective-search-for-object-detection-cpp-python/

基本思想

為了避免蠻力搜索,selective search 算法首先需要一個(gè)基于像素的圖像分割。這里用的是 Felzenszwalb and Huttenlocher 算法 (因?yàn)槭钱?dāng)時(shí)速度最快的算法,而且是公開的),得到一個(gè) oversegmented 的圖像分割。例如:

oversegmented.png

這里之所以用 oversegmented 圖像,是為了得到盡可能細(xì)分的區(qū)域,再以此為基礎(chǔ)逐步合并,形成更大的區(qū)域。

image segmentation 可以用作 region proposal 的基礎(chǔ),每個(gè)分割的區(qū)域都可以看作一個(gè)潛在的 region,但是一個(gè) object 往往包含了多個(gè)分割的區(qū)域,例如盛有咖啡的杯子,咖啡和杯子應(yīng)該作為一個(gè)整體來看待。因此,還要根據(jù)某種相似性原則進(jìn)行分割區(qū)域的合并,得到更大范圍的 region。

Selective search 算法考慮了 4 種相似性度量,取值都在 [0,1] 之間,越大越相似。

  • 顏色相似性 s_{colour}(r_i, r_j)
  • 紋理相似性 s_{texture}(r_i, r_j)
  • size 相似性 s_{size}(r_i, r_j),促使小的區(qū)域之間優(yōu)先合并
  • shape 相似性 s_{fill}(r_i, r_j),合并只能在緊鄰的兩個(gè)區(qū)域間進(jìn)行,遠(yuǎn)離的兩個(gè)區(qū)域不能合并

最終的相似性度量是上述四個(gè)度量的組合:
s(r_i, r_j) = a_1\times s_{colour}(r_i, r_j) + a_2\times s_{texture}(r_i, r_j) + a_3 \times s_{size}(r_i, r_j) + a_4 \times s_{fill}(r_i, r_j)
其中 a_k 取 0 或 1.

總結(jié)起來,selective search 的算法步驟非常簡(jiǎn)單:

  1. 基于 oversegmented 得到細(xì)分的區(qū)域,作為初始的 region 集合。
  2. 計(jì)算 region 兩兩之間的相似性,合并具有最大相似性的兩個(gè) region,得到新的更大的 region,加入 region 集合中。
  3. 重復(fù) step 2,直到整幅圖只剩一個(gè) region。至此,得到的 region 集合就是算法的輸出。
hierarchical-segmentation-1.jpg

實(shí)例程序

環(huán)境配置:

  • opencv >= 3.3,本機(jī)用的 4.1.0 版本
  • 安裝 opencv-contrib-python package
    pip install opencv-contrib-python --user
    
  • 測(cè)試用的圖片如下:


    from https://people.com/pets/dog-breeds-diversity-verses-cats-breeds-explainer/

具體程序:

import sys
import cv2
 
# 讀取照片,這里要根據(jù)具體情況設(shè)置路徑
im = cv2.imread("./pic/cats-dogs.jpg")

# 重置圖片大小,高設(shè)置為 400,保持高、寬比例
newHeight = 400
newWidth = int(im.shape[1]*400/im.shape[0])
im = cv2.resize(im, (newWidth, newHeight))    

# 創(chuàng)建 Selective Search Segmentation 對(duì)象
ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()

# 添加待處理的圖片
ss.setBaseImage(im)

# 可以選擇快速但是低 recall 的方式 
# 這里的 recall 指的是選擇出來的 region 是否包含了所有應(yīng)該包含的區(qū)域。recall 越高越好
#ss.switchToSelectiveSearchFast()

# 也可以選擇慢速但是高 recall 的方式
ss.switchToSelectiveSearchQuality()


# 進(jìn)行 region 劃分,輸出得到的 region 數(shù)目
rects = ss.process()
print('Total Number of Region Proposals: {}'.format(len(rects)))

# 設(shè)定要顯示的 region 數(shù)目
numShowRects = 100

# 可以通過按鍵逐步增加或者減少顯示的 region 數(shù)目
increment = 50

while True:
    # 不要在原圖上畫 bounding box,而是復(fù)制一個(gè)新圖
    imOut = im.copy()

    # 遍歷 regions
    for i, rect in enumerate(rects):
        # 通過 bounding box 顯示出指定數(shù)量的 region
        if (i < numShowRects):
            x, y, w, h = rect  # bounding box 左上角坐標(biāo) x,y, 以及 box 的寬和高
            cv2.rectangle(imOut, (x, y), (x+w, y+h), (0, 255, 0), 1) # 綠色 box,線寬為 1
        else:
            break

    # 顯示圖片+bbox
    cv2.imshow("Output", imOut)

    # 接收按鍵輸入
    k = cv2.waitKey(0) & 0xFF

    # “m” 鍵 is pressed
    if k == 109:
        # 增加顯示的 bbox 數(shù)目
        numShowRects += increment
    # “l(fā)” 鍵 is pressed
    elif k == 108 and numShowRects > increment:
        # 減少顯示的 bbox 數(shù)目
        numShowRects -= increment
    # “q” 鍵 is pressed
    elif k == 113:  
        break
# close image show window
cv2.destroyAllWindows()

最后效果如下:


regions.png

顯示的 100 個(gè) region 已經(jīng)包含了我們感興趣的待檢測(cè)區(qū)域,說明了 selective search 算法的高效。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容