一、學習目標
了解什麼是ROI了解floodFill的使用方法如有錯誤歡迎指出~
目錄
「python opencv 計算機視覺零基礎實戰」 第一節
「python opencv視覺入門到實戰」二、格式與攝像頭
「python opencv 視覺入門到實戰」 三、圖像編輯
「python opencv視覺入門到實戰」 第四節色彩空間
「python opencv視覺入門到實戰」 五、對象追蹤
「python opencv視覺零基礎到實戰」 六、圖像運算
「python opencv視覺零基礎實戰」 七邏輯運算應用
二、了解OpenCV中圖像ROI的顏色填充
2.1 了解ROI是什麼
ROI指的是region of Interest,翻譯過來就是你所感興趣的區域。若在一張圖片中,你感興趣的是某一個區域,那麼這個區域就可以稱為ROI。我們通過一些方法選取了該區域後,可以進行操作;例如顏色填充、圖像變換等編輯。
現有一張圖如下:
我們對這張圖的雷射雕刻機部分感興趣,那麼就可以選取該部分。如何進行選取呢?我們可以通過代碼得知該圖片的大小:
import cv2img = cv2.imread(r'C:\Users\mx\Desktop\111.png')dst=cv2.medianBlur(img,5)得到該圖片的高寬分別為447與755。
我們可以通過粗略的丈量得知雷射雕刻機應在整個圖片的正中央,那麼寬應該為一半,大致在200到400之間;由於圖片中雷射雕刻機位於圖片偏下部分,所以可以粗略得知高度在200至400之間。這時我們可以直接讀取圖片後獲取指定的行列得到該區域圖片。
cv2.imshow("img", dst)cv2.waitKey (0)cv2.destroyAllWindows()以上代碼讀取圖片後,通過選取圖片區域進行ROI選擇。img[200:400,200:400]代碼中,第一個200:400指的是200指400行,第二個200:400指的是200至400列。通過兩個選取的行與列的交叉區域則是所選擇的ROI區域。圖示如下,紅色框框表示列,紫色框框表示行,其中重疊區域則是ROI選擇區域。
以上代碼在運行結果如下:
從結果中,我們可以知道,該值的列選擇還應該往右邊移動一部分,由於我們是200至400這個區域,那麼我們現在應該移動的訪問從圖片上看,應該是接近300指500。修改代碼。
dst=cv2.blur(img,(2,24))運行後最後得到如下結果:
我們得到ROI內容後,可以對該部分的內容進行編輯,例如轉為灰度圖像:
cv2.GaussianBlur( SRC,ksize,sigmaX )結果如下:
也可以將轉換後的圖片與原圖進行結合,只需要將轉換後的圖片值對原圖該區域的值進行替換即可,完整代碼如下:
dst=cv2.GaussianBlur(img,(0,0),20) 在以上代碼中需要注意的是,灰度圖像必須轉為RGB圖形才能對原圖進行賦值。以上代碼中灰度轉RGB圖像的代碼為:
gray_roi_rgb = cv2.cvtColor(gray_roi, cv2.COLOR_GRAY2BGR)最終運行結果如下:
2.2 泛洪填充及floodFill使用方法
泛洪填充指指定起始點,通過該像素點所連結的周圍像素點在所指定的顏色值範圍內進行顏色填充。該操作需要一個遮罩或者說掩膜進行運算處理。
首先我們依舊開始讀取一張圖像:
import cv2img = cv2.imread(r'C:\Users\mx\Desktop\111.png')h,w,c=img.shape接著通過copy方法可以快速複製一張圖片:
for row in range(h): for col in range(w): b=img[row,col,0] g=img[row,col,1] r=img[row,col,2]由於我們需要建立一個遮罩,這個遮罩跟原圖片大小一致,所以代碼可以寫成如下:
srand=np.random.normal(0,30,3)img[row,col,0]=b+srand[0]img[row,col,1]=g+srand[1]img[row,col,2]=r+srand[2]以上代碼通過shape獲取了原圖片的高寬,接著通過zeros創建一個與原圖大小一致的純黑圖片。那為什麼要加2呢?因為接下來我們需要對圖片進行顏色填充,官方的規定要+2,具體什麼原因我本人沒有進行深究,按照官方要求來就可以了。
那問題來了,遮罩是什麼?還記得我們在邏輯運算應用那一個小節中,通過色彩提取後,可以得到目標對象的顏色範圍,這個顏色範圍是一張黑白圖片,白色為選取的區域,黑色為不選取的區域,這時我們通過將提取出來的圖片作為遮罩對圖片進行bitwise_and運算,這時就可以還原出原本色彩,摳選出原圖中的圖像內容。其實遮罩的作用就是如此,我們通過zeros創建一張純黑圖片後,使用floodFill函數對指定目標進行填充;在填充之前,將進行一定的計算。由於floodFill函數將會選取出目標點,該目標點將作用在這張純黑色的遮罩圖片中,該純黑圖片將會對計算後選取的點進行指的變換,該區域就會變成白色,最終得到顏色填充的區域,進行填充。
我們首先看一下floodFill函數,floodFill函數接收7個參數,函數原型如下:
floodFill(image, mask, seedPoint, newVal, loDiff=None, upDiff=None, flags=None)image為傳入的圖像參數mask為遮罩seedPoint為選中的顏色填充的起始點newVal填充的顏色像素值loDiff選中起始點的顏色像素值的最低範圍,例如是紅色,那麼紅色減去該值後得到最低的取值範圍upDiff選中起始點的顏色像素值的最高範圍,例如是紅色,那麼紅色加該值後得到最高的取值範圍flags為CV_FLOODFILL_FIXED_RANGE或者CV_FLOODFILL_MASK_ONLY,兩者填充方式不一樣,當前示例將講解CV_FLOODFILL_FIXED_RANGE。若選擇CV_FLOODFILL_FIXED_RANGE,則會比較像素點與其實像素點,若在顏色值的範圍內,則進行填充。此時我們調用floodFill方法,傳入圖片,遮罩,起始點,填充的顏色值,最低值,最高值與填充模式。cv2.floodFill(copyimg, mask, (220,420), (0, 255, 255), (5, 5, 5), (5, 5 ,5), cv2.FLOODFILL_FIXED_RANGE)copyimg為圖片;mask為遮罩;220,420為起始點;0, 255, 255為填充的顏色,為黃色;5, 5, 5為選中的起始點減去該顏色值,判斷周圍的顏色是否低於該值;5, 5 ,5為選中的起始點加上該顏色值,判斷周圍的顏色是否高於該值。最終的完整代碼如下:img = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")cv2.imshow(「img」, img)
在複製圖像上進行操作
import cv2import numpy as npimg = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")cv2.imshow("img", img)copyimg = img.copy()h, w = copyimg.shape[:2]mask = np.zeros([h + 2, w + 2], np.uint8)cv2.floodFill(copyimg, mask, (220,420), (0, 255, 255), (5, 5, 5), (5, 5 ,5), cv2.FLOODFILL_FIXED_RANGE)cv2.imshow("fill_color", copyimg)cv2.waitKey (0)#等待關閉cv2.destroyAllWindows()#destroy運行結果如下:
我們現在可以證明220,420是否是起始點,我們可以換一個值,例如0,0。若在左上角進行顏色填充那麼則判斷正確:
我們也可以改變填充值的選擇範圍,將2個5,5,5改為50,50,50,可以明顯看到效果:
dst=cv2.GaussianBlur(img,(5,5),0)這時候的相關所連結的顏色範圍擴大,那麼所能填充的範圍也肯定是擴大,運行結果如下:
其中顏色值可以可以進行修改,修改方法不再贅述。
該系列文章首發於ebaina,了解更多可查看擴展連結。
三、總結
了解了ROI是感興趣的選擇範圍了解了ROI可以通過圖片內容進行選擇,並且可以與原圖進行結合了解了泛洪填充的方法初步了解了mask遮罩以及floodFill函數的使用方法