GrabCut

GrabCut簡介
    OpenCV中的GrabCut算法是依據《"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts》這篇文章來實現的。該算法利用了圖像中的紋理(顏色)信息和邊界(反差)信息,只要少量的用戶交互操作即可得到比較好的分割結果。如果前景和背景之間的顏色反差不大,分割的效果不好;不過,這種情況下允許手工標記一些前景或背景區域,這樣能得到較好的結果。經我測試,GrabCut算法的效率不高,初始化341x326大小的矩形窗大約需要20秒,處理需要9秒;而論文中宣稱初始化450x300大小的矩形窗僅0.9秒,處理只要0.12秒;雖然矩形大小和測試環境稍有區別,但是結果卻相差太多。

GrabCut函數說明
函數原型:
    void cv::grabCut( const Mat& img, Mat& mask, Rect rect,
             Mat& bgdModel, Mat& fgdModel,
             int iterCount, int mode )
其中:
img——待分割的源圖像,必須是8位3通道(CV_8UC3)圖像,在處理的過程中不會被修改;
mask——掩碼圖像,如果使用掩碼進行初始化,那麼mask保存初始化掩碼信息;在執行分割的時候,也可以將用戶交互所設定的前景與背景保存到mask中,然後再傳入grabCut函數;在處理結束之後,mask中會保存結果。mask只能取以下四種值:
GCD_BGD(=0),背景;
GCD_FGD(=1),前景;
GCD_PR_BGD(=2),可能的背景;
GCD_PR_FGD(=3),可能的前景。
如果沒有手工標記GCD_BGD或者GCD_FGD,那麼結果只會有GCD_PR_BGD或GCD_PR_FGD;
rect——用於限定需要進行分割的圖像範圍,只有該矩形窗口內的圖像部分才被處理;
bgdModel——背景模型,如果爲null,函數內部會自動創建一個bgdModel;bgdModel必須是單通道浮點型(CV_32FC1)圖像,且行數只能爲1,列數只能爲13x5;
fgdModel——前景模型,如果爲null,函數內部會自動創建一個fgdModel;fgdModel必須是單通道浮點型(CV_32FC1)圖像,且行數只能爲1,列數只能爲13x5;
iterCount——迭代次數,必須大於0;
mode——用於指示grabCut函數進行什麼操作,可選的值有:
GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;
GC_INIT_WITH_MASK(=1),用掩碼圖像初始化GrabCut;
GC_EVAL(=2),執行分割。

GrabCut的用法
    您可以按以下方式來使用GrabCut函數:
(1)用矩形窗或掩碼圖像初始化grabCut;
(2)執行分割;
(3)如果對結果不滿意,在掩碼圖像中設定前景和(或)背景,再次執行分割;
(4)使用掩碼圖像中的前景或背景信息。

從上述圖片中可以看出,用更多的迭代次數,或者更多的用戶交互都能得到更好的結果。

示例
    下面是一個使用GrabCut進行圖像分割的例子,其中用了P/INVOKE形式的CvGrabCut函數,以及封裝在Image<TColor,TDepth>類中的GrabCut方法。封裝的方法便於使用,但是缺少一些功能,靈活性不足。

來自:http://www.cnblogs.com/xrwang/archive/2010/04/27/GrabCut.html

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