欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

OpenCV-Python學(xué)習(xí)筆記(十八):使用 GrabCut 算法進(jìn)行

系統(tǒng) 1941 0

Interactive Foreground Extraction using GrabCut Algorithm:

目標(biāo)
在本節(jié)中我們將要學(xué)習(xí):
? GrabCut 算法原理,使用 GrabCut 算法提取圖像的前景
? 創(chuàng)建一個(gè)交互是程序完成前景提取?

原理
GrabCut 算法是由微軟劍橋研究院的 Carsten_Rother, Vladimir_Kolmogorov和 Andrew_Blake 在文章《GrabCut”: interactive foreground extraction using iterated graph cuts》中共同提出的。此算法在提取前景的操作過程中需要很少的人機(jī)交互,結(jié)果非常好。?

從用戶的角度來看它到底是如何工作的呢?開始時(shí)用戶需要用一個(gè)矩形將前景區(qū)域框?。ㄇ熬皡^(qū)域應(yīng)該完全被包括在矩形框內(nèi)部)。然后算法進(jìn)行迭代式分割直達(dá)達(dá)到最好結(jié)果。但是有時(shí)分割的結(jié)果不夠理想,比如把前景當(dāng)成了背景,或者把背景當(dāng)成了前景。在這種情況下,就需要用戶來進(jìn)行修改了。用戶只需要在不理想的部位畫一筆(點(diǎn)一下鼠標(biāo))就可以了。畫一筆就等于在告訴計(jì)算機(jī):“嗨,老兄,你把這里弄反了,下次迭代的時(shí)候記得改過來呀!”。然后,在下一輪迭代的時(shí)候你就會(huì)得到一個(gè)更好的結(jié)果了。

如下圖所示。運(yùn)動(dòng)員和足球被藍(lán)色矩形包圍在一起。其中有我做的幾個(gè)修正,白色畫筆表明這里是前景,黑色畫筆表明這里是背景。最后我得到了一個(gè)很好的結(jié)果。??

OpenCV-Python學(xué)習(xí)筆記(十八):使用 GrabCut 算法進(jìn)行交互式前景提取_第1張圖片

在整個(gè)過程中到底發(fā)生了什么呢?
? 用戶輸入一個(gè)矩形。矩形外的所有區(qū)域肯定都是背景(我們?cè)谇懊嬉呀?jīng)提到,所有的對(duì)象都要包含在矩形框內(nèi))。矩形框內(nèi)的東西是未知的。同樣用戶確定前景和背景的任何操作都不會(huì)被程序改變。

? 計(jì)算機(jī)會(huì)對(duì)我們的輸入圖像做一個(gè)初始化標(biāo)記。它會(huì)標(biāo)記前景和背景像素。?

? 使用一個(gè)高斯混合模型(GMM)對(duì)前景和背景建模。
? 根據(jù)我們的輸入, GMM 會(huì)學(xué)習(xí)并創(chuàng)建新的像素分布。對(duì)那些分類未知的像素(可能是前景也可能是背景),可以根據(jù)它們與已知分類(如背景)的像素的關(guān)系來進(jìn)行分類(就像是在做聚類操作)。

? 這樣就會(huì)根據(jù)像素的分布創(chuàng)建一副圖。圖中的節(jié)點(diǎn)就是像素點(diǎn)。除了像素點(diǎn)做節(jié)點(diǎn)之外還有兩個(gè)節(jié)點(diǎn): Source_node 和 Sink_node。所有的前景像素都和 Source_node 相連。所有的背景像素都和 Sink_node 相連。?

? 將像素連接到 Source_node/end_node 的邊的權(quán)值由像素作為前景/背景的概率來定義。像素之間的權(quán)重由邊緣信息或像素相似度定義。如果像素顏色有較大的差異,它們之間的邊緣會(huì)得到較低的權(quán)重。

? 然后利用mincut算法對(duì)圖像進(jìn)行分割。利用最小代價(jià)函數(shù)將圖分割為兩個(gè)分離的 Source_node 和 Sink_node。代價(jià)函數(shù)是所有被切割邊的權(quán)值之和。切割后,所有連接到 Source_node 的像素被認(rèn)為是前景,所有連接到 Sink_node 的像素被認(rèn)為是背景。

? 繼續(xù)這個(gè)過程直到分類收斂。?

下圖演示了這個(gè)過程(Image Courtesy: http://www.cs.ru.ac.za/research/g02m1682/):?

OpenCV-Python學(xué)習(xí)筆記(十八):使用 GrabCut 算法進(jìn)行交互式前景提取_第2張圖片

示例

現(xiàn)在我們進(jìn)入 OpenCV 中的 grabcut 算法。 OpenCV 提供了函數(shù): cv2.grabCut() 。我們來先看看它的參數(shù):

? img - 輸入圖像
? mask-掩模圖像,用來確定那些區(qū)域是背景,前景,可能是前景/背景等。可以設(shè)置為:cv2.GC_BGD,cv2.GC_FGD,cv2.GC_PR_BGD,cv2.GC_PR_FGD,或者直接輸入 0,1,2,3 也行。
? rect - 包含前景的矩形,格式為 (x,y,w,h)
? bdgModel, fgdModel - 算法內(nèi)部使用的數(shù)組. 你只需要?jiǎng)?chuàng)建兩個(gè)大小為 (1,65),數(shù)據(jù)類型為 np.float64 的數(shù)組。
? iterCount - 算法的迭代次數(shù)
? mode 可以設(shè)置為 cv2.GC_INIT_WITH_RECT 或 cv2.GC_INIT_WITH_MASK,也可以聯(lián)合使用。這是用來確定我們進(jìn)行修改的方式,矩形模式或者掩模模式。

首先,我們來看使用矩形模式。加載圖片,創(chuàng)建掩模圖像,構(gòu)建 bdgModel和 fgdModel。傳入矩形參數(shù)。都是這么直接。讓算法迭代 5 次。由于我們?cè)谑褂镁匦文J剿孕薷哪J皆O(shè)置為 cv2.GC_INIT_WITH_RECT。運(yùn)行g(shù)rabcut。算法會(huì)修改掩模圖像,在新的掩模圖像中,所有的像素被分為四類:背景,前景,可能是背景/前景使用 4 個(gè)不同的標(biāo)簽標(biāo)記(前面參數(shù)中提到過)。然后我們來修改掩模圖像,所有的 0 像素和 2?像素都被歸為 0(背景),所有的 1 像素和 3 像素都被歸為 1(前景)。我們最終的掩模圖像就這樣準(zhǔn)備好了。用它和輸入圖像相乘就得到了分割好的圖像。?

            
              import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('messi5.jpg')
mask = np.zeros(img.shape[:2],np.uint8)

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

rect = (50,50,450,290)
# 函數(shù)的返回值是更新的 mask, bgdModel, fgdModel
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()
            
          

?結(jié)果如下:

OpenCV-Python學(xué)習(xí)筆記(十八):使用 GrabCut 算法進(jìn)行交互式前景提取_第3張圖片

哎呀,梅西的頭發(fā)被我們弄沒了!讓我們來幫他找回頭發(fā)。所以我們要在那里畫一筆(設(shè)置像素為 1,肯定是前景)。同時(shí)還有一些我們并不需要的草地。我們需要去除它們,我們?cè)僭谶@個(gè)區(qū)域畫一筆(設(shè)置像素為 0,肯定是背景)。現(xiàn)在可以象前面提到的那樣來修改掩模圖像了。

實(shí)際上我是怎么做的呢?我們使用圖像編輯軟件打開輸入圖像,添加一個(gè)圖層,使用筆刷工具在需要的地方(比如頭發(fā),鞋子,球等)使用白色繪制;使用黑色筆刷在不需要的地方繪制(比如, logo,草地等)。然后將其他地方用灰色填充,保存成新的掩碼圖像。在 OpenCV 中導(dǎo)入這個(gè)掩模圖像,根據(jù)新的掩碼圖像對(duì)原來的掩模圖像進(jìn)行編輯。代碼如下:

            
              # newmask is the mask image I manually labelled
newmask = cv2.imread('newmask.png',0)

# whereever it is marked white (sure foreground), change mask=1
# whereever it is marked black (sure background), change mask=0
mask[newmask == 0] = 0
mask[newmask == 255] = 1

mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)

mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()
            
          

?結(jié)果如下:

OpenCV-Python學(xué)習(xí)筆記(十八):使用 GrabCut 算法進(jìn)行交互式前景提取_第4張圖片

就是這樣。你也可以不使用矩形初始化,直接進(jìn)入掩碼圖像模式。使用 2像素和 3 像素(可能是背景/前景)對(duì)矩形區(qū)域的像素進(jìn)行標(biāo)記。然后象我們?cè)诘诙€(gè)例子中那樣對(duì)肯定是前景的像素標(biāo)記為 1 像素。然后直接在掩模圖像模式下使用 grabCut 函數(shù)。

OpenCV 自帶的示例中有一個(gè)使用 grabcut 算法的交互式工具 grabcut.py。

參考資料:

1.?OpenCV官方文檔-Interactive Foreground Extraction using GrabCut Algorithm

2.《OpenCV-Python 中文教程》(段力輝 譯)

?

?

?


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久久精品中文 | 国产成人免费视频网站高清观看视频 | 日本字幕在线观看 | 香蕉视频在线观看免费国产婷婷 | 亚洲一区精品在线 | 三级黄色片在线观看 | 国产精品久久久久一区二区 | 国产亚洲蜜芽精品久久 | 国产激爽大片高清在线观看 | 国产亚洲精品久久久久久打不开 | 天天干天天干天天干天天干天天干 | 亚洲午夜精品A片久久不卡蜜桃 | 日本黄a三级三级三级 | 日韩国产欧美一区二区三区 | 国产精品美女久久久久久免费 | 亚洲一区二区三区久久 | 九九热在线视频免费观看 | 国产福利区一区二在线观看 | 欧美视频不卡 | 欧美高清成人 | 国产成人精品午夜 | 91久久艹| 精品视频一区二区三区 | 欧美八区| 国产高清视频在线 | 成人午夜视频在线观看 | 妖精视频永久在线入口 | 啪一啪在线视频 | 国产高清卡一卡新区 | 欧美日色| 九九视频高清视频免费观看 | 国产中文字幕一区 | 久久久av| 成人国产永久福利看片 | 爱性久久久久久久 | 国产亚洲视频在线 | 国产精品亚洲一区二区三区在线 | 午夜大片免费男女爽爽影院久久 | 国产精品久久久久久免费 | 日韩少妇成熟A片无码专区 黄在线免费观看 | wwwwxxxx免费 |