OpenCV-泛洪填充

  • 2019 年 11 月 13 日
  • 筆記

泛洪填充簡單理解就是將指定顏色從指定位置開始填充一個連通區域,此時的連通性由像素值的接近程度來衡量。OpenCV中提供兩種泛洪填充方式:

  1. 填充彩色影像;
  2. 填充掩碼影像。

下面先來看看在OpenCV中泛洪填充的函數。

01

OpenCV中泛洪填充函數

OpenCV提供了floodFill函數進行泛洪填充,函數的完整定義:

floodFill(image, mask, seedPoint, newVal, loDiff, upDiff, flags)具體參數如下:

1. image,需要進行泛洪填充的原始影像;

2. msak,一個二值矩陣也就是說裡面元素值要不為0要不為1;

3. seedPoint,種子像素,填充的起始點像素

4. newVal,要填充的顏色;

5. loDiff,規定像素值的下限;

6. upDiff,規定像素值的上限;

7. flags,填充的方法。

這裡需要說明一點,在影像上會被填充的像素值的範圍是[seedPoind.BGR – lowDiff, seedPoint.BGR + upDiff]。

有了函數定義,接下來就看一看這兩種泛洪填充方式吧。

02

填充彩色影像

對於填充彩色影像,我們需要使用像素值的接近程度來決定是否進行填充,此時需要指定一個起始點,規定像素值的上下限,只要與起始點連接並且其像素值在定義的範圍之內,則會被填充,然後這個被填充的點連接的點,哪一個點的像素值在上面定義的範圍之內,也會被填充,如此往複,由此可以看出位置被填充的條件:

  1. 與起始點或者其他被填充的點相連接;
  2. 此位置的像素在指定範圍之內。

使用"my_love.jpg"的圖片:

具體程式碼如下:

效果如下:

此時需要注意兩點:

  1. mask只能取0,1值,此時0,1起到一個鎖定影像,
    1. 當mask對應位置為0的區域會被填充;
    2. 當mask對應位置為1的區域會被鎖定,也就是不能被填充。

而且必須要比原始影像的寬高上加兩個像素,這是OpenCV強制的,如果不這樣指定會拋出異常;

  1. cv.FLOODFILL_FIXED_RANGE,這也是使用填充圖片的方式參數,也就是設定起始點,通過設置像素區間來進行填充,這種方式直接在影像自身上進行填充,此時的掩碼mask只起到鎖定不被填充的區域
  2. seedPoint參數需要特別注意,seedPoint表示的是起始點,在前面獲取ROI的時候,通過對像素ndarray數組,通過切片的方式獲取ROI區域,我們當時將像素矩陣看成是一個高*寬維度的矩陣,想獲取影像中的某一區域直接獲取相應矩陣的區域即可。但是seedPoint是將圖片放在一個二維的坐標系中,即(x, y),通過(x, y)來選擇指定位置。具體如下圖所示:

前面說到在此模式下,mask二值掩碼(只能取0或1)能夠鎖定被圖片不被填充,比如在上面的填充圖片中,我們想保留頭部分不被填充,在提取ROI的時候我們已經提取過這一範圍了,具體的只需要將這一區域mask值設置為1即可:

# 鎖定不被填充的區域mask[151:501, 161:551] = 1

此時需要注意mask掩碼的比原始圖片長寬都大了兩個像素,因此如果選擇指定範圍,需要加上1即可。具體效果如下:

從上圖也可以看出,阻斷了像素的連通性,也是不會被填充的。

03

填充掩碼影像

掩碼就是前面所說的mask二值,前面說的填充影像,mask只起到鎖定影像的作用,而在填充掩碼影像的模式下,不直接對影像進行填充,而是對掩碼進行填充。當設置這種填充掩碼影像的模式的時候(cv.FLOODFILL_MASK_ONLY),loDiff,規定像素值的下限,upDiff,規定像素值的上限,自動會失效。此時為了效果明顯使用純色進行試驗,因為此時填充沒有了像素範圍,也就是當設置cv.FLOODFILL_MASK_ONLY的時候,原始圖片起始點周邊只能是完全相同的像素值才能被填充。

執行效果如下:

下面來具體分析,原始影像如下圖所示:

此時mask二值掩碼都為0,也就是說整張圖片都可以進行填充。此時seedPoint值為(0, 0),也就是左上角,因為左上角對於原始影像來說,有一個範圍都是白色,因此就會把這些具有相同像素值的白色進行填充。接下來再來看一個例子:

執行效果如下所示:

接下來具體分析一下,原始影像和上面一樣:

此時的mask二值掩碼就有很大的不同,此時為了表示方便,將可以填充區域,即值為0的區域用綠色進行顯示,當然這並不是mask的真實效果,mask是擁有單通道的0,1值,如果將其顯示是黑色的影像。

此時將原始圖片和mask結合:

此時設置seedPoint為(0, 0),即左上角,左上角相同顏色就是白色,但是此時二值影像只有綠色區域可以被填充,因此最終的效果:

也就是說,如果使用填充掩碼的方式,要被填充必須具備兩個條件:

  1. 起始點周邊相同的像素點;
  2. mask二值掩碼值必須為0,而且需要注意,此時顏色是填充在mask二值掩碼上,而不改變原始影像。