iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0
Software Development

【錢不夠買ps的我,只好用OpenCV來修圖了!】系列 第 21

【沒錢ps,我用OpenCV!】Day 21 - 花式修圖3,OpenCV 也有 photoshop 的魔術棒工具?! 漫水填充法 cv2.floodFill (Magic Wand Tool)

先來看看今天的結果圖

https://ithelp.ithome.com.tw/upload/images/20201003/20120424hmhfl6eFFu.png

-> 此篇文章的程式碼 github

Day21_魔術棒工具_magic_wand_tool.ipynb

前言

花式修圖的這個系列...
主要會講的是一些比進階再更進階的內容,
會有比較多冷門的功能,或是更難的演算法。

OpenCV 也有 photoshop 的魔術棒工具?!

今天要來介紹的是 OpenCV 中類似 photoshop 魔術棒工具的函數,
我們稱之為「漫水填充法」 cv2.floodFill

def floodfill(img, seed=(0, 0), loDiff=40, upDiff=30):
    copyimg = img.copy()
    h, w = img.shape[:2]
    mask = np.zeros([h+2, w+2], np.uint8) 
    cv2.floodFill(copyimg, mask, seed, (0, 0, 0), (loDiff, loDiff, loDiff), (upDiff, upDiff, upDiff), cv2.FLOODFILL_FIXED_RANGE)  

他的原理是從一個點的資訊出發,我們開始尋找鄰近點是否有與他相似的值,
如果有,則填充一樣的顏色,最後我們可以再利用此顏色進行其他修圖。

cv2.floodFill 的函數定義

cv2.floodFill(image, mask, seedPoint, newVal, loDiff, upDiff, flags)
  • image: 你的圖
  • mask: 遮罩,預設為「原圖的大小長寬各+2」
  • seedPoint: 種子點 (顏色對照點)
  • newVal: 要填充的顏色
  • loDiff: 與種子點顏色之負向顏色差距最大值
  • upDiff: 與種子點顏色之正向顏色差距最大值
  • flags: 可以分為
    • FLOODFILL_MASK_ONLY: 設定則表示不改變原始圖片(等於忽略newVal的值),結果會改變在mask裡面
    • FLOODFILL_FIXED_RANGE: 設定這個表示考慮當前像素與種子點的差,沒有則代表都與鄰近的比
    • 以上兩個參數可以用 or 相連表示同時使用: 即 FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE

「漫水填充法」 cv2.floodFill實作

又要來借用我自己的照片當示範一下啦...

原圖:

https://ithelp.ithome.com.tw/upload/images/20201003/20120424I8h5HiKBhH.png

填充後(此處用黃色來凸顯效果):

https://ithelp.ithome.com.tw/upload/images/20201003/201204242WAh3Wqxmk.png

當然這參數我有調過,實際上使用也需要自行調整參數以達到最佳效果。

用二值化濾出人物

img2gray = cv2.cvtColor(copyimg2,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY)

https://ithelp.ithome.com.tw/upload/images/20201003/20120424Weo97Wq1kJ.png

https://ithelp.ithome.com.tw/upload/images/20201003/2012042411NaUUT8RA.png

其實操作很簡單,一開始填充值都設 黑色(0,0,0)
在二值化時,只需要將閥值設1 (1>0) 即可得到過濾出人物。

手動去掉不要的部分

roi = mask2[400:550, 950:w] # roi_y, roi_x
roi[np.where(roi > 254)] = 0
mask2[400:550, 950:w] = roi

https://ithelp.ithome.com.tw/upload/images/20201003/20120424TuAHYuFMEa.png

這部分沒辦法,就算用 photoshop 的魔術棒工具也是會有不完美的部分,
我們在針對區域去掉我們不要的地方。

得到最後乾淨的人物遮罩圖片

mask_inv = cv2.bitwise_not(mask2)

https://ithelp.ithome.com.tw/upload/images/20201003/20120424OhfpvRXI1Z.png

運用之前 cv2.bitwise_not的技巧,
快速得到我們人物的遮罩。

Reference

https://www.cnblogs.com/youmuchen/p/7450049.html

https://docs.opencv.org/master/d0/d86/tutorial_py_image_arithmetics.html

https://blog.csdn.net/weixin_42508025/article/details/84029054?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

https://blog.csdn.net/E01114255/article/details/76186656?utm_source=blogxgwz4&utm_medium=distribute.pc_relevant.none-task-blog-title-9&spm=1001.2101.3001.4242

https://www.itread01.com/content/1537189082.html


上一篇
【沒錢ps,我用OpenCV!】Day 20 - 花式修圖2,OpenCV 的各種 Threshold 方法整理,Otsu's Threshold 大津二值化,自動計算最佳閥值,做出最好的黑白效果圖!
下一篇
【沒錢ps,我用OpenCV!】Day 22 - 綜合運用1,用 OpenCV 來P圖囉! 來運用各種之前學習的各種東西吧! merge two images
系列文
【錢不夠買ps的我,只好用OpenCV來修圖了!】30

尚未有邦友留言

立即登入留言