冒泡~好像是很久沒有寫...在實(shí)驗(yàn)室一周多了...在不斷地安裝環(huán)境和庫(kù)赞弥,其他沒有太大的進(jìn)展讯泣,今天在做顯著性圖片的提取中嗦枢,發(fā)現(xiàn)了grabcut的函數(shù)可以用來摳圖,做個(gè)小筆記附鸽。
GrabCut
簡(jiǎn)介
GrabCut該算法利用了圖像中的紋理(顏色)信息和邊界(反差)信息脱拼,只要小量的用戶交互操作即可得到比較好的分割效果
算法原理
補(bǔ)充說明:
【a.矩形外的所有區(qū)域肯定是背景。矩形框內(nèi)的東西是未知的坷备。同樣用戶確定前景和背景的任何操作都不會(huì)被程序改變挪拟。
b.根據(jù)我們的輸入,GMM會(huì)學(xué)習(xí)并創(chuàng)建新的像素分布击你。對(duì)那些分類未知的像素(可能是前景也可能是背景)玉组,可以根據(jù)他們與已知分類(如背景)的像素關(guān)系來進(jìn)行分類(就想在做聚類操作)。
c.圖中的節(jié)點(diǎn)就是像素點(diǎn)丁侄。除了像素點(diǎn)做節(jié)點(diǎn)之外還有兩個(gè)節(jié)點(diǎn):Source_node和Sink_node惯雳。所有的前景像素都和Source_node相連。所有的背景像素都和sink_node相連鸿摇。
d.兩個(gè)像素之間的權(quán)重由邊的信息或者兩個(gè)像素的相似性來決定石景。如果兩個(gè)像素的顏色有很大的不同,那么它們之間的邊的權(quán)重就會(huì)很小拙吉〕蹦酰】
具體的算法原理可參考(https://www.cnblogs.com/mikewolf2002/p/3341418.html)
函數(shù)原型
grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None)
解釋
img:待分割的源圖像,必須是8位3通道(CV_8UC3)圖像筷黔,在處理的過程中不會(huì)被修改往史;
mask:掩碼圖像,如果使用掩碼進(jìn)行初始化佛舱,那么mask保存初始化掩碼信息椎例;在執(zhí)行分割的時(shí)候,也可以將用戶交互所設(shè)定的前景與背景保存到mask中请祖,然后再傳入grabCut函數(shù)订歪;在處理結(jié)束之后,mask中會(huì)保存結(jié)果肆捕。
mask只能取以下四種值:
GCD_BGD(=0)刷晋,背景;
GCD_FGD(=1),前景眼虱;
GCD_PR_BGD(=2)或舞,可能的背景;
GCD_PR_FGD(=3)蒙幻,可能的前景映凳。
如果沒有手工標(biāo)記GCD_BGD或者GCD_FGD,那么結(jié)果只會(huì)有GCD_PR_BGD或GCD_PR_FGD邮破;
rect:用于限定需要進(jìn)行分割的圖像范圍诈豌,只有該矩形窗口內(nèi)的圖像部分才被處理;
bgdModel:背景模型抒和,如果為null矫渔,函數(shù)內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)bgdModel;bgdModel必須是單通道浮點(diǎn)型(CV_32FC1)圖像摧莽,且行數(shù)只能為1庙洼,列數(shù)只能為13x5;
fgdModel:前景模型镊辕,如果為null油够,函數(shù)內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)fgdModel;fgdModel必須是單通道浮點(diǎn)型(CV_32FC1)圖像征懈,且行數(shù)只能為1石咬,列數(shù)只能為13x5;
iterCount:迭代次數(shù)卖哎,必須大于0鬼悠;
mode:用于指示grabCut函數(shù)進(jìn)行什么操作,可選的值有:
GC_INIT_WITH_RECT(=0)亏娜,用矩形窗初始化GrabCut焕窝;
GC_INIT_WITH_MASK(=1),用掩碼圖像初始化GrabCut维贺;
GC_EVAL(=2)它掂,執(zhí)行分割。
代碼實(shí)現(xiàn)
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('F:/8.jpg')
OLD_IMG = img.copy()
mask = np.zeros(img.shape[:2], np.uint8)
SIZE = (1, 65)
bgdModle = np.zeros(SIZE, np.float64)
fgdModle = np.zeros(SIZE, np.float64)
rect = (1, 1, img.shape[1], img.shape[0])
cv2.grabCut(img, mask, rect, bgdModle, fgdModle, 10, cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img *= mask2[:, :, np.newaxis]
plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("grabcut"), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(OLD_IMG, cv2.COLOR_BGR2RGB))
plt.title("original"), plt.xticks([]), plt.yticks([])
plt.show()
效果圖
改變iterCount(迭代)的次數(shù)可以改變摳圖的精準(zhǔn)度
(不足幸缕,迭代次數(shù)越多 運(yùn)行所耗的時(shí)間更長(zhǎng))
迭代10次
迭代100次
N次之后
參考資料(https://blog.csdn.net/HuangZhang_123/article/details/80535269)
(https://blog.csdn.net/sunshine_in_moon/article/details/45200793)
Ending~
感覺實(shí)驗(yàn)是要做不出來了群发,只能祈禱畢設(shè)順利了。