一、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來填充。