1. 程式人生 > >Python+OpenCV圖像處理(五)—— ROI與泛洪填充

Python+OpenCV圖像處理(五)—— ROI與泛洪填充

targe ros com ray inter color 方式 高度 lan

一、ROI

ROI(region of interest),感興趣區域。機器視覺、圖像處理中,從被處理的圖像以方框、圓、橢圓、不規則多邊形等方式勾勒出需要處理的區域,稱為感興趣區域,ROI。

代碼如下:

#進行圖片截取、合並、填充
import cv2 as cv
src=cv.imread(E:\imageload\lena.jpg)
cv.namedWindow(first_image, cv.WINDOW_AUTOSIZE)
cv.imshow(first_image, src)
face = src[200:300, 200:400]    #選擇200:300行、200:400列區域作為截取對象
gray = cv.cvtColor(face, cv.COLOR_RGB2GRAY)  #
生成的的灰度圖是單通道圖像 backface = cv.cvtColor(gray, cv.COLOR_GRAY2BGR) #將單通道圖像轉換為三通道RGB灰度圖,因為只有三通道的backface才可以賦給三通道的src src[200:300, 200:400] = backface cv.imshow("face", src) cv.waitKey(0) cv.destroyAllWindows()

運行結果:

技術分享圖片

技術分享圖片

註意:COLOR_RGB2GRAY是把三通道RGB對象轉換為單通道灰度對象

二、泛洪填充(彩色圖像填充)

代碼如下:

#泛洪填充(彩色圖像填充)
import cv2 as cv
import
numpy as np def fill_color_demo(image): copyImg = image.copy() h, w = image.shape[:2] mask = np.zeros([h+2, w+2],np.uint8) #mask必須行和列都加2,且必須為uint8單通道陣列 #為什麽要加2可以這麽理解:當從0行0列開始泛洪填充掃描時,mask多出來的2可以保證掃描的邊界上的像素都會被處理 cv.floodFill(copyImg, mask, (220, 250), (0, 255, 255), (100, 100, 100), (50, 50 ,50), cv.FLOODFILL_FIXED_RANGE) cv.imshow(
"fill_color_demo", copyImg) src = cv.imread(E:/imageload/baboon.jpg) cv.namedWindow(input_image, cv.WINDOW_AUTOSIZE) cv.imshow(input_image, src) fill_color_demo(src) cv.waitKey(0) cv.destroyAllWindows()

運行結果:

技術分享圖片

技術分享圖片

註意:

1.opencv裏的mask都是為uin8類型的單通道陣列

2.泛洪填充算法也叫漫水填充算法。opencv的floodFill函數原型: floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]]) -> retval, image, mask, rect

  image參數表示輸入/輸出1或3通道,8位或浮點圖像。

  mask參數表示掩碼,該掩碼是單通道8位圖像,比image的高度多2個像素,寬度多2個像素。填充時不能穿過輸入掩碼中的非零像素。

  seedPoint參數表示泛洪算法(漫水填充算法)的起始點。

  newVal參數表示在重繪區域像素的新值。

  loDiff參數表示當前觀察像素值與其部件鄰域像素值或待加入該組件的種子像素之間的亮度或顏色之負差的最大值。

  upDiff參數表示當前觀察像素值與其部件鄰域像素值或待加入該組件的種子像素之間的亮度或顏色之正差的最大值。

  flags參數:操作標誌符,包含三部分:(參考https://www.cnblogs.com/little-monkey/p/7598529.html)

    低八位(0~7位):用於控制算法的連通性,可取4(默認)或8。

    中間八位(8~15位):用於指定掩碼圖像的值,但是如果中間八位為0則掩碼用1來填充。

    高八位(16~32位):可以為0或者如下兩種標誌符的組合:

    FLOODFILL_FIXED_RANGE:表示此標誌會考慮當前像素與種子像素之間的差,否則就考慮當前像素與相鄰像素的差。FLOODFILL_MASK_ONLY:表示函數不會去填充改變原始圖像,而是去填充掩碼圖像mask,mask指定的位置為零時才填充,不為零不填充。  

3.個人理解:參數3起始點的像素值減去參數5的像素值表示的是從起始點開始搜索周邊範圍的像素最低值,參數3起始點的像素值加上參數5的像素值表示的是從起始點開始搜索周邊範圍的像素最大值。有了這個範圍,然後該函數就可以在這個連續像素範圍內填充指定的顏色newVal參數值。

4.設置FLOODFILL_FIXED_RANGE – 改變圖像,泛洪填充

設置FLOODFILL_MASK_ONLY – 不改變圖像,只填充遮罩層本身,忽略新的顏色值參數

三、泛洪填充(二值圖像填充)

代碼如下:

#泛洪填充(二值圖像填充)
import cv2 as cv
import numpy as np
def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300] = 255
    cv.imshow("fill_binary", image)
    mask = np.ones([402, 402], np.uint8)   #mask要保證比原圖像高和寬都多2
    mask[101:301, 101:301] = 0
    cv.floodFill(image, mask, (200,200), (255 , 0, 0), cv.FLOODFILL_MASK_ONLY) #mask不為0的區域不會被填充,mask為0的區域才會被填充
    cv.imshow("filled_binary", image)
fill_binary()
cv.waitKey(0)
cv.destroyAllWindows()

運行結果:

技術分享圖片

技術分享圖片

註意:

1.個人認為,不管是FLOODFILL_FIXED_RANGE還是FLOODFILL_MASK_ONLY操作,泛洪填充都不會填充掩膜mask的非零像素區域

2. mask[101:301, 101:301] = 0 這條語句為什麽是101:301而不是100:300呢?我覺得應該是掩膜mask是比原圖像左右上下都多了1,所以掩膜mask左右一共比原圖像多2,上下也比原圖像多2。那麽原圖像的100就自然對應到掩膜的101,同樣原圖像的300就自然對應到掩膜的301。

3.當FLOODFILL_MASK_ONLY設置了的時候,原圖不會改變,只會用中間八位的值填沖mask。 floodFill的flags參數的中間八位的值就是用於指定填充掩碼圖像的值的,但是如果flags中間八位的值為0,則掩碼會用1來填充。

Python+OpenCV圖像處理(五)—— ROI與泛洪填充