首頁 > 軟體

python中的opencv 影象分割與提取

2022-06-01 22:00:51

影象分割與提取

影象中將前景物件作為目標影象分割或者提取出來。對背景本身並無興趣分水嶺演演算法及GrabCut演演算法對影象進行分割及提取。

用分水嶺演演算法實現影象分割與提取

分水嶺演演算法將影象形象地比喻為地理學上的地形表面,實現影象分割,該演演算法非常有效。

演演算法原理

任何一幅灰度影象,都可以被看作是地理學上的地形表面,灰度值高的區域可以被看成是山峰,灰度值低的區域可以被看成是山谷。

左圖是原始影象,右圖是其對應的“地形表面”。

該過程將影象分成兩個不同的集合:集水盆地和分水嶺線。我們構建的堤壩就是分水嶺線,也即對原始影象的分割。這就是分水嶺演演算法。

由於噪聲等因素的影響,採用上述基礎分水嶺演演算法經常會得到過度分割的結果。過度分割會將影象劃分為一個個稠密的獨立小塊,讓分割失去了意義。為了改善影象分割效果,人們提出了基於掩模的改進的分水嶺演演算法。改進的分水嶺演演算法允許使用者將他認為是同一個分割區域的部分標註出來(被標註的部分就稱為掩模)。分水嶺演演算法在處理時,就會將標註的部分處理為同一個分割區域。

例如:

原始影象,對其做標註處理,其中被標註為深色的三個小色塊表示,在使用掩模分水嶺演演算法時,這些部分所包含的顏色都會被分割在同一個區域內。

相關函數介紹

在OpenCV中,可以使用函數cv2.watershed()實現分水嶺演演算法。

在具體的實現過程中,還需要藉助於形態學函數、距離變換函數cv2.distanceTransform()、cv2.connectedComponents()來完成影象分割。

  • 形態學函數
    在使用分水嶺演演算法對影象進行分割前,需要對影象進行簡單的形態學處理。
  • 開運算
    開運算是先腐蝕、後膨脹的操作,開運算能夠去除影象內的噪聲
    在用分水嶺演演算法處理影象前,要先使用開運算去除影象內的噪聲,以避免噪聲對影象分割可能造成的干擾。
  • 獲取影象邊界
    通過形態學操作和減法運算能夠獲取影象的邊界。
    使用形態學變換,獲取一幅影象的邊界資訊
import cv2
import numpy as np
import matplotlib.pyplot as plt
o=cv2.imread("my.bmp", cv2.IMREAD_UNCHANGED)
k=np.ones((5,5), np.uint8)
e=cv2.erode(o, k)
b=cv2.subtract(o, e)
plt.subplot(131)
plt.imshow(o)
plt.axis('off')
plt.subplot(132)
plt.imshow(e)
plt.axis('off')
plt.subplot(133)
plt.imshow(b)
plt.axis('off')
plt.show()

使用形態學操作和減法運算能夠獲取影象的邊界資訊。但是,形態學操作僅適用於比較簡單的影象。如果影象內的前景物件存在連線的情況,使用形態學操作就無法準確獲取各個子影象的邊界了。

  • 距離變換函數distanceTransform
    當影象內的各個子圖沒有連線時,可以直接使用形態學的腐蝕操作確定前景物件,但是如果影象內的子圖連線在一起時,就很難確定前景物件了
    此時,藉助於距離變換函數cv2.distanceTransform()可以方便地將前景物件提取出來。
    函數cv2.distanceTransform()計算二值影象內任意點到最近背景點的距離。
    一般情況下,該函數計算的是影象內非零值畫素點到最近的零值畫素點的距離,即計算二值影象中所有畫素點距離其最近的值為0的畫素點的距離。

如果畫素點本身的值為0,則這個距離也為0。

  • cv2.distanceTransform()的計算結果反映了各個畫素與背景(值為0的畫素點)的距離關係。

通常情況下:

  • 如果前景物件的中心(質心)距離值為0的畫素點距離較遠,會得到一個較大的值。
  • 如果前景物件的邊緣距離值為0的畫素點較近,會得到一個較小的值。

如果對上述計算結果進行閾值化,就可以得到影象內子圖的中心、骨架等資訊。距離變換函數cv2.distanceTransform()可以用於計算物件的中心,還能細化輪廓、獲取影象前景等

函數cv2.distanceTransform()的語法格式為:

dst=cv2.distanceTransform(src, distanceType, maskSize[, dstType]])
  • src是8位元單通道的二值影象。
  • distanceType為距離型別引數

  • maskSize為掩模的尺寸
    distanceType=cv2.DIST_L1或cv2.DIST_C時,maskSize強制為3(因為設定為3和設定為5及更大值沒有什麼區別)。

  • dstType為目標影象的型別,預設值為CV_32F。
  • dst表示計算得到的目標影象,可以是8位元或32位元浮點數,尺寸和src相同。

使用距離變換函數cv2.distanceTransform(),計算一幅影象的確定前景

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('water_coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ishow=img.copy()
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2) # 進行開運算
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, fore = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
plt.subplot(131)
plt.imshow(ishow)
plt.axis('off')
plt.subplot(132)
plt.imshow(dist_transform)
plt.axis('off')
plt.subplot(133)
plt.imshow(fore)
plt.axis('off')
plt.show()

fore影象中: 比較準確地顯示出左圖內的“確定前景”。確定前景,通常是指前景物件的中心。之所以認為這些點是確定前景,是因為它們距離背景點的距離足夠遠,都是距離大於足夠大的固定閾值(0.7*dist_transform.max())的點。

  • 確定未知區域
    使用形態學的膨脹操作能夠將影象內的前景“膨脹放大”。
    當影象內的前景被放大後,背景就會被“壓縮”,所以此時得到的背景資訊一定小於實際背景的,不包含前景的“確定背景”。

為了方便說明將確定背景稱為B。

  • 距離變換函數cv2.distanceTransform()能夠獲取影象的“中心”,得到“確定前景”。
    影象中有了確定前景F和確定背景B,剩下區域的就是未知區域UN了。這部分割區域正是分水嶺演演算法要進一步明確的區域。
    針對一幅影象O,通過以下關係能夠得到未知區域UN:
  • 未知區域UN=影象O-確定背景B-確定前景F
  • 未知區域UN=(影象O-確定背景B)- 確定前景F

“影象O-確定背景B”,可以通過對影象進行形態學的膨脹操作得到。

標註一幅影象的確定前景、確定背景及未知區域。

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('water_coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ishow=img.copy()
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)
bg = cv2.dilate(opening, kernel, iterations=3)
dist = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, fore = cv2.threshold(dist,0.7*dist.max(),255,0)
fore = np.uint8(fore)
un = cv2.subtract(bg, fore)
plt.subplot(221)
plt.imshow(ishow)
plt.axis('off')
plt.subplot(222)
plt.imshow(bg)
plt.axis('off')
plt.subplot(223)
plt.imshow(fore)
plt.axis('off')
plt.subplot(224)
plt.imshow(un)
plt.axis('off')
plt.show()

  • 函數connectedComponents
    明確了確定前景後,就可以對確定前景影象進行標註了。
    在OpenCV中,可以使用函數cv2.connectedComponents()進行標註。該函數會將背景標註為0,將其他的物件使用從1開始的正整數標註。
    函數cv2.connectedComponents()的語法格式為:

retval, labels = cv2.connectedComponents( image )

  • image為8位元單通道的待標註影象。
  • retval為返回的標註的數量。
  • labels為標註的結果影象。

使用函數cv2.connectedComponents()標註一幅影象

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('water_coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ishow=img.copy()
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)
sure_bg = cv2.dilate(opening, kernel, iterations=3)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, fore = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
fore = np.uint8(fore)
ret, markers = cv2.connectedComponents(fore)
print(ret)
plt.subplot(131)
plt.imshow(ishow)
plt.axis('off')
plt.subplot(132)
plt.imshow(fore)
plt.axis('off')
plt.subplot(133)
plt.imshow(markers)
plt.axis('off')
plt.show()

前景影象的中心點被做了不同的標註(用不同顏色區分)

函數cv2.connectedComponents()在標註影象時,會將背景標註為0,將其他的物件用從1開始的正整數標註。具體的對應關係為:

  • 數值0代表背景區域。
  • 從數值1開始的值,代表不同的前景區域。

在分水嶺演演算法中,標註值0代表未知區域。所以,我們要對函數cv2.connectedComponents()標註的結果進行調整:將標註的結果都加上數值1。經過上述處理後,在標註結果中:

  • 數值1代表背景區域。
  • 從數值2開始的值,代表不同的前景區域。

為了能夠使用分水嶺演演算法,還需要對原始影象內的未知區域進行標註,將已經計算出來的未知區域標註為0即可。

關鍵程式碼:

ret, markers = cv2.connectedComponents(fore)
markers = markers+1
markers[未知區域] = 0

使用函數cv2.connectedComponents()標註一幅影象,並對其進行修正,使未知區域被標註為0

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('water_coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ishow=img.copy()
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)
sure_bg = cv2.dilate(opening, kernel, iterations=3)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, fore = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
fore = np.uint8(fore)
ret, markers1 = cv2.connectedComponents(fore)
foreAdv=fore.copy()
unknown = cv2.subtract(sure_bg, foreAdv)
ret, markers2 = cv2.connectedComponents(foreAdv)
markers2 = markers2+1
markers2[unknown==255] = 0
plt.subplot(121)
plt.imshow(markers1)
plt.axis('off')
plt.subplot(122)
plt.imshow(markers2)
plt.axis('off')
plt.show()

前景都有一個黑色的邊緣,這個邊緣是被標註的未知區域。

  • 函數cv2.watershed()
    完成上述處理後,就可以使用分水嶺演演算法對預處理結果影象進行分割了。
    在OpenCV中,實現分水嶺演演算法的函數是cv2.watershed(),其語法格式為:
markers = cv2.watershed( image, markers )
  • image是輸入影象,必須是8位元三通道的影象。在對影象使用

cv2.watershed()函數處理之前,必須先用正數大致勾畫出影象中的期望分割區域。每一個分割的區域會被標註為1、2、3等。對於尚未確定的區域,需要將它們標註為0。我們可以將標註區域理解為進行分水嶺演演算法分割的“種子”區域。

  • markers是32位元單通道的標註結果,它應該和image具有相等大小。在markers中,每一個畫素要麼被設定為初期的“種子值”,要麼被設定為**“-1”表示邊界**。

分水嶺演演算法影象分割範例

使用分水嶺演演算法進行影象分割時,基本的步驟為:

  • 通過形態學開運算對原始影象O去噪。
  • 通過腐蝕操作獲取“確定背景B”。
    需要注意,這裡得到“原始影象-確定背景”即可。
  • 利用距離變換函數cv2.distanceTransform()對原始影象進行運算,並對其進行閾值處理,得到“確定前景F”。
  • 計算未知區域UN(UN=O -B - F)
  • 利用函數cv2.connectedComponents()對原始影象O進行標註。
  • 對函數cv2.connectedComponents()的標註結果進行修正。
  • 使用分水嶺函數完成對影象的分割。

使用分水嶺演演算法對一幅影象進行分割:

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('water_coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ishow=img.copy()
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)
sure_bg = cv2.dilate(opening, kernel, iterations=3)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers+1
markers[unknown==255] = 0
markers = cv2.watershed(img, markers)
img[markers == -1] = [0,255,0] # 邊界
plt.subplot(121)
plt.imshow(ishow)
plt.axis('off')
plt.subplot(122)
plt.imshow(img)
plt.axis('off')
plt.show()

互動式前景提取

經典的前景提取技術主要使用紋理(顏色)資訊,如魔術棒工具,或根據邊緣(對比度)資訊,如智慧剪刀等。在開始提取前景時,先用一個矩形框指定前景區域所在的大致位置範圍,然後不斷迭代地分割,直到達到最好的效果。經過上述處理後,提取前景的效果可能並不理想,存在前景沒有提取出來,或者將背景提取為前景的情況,此時需要使用者干預提取過程。

使用者在原始影象的副本中(也可以是與原始影象大小相等的任意一幅影象),用白色標註要提取為前景的區域,用黑色標註要作為背景的區域。然後,將標註後的影象作為掩模,讓演演算法繼續迭代提取前景從而得到最終結果。

PowerPoint 2016提供了“刪除背景”功能。

GrabCut演演算法的具體實施過程。

  • 將前景所在的大致位置使用矩形框標註出來。
  • 此時矩形框框出的僅僅是前景的大致位置,其中既包含前景又包含背景,所以該區域實際上是未確定區域。但是,該區域以外的區域被認為是“確定背景”。
  • 根據矩形框外部的“確定背景”資料來區分矩形框區域內的前景和背景。
  • 用高斯混合模型(Gaussians Mixture Model, GMM)對前景和背景建模。
  • GMM會根據使用者的輸入 學習並建立新的畫素分佈。對未分類的畫素(可能是背景也可能是前景),根據其與已知分類畫素(前景和背景)的關係進行分類。
  • 根據畫素分佈情況生成一幅圖,圖中的節點就是各個畫素點。
  • 除了畫素點之外,還有兩個節點:前景節點和背景節點。所有的前景畫素都和前景節點相連,所有的背景畫素都和背景節點相連。每個畫素連線到前景節點或背景節點的邊的權重由畫素是前景或背景的概率來決定。
  • 圖中的每個畫素除了與前景節點或背景節點相連外,彼此之間還存在著連線。兩個畫素連線的邊的權重值由它們的相似性決定,兩個畫素的顏色越接近,邊的權重值越大。
  • 完成節點連線後,需要解決的問題變成了一幅連通的圖。在該圖上根據各自邊的權重關係進行切割,將不同的點劃分為前景節點和背景節點。
  • 不斷重複上述過程,直至分類收斂為止。

在OpenCV中,實現互動式前景提取的函數是cv2.grabCut(),其語法格式為:

mask, bgdModel, fgdModel =cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode] )
  • img為輸入影象,要求是8位元3通道的。
  • mask為掩模影象,要求是8位元單通道的。該引數用於確定前景區域、背景區域和不確定區域,可以設定為4種形式。
  • cv2.GC_BGD:表示確定背景,也可以用數值0表示。
  • cv2.GC_FGD:表示確定前景,也可以用數值1表示。
  • cv2.GC_PR_BGD:表示可能的背景,也可以用數值2表示。
  • cv2.GC_PR_FGD:表示可能的前景,也可以用數值3表示。

在最後使用模板提取前景時,會將引數值0和2合併為背景(均當作0處理),將引數值1和3合併為前景(均當作1處理)。

在通常情況下,我們可以使用白色筆刷和黑色筆刷在掩模影象上做標記,再通過轉換將其中的白色畫素設定為0,黑色畫素設定為1。

  • rect指包含前景物件的區域,該區域外的部分被認為是“確定背景”。因此,在選取時務必確保讓前景包含在rect指定的範圍內;否則,rect外的前景部分是不會被提取出來的。

只有當引數mode的值被設定為矩形模式cv2.GC_INIT_WITH_RECT時,引數rect才有意義。

其格式為(x, y, w, h),分別表示區域左上角畫素的x軸和y軸座標以及區域的寬度和高度。

如果前景位於右下方,又不想判斷原始影象的大小,對於w 和h可以直接用一個很大的值。

使用掩模模式時,將該值設定為none即可。

  • bgdModel為演演算法內部使用的陣列,只需要建立大小為(1, 65)的numpy.float64陣列。
  • fgdModel為演演算法內部使用的陣列,只需要建立大小為(1, 65)的numpy.float64陣列。
  • iterCount表示迭代的次數。

mode表示迭代模式。其可能的值與含義如下:

RECT 和MASK可以組合使用( 並的關係 )

使用GrabCut演演算法提取影象的前景

import numpy as np
import cv2
import matplotlib.pyplot as plt
o = cv2.imread('lenacolor.png')
orgb=cv2.cvtColor(o, cv2.COLOR_BGR2RGB)
mask = np.zeros(o.shape[:2], np.uint8)
bgdModel = np.zeros((1,65), np.float64)
fgdModel = np.zeros((1,65), np.float64)
rect = (50,50,400,500)
cv2.grabCut(o, mask, rect, bgdModel, fgdModel,5, cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
ogc = o*mask2[:, :, np.newaxis]
ogc=cv2.cvtColor(ogc, cv2.COLOR_BGR2RGB)
plt.subplot(121)
plt.imshow(orgb)
plt.axis('off')
plt.subplot(122)
plt.imshow(ogc)
plt.axis('off')
plt.show()

為了得到完整的前景物件,需要做一些改進。

這裡對原始影象進行標註,將需要保留的部分設定為白色,將需要刪除的背景設定為黑色。以標記好的影象作為模板,使用函數cv2.grabCut()完成前景的提取。

這個過程主要包含以下步驟:

  • 利用函數cv2.grabCut()在cv2.GC_INIT_WITH_RECT 模式下對影象進行初步的前景提取,得到初步提取的結果影象og。
  • 使用Windows系統自帶的筆刷工具,開啟要提取前景的影象,比如lena。
  • 使用白色筆刷在希望提取的前景區域做標記。
  • 使用黑色筆刷在希望刪除的背景區域做標記。
  • 將當前設定好的lena影象另存為模板影象m0。
  • 將模板影象m0中的白色值和黑色值對映到模板m中。將模板影象m0中的白色值(畫素值為255)對映為模板影象m中的確定前景(畫素值為1),將模板影象m0中的黑色值(畫素值為0)對映為模板影象m中的確定背景(畫素值為0)。
  • 以模板影象m作為函數cv2.grabCut()的模板引數(mask),對影象og完成前景提取。
    使用畫筆標記的模板影象m0不能直接作為模板(即引數mask)使用

    函數cv2.grabCut()要求,引數mask的值必須是cv2.GC_BGD(確定背景)、cv2.GC_FGD(確定前景)、cv2.GC_PR_BGD(可能的背景)、cv2.GC_PR_FGD(可能的前景),或者是0、1、2、3之中的值。
    必須先將模板影象m0中的白色值和黑色值對映到模板m上,再將模板影象m作為函數cv2.grabCut()的模板引數。

在GrabCut演演算法中使用模板提取影象的前景:

import numpy as np
import cv2
import matplotlib.pyplot as plt
o= cv2.imread('lenacolor.png')
orgb=cv2.cvtColor(o, cv2.COLOR_BGR2RGB)
mask = np.zeros(o.shape[:2], np.uint8)
bgd = np.zeros((1,65), np.float64)
fgd = np.zeros((1,65), np.float64)
rect = (50,50,400,500)
cv2.grabCut(o, mask, rect, bgd, fgd,5, cv2.GC_INIT_WITH_RECT)
mask2 = cv2.imread('mask.png',0)
mask2Show = cv2.imread('mask.png', -1)
m2rgb=cv2.cvtColor(mask2Show, cv2.COLOR_BGR2RGB)
mask[mask2 == 0] = 0
mask[mask2 == 255] = 1
mask, bgd, fgd = cv2.grabCut(o, mask, None, bgd, fgd,5, cv2.GC_INIT_WITH_MASK)
mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
ogc = o*mask[:, :, np.newaxis]
ogc=cv2.cvtColor(ogc, cv2.COLOR_BGR2RGB)
plt.subplot(121)
plt.imshow(m2rgb)
plt.axis('off')
plt.subplot(122)
plt.imshow(ogc)
plt.axis('off')
plt.show()

在函數cv2.grabCut()的實際使用中,也可以不使用矩形初始化,直接使用模板模式。構造一個模板影象,其中:

  • 使用畫素值0標註確定背景。
  • 使用畫素值1標註確定前景。
  • 使用畫素值2標註可能的背景。
  • 使用畫素值3標註可能的前景。

構造完模板後,直接將該模板用於函數cv2.grabCut()處理原始影象,即可完成前景的提取。

一般情況下,自定義模板的步驟為:

  • 先使用numpy.zeros構造一個內部畫素值都是0(表示確定背景)的影象mask,以便在後續步驟中逐步對該模板影象進行細化。
  • .使用mask[30:512, 50:400]=3,將模板影象中第30行到第512行,第50列到400列的區域劃分為可能的前景(畫素值為3,對應引數mask的含義為“可能的前景”)。
  • 使用mask[50:300, 150:200]=1,將模板影象中第50行到第300行,第150列到第200列的區域劃分為確定前景(畫素值為1,對應引數mask的含義為“確定前景”)。

在GrabCut演演算法中直接使用自定義模板提取影象的前景

import numpy as np
import cv2
import matplotlib.pyplot as plt
o= cv2.imread('lenacolor.png')
orgb=cv2.cvtColor(o, cv2.COLOR_BGR2RGB)
bgd = np.zeros((1,65), np.float64)
fgd = np.zeros((1,65), np.float64)
mask2 = np.zeros(o.shape[:2], np.uint8)
#先將掩模的值全部構造為0(確定背景),在後續步驟中,再根據需要修改其中的部分值
mask2[30:512,50:400]=3 #lena頭像的可能區域
mask2[50:300,150:200]=1 #lena頭像的確定區域,如果不設定這個區域,頭像的提取不完整
cv2.grabCut(o, mask2, None, bgd, fgd,5, cv2.GC_INIT_WITH_MASK)
mask2 = np.where((mask2==2)|(mask2==0),0,1).astype('uint8')
ogc = o*mask2[:, :, np.newaxis]
ogc=cv2.cvtColor(ogc, cv2.COLOR_BGR2RGB)
plt.subplot(121)
plt.imshow(orgb)
plt.axis('off')
plt.subplot(122)
plt.imshow(ogc)
plt.axis('off')
plt.show()

對於不同的影象,要構造不同的模板來劃分它們的確定前景、確定背景、可能的前景與可能的背景。

到此這篇關於python中的opencv 影象分割與提取 的文章就介紹到這了,更多相關opencv影象分割 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com