選擇性搜索(Select Search)

候選區域(Region Proposal)算法

滑窗法的問題可以使用候選區域產生算法解決。這些算法輸入整張圖片,然後輸出可能有物體的候選區域位置,這些候選區域可以有噪聲或者重疊,或者和物體的重合度不是很好,這都不要緊,只要這些區域裏有一個和實際物體的位置足夠接近就行。因爲不好的候選區域會被物體識別算法過濾掉。

 

候選區域算法用分割不同區域的辦法來識別潛在的物體。在分割的時候,我們要合併那些在某些方面(如顏色、紋理)類似的小區域。相比滑窗法在不同位置和大小的窮舉,候選區域算法將像素分配到少數的分割區域中。所以最終候選區域算法產生的數量比滑窗法少的多,從而大大減少運行物體識別算法的次數。同時候選區域算法所選定的範圍天然兼顧了不同的大小和長寬比。

 

候選區域算法比較重要的特徵就是要有較高的召回率。我們要通過這種方法保證擁有物體的區域就在候選區域列表裏。所以我們不介意有很多區域什麼都有,這都沒關係,物體檢測算法會過濾掉他們,雖然會浪費一點時間。

 

物體檢測之選擇性搜索(Selective Search)

選擇性搜索算法用於爲物體檢測算法提供候選區域,它速度快,召回率高。

 

選擇性搜索算法需要先使用《Efficient Graph-Based Image Segmentation》論文裏的方法產生初始的分割區域,然後使用相似度計算方法合併一些小的區域。
下列兩張圖分別是原圖和原始分割圖:

 

 

我們不能使用原始分割圖的區域作爲候選區域,原因如下:

  1. 大部分物體在原始分割圖裏都被分爲多個區域
  2. 原始分割圖無法體現物體之間的遮擋和包含。

如果我們試圖通過進一步合併相鄰的區域來解決第一個問題,我們最終會得到一個包含兩個對象的分段區域。

我們不要需要完美的的分割區域,我們只想要和實際物體高度重合的區域就行了。

選擇性搜索算法使用《Efficient Graph-Based Image Segmentation》論文裏的方法產生初始的分割區域作爲輸入,通過下面的步驟進行合併:

  1. 首先將所有分割區域的外框加到候選區域列表中
  2. 基於相似度合併一些區域
  3. 將合併後的分割區域作爲一個整體,跳到步驟1

通過不停的迭代,候選區域列表中的區域越來越大。可以說,我們通過自底向下的方法創建了越來越大的候選區域。表示效果如下:

相似度

選擇性搜索算法如何計算兩個區域的像素度的呢?
主要是通過以下四個方面:顏色、紋理、大小和形狀交疊
最終的相似度是這四個值取不同的權重相加

效果

opencv實現了選擇性搜索算法,可以給出上千個根據有物體的可能性降序排列的候選區域。
下圖是畫出了前面250個候選區域的效果。一般來說。1200個候選區域基本能勝任物體檢測的任務了。

 

opencv中的實現-python版本

代碼主要參考《Selective Search for Object Detection (C++ / Python)》

#!/usr/bin/env python
'''
Usage:
    ./ssearch.py input_image (f|q)
    f=fast, q=quality
Use "l" to display less rects, 'm' to display more rects, "q" to quit.
'''

import sys
import cv2

if __name__ == '__main__':

    # speed-up using multithreads
    cv2.setUseOptimized( True );
    cv2.setNumThreads( 4 );

    # read image
    im = cv2.imread( './test.jpg' )
    # resize image
    newHeight = 200
    newWidth = int( im.shape[1] * 200 / im.shape[0] )
    im = cv2.resize( im, (newWidth, newHeight) )

    # create Selective Search Segmentation Object using default parameters
    ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()

    # set input image on which we will run segmentation
    ss.setBaseImage( im )

    if 1:
        # Switch to fast but low recall Selective Search method
        ss.switchToSelectiveSearchFast()
    else:
        # Switch to high recall but slow Selective Search method
        ss.switchToSelectiveSearchQuality()


    # run selective search segmentation on input image
    rects = ss.process()
    print( 'Total Number of Region Proposals: {}'.format( len( rects ) ) )

    # number of region proposals to show
    numShowRects = 100
    # increment to increase/decrease total number
    # of reason proposals to be shown
    increment = 50

    while True:
        # create a copy of original image
        imOut = im.copy()

        # itereate over all the region proposals
        for i, rect in enumerate( rects ):
            # draw rectangle for region proposal till numShowRects
            if (i < numShowRects):
                x, y, w, h = rect
                cv2.rectangle( imOut, (x, y), (x + w, y + h), (0, 255, 0), 1, cv2.LINE_AA )
            else:
                break

        # show output
        cv2.imshow( "Output", imOut )

        # record key press
        k = cv2.waitKey( 0 ) & 0xFF

        # m is pressed
        if k == 109:
            # increase total number of rectangles to show by increment
            numShowRects += increment
        # l is pressed
        elif k == 108 and numShowRects > increment:
            # decrease total number of rectangles to show by increment
            numShowRects -= increment
        # q is pressed
        elif k == 113:
            break
    # close image show window
    cv2.destroyAllWindows()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章