Interactive Foreground Extraction using GrabCut Algorithm
วัตถุประสงค์
- เราจะได้เห็นขั้นตอนวิธีการที่จะดึง GrabCut เบื้องหน้าในภาพ
- เราจะสร้างโปรแกรมประยุกต์แบบโต้ตอบสำหรับการนี้
ทฤษฎี
GrabCut อัลกอริทึมที่ออกแบบโดยคาร์สเท Rother, Vladimir Kolmogorov และแอนดรูเบลคจาก Microsoft Research เคมบริดจ์, สหราชอาณาจักร "GrabCut": การสกัดเบื้องหน้าโต้ตอบโดยใช้กราฟตัดซ้ำ อัลกอริทึมที่จำเป็นสำหรับการสกัดเบื้องหน้าด้วยปฏิสัมพันธ์ของผู้ใช้น้อยที่สุดและผลที่ได้ GrabCut
ดูภาพด้านล่าง ผู้เล่นคนแรกและฟุตบอลถูกปิดล้อมอยู่ในกรอบสี่เหลี่ยมสีฟ้า แล้วบาง touchups สุดท้ายกับจังหวะสีขาว (denoting หน้า) และจังหวะสีดำ (พื้นหลัง denoting) จะทำ และเราจะได้รับผลดี
แสดงให้เห็นในภาพด้านล่าง (Image Courtesy: www.cs.ru.ac.za/research/g02m1682/)
DEMO
grabcut กับ OpenCV OpenCV มีฟังก์ชั่น cv2.grabCut () สำหรับเรื่องนี้ เราจะเห็นการขัดแย้งครั้งแรก
- img - ภาพที่นำเข้า
- mask - มันเป็นภาพหน้ากากที่เราระบุพื้นที่ที่มีพื้นหลังเบื้องหน้าหรือพื้นหลัง / เบื้องหน้า ฯลฯ มันจะกระทำโดย cv2.GC_BGD, cv2.GC_FGD, cv2.GC_PR_BGD, cv2.GC_PR_FGD หรือเพียงแค่ผ่าน 0,1,2,3 กับภาพ
- rect - มันเป็นพิกัดของสี่เหลี่ยมซึ่งรวมถึงวัตถุเบื้องหน้าในรูปแบบที่ (x, y, W, H)
- BD รุ่น FG รุ่น - เหล่านี้เป็นอาร์เรย์ใช้โดยอัลกอริทึมภายใน คุณเพียงแค่สร้างสองประเภท np.float64 ศูนย์อาร์เรย์ขนาด (1,65)
- iterCount - จำนวนการทำซ้ำขั้นตอนวิธีควรใช้
- mode - มันควรจะเป็นหรือ cv2.GC_INIT_WITH_RECT หรือ cv2.GC_INIT_WITH_MASK หรือรวมที่ตัดสินใจว่าเราจะวาดรูปสี่เหลี่ยมผืนผ้าหรือจังหวะ TouchUp สุดท้าย
ครั้งแรกเรามาดูด้วยโหมดสี่เหลี่ยม เราโหลดภาพที่สร้างภาพหน้ากากคล้ายกัน เราสร้าง fgdModel และ bgdModel เราให้พารามิเตอร์สี่เหลี่ยมผืนผ้า มันคือทั้งหมดที่ตรงไปข้างหน้า ขอให้ขั้นตอนวิธีการทำงานเป็นเวลา 5 ซ้ำ โหมดควรจะ cv2.GC_INIT_WITH_RECT ตั้งแต่ที่เรากำลังใช้รูปสี่เหลี่ยมผืนผ้า จากนั้นเรียก grabcut ปรับเปลี่ยนภาพหน้ากาก ในภาพหน้ากากใหม่พิกเซลจะถูกทำเครื่องหมายแสดงถึงพื้นหลัง / เบื้องหน้าตามที่ระบุไว้ข้างต้น ดังนั้นเราจึงปรับเปลี่ยนหน้ากากดังกล่าวว่าทั้งหมด 0 พิกเซลและ 2 พิกเซลจะนำไป 0 (เช่นพื้นหลัง) และทุก 1 พิกเซลและ 3 พิกเซลจะนำไป 1 (เช่นเบื้องหน้าพิกเซล) ตอนนี้หน้ากากสุดท้ายของเรามีความพร้อม เพียงแค่คูณกับภาพที่นำเข้าเพื่อให้ได้ภาพที่แบ่งกลุ่ม
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('joy.jpg') mask = np.zeros(img.shape[:2],np.uint8) bgdModel = np.zeros((1,65),np.float64) fgdModel = np.zeros((1,65),np.float64) rect = (70,40,900,900) cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT) mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8') img = img*mask2[:,:,np.newaxis] plt.imshow(img),plt.colorbar(),plt.show()
ดูผลการดังต่อไปนี้