Interactive Foreground Extraction using GrabCut Algorithm

จาก Morange Wiki

วัตถุประสงค์

  • เราจะได้เห็นขั้นตอนวิธีการที่จะดึง GrabCut เบื้องหน้าในภาพ
  • เราจะสร้างโปรแกรมประยุกต์แบบโต้ตอบสำหรับการนี้

ทฤษฎี
GrabCut อัลกอริทึมที่ออกแบบโดยคาร์สเท Rother, Vladimir Kolmogorov และแอนดรูเบลคจาก Microsoft Research เคมบริดจ์, สหราชอาณาจักร "GrabCut": การสกัดเบื้องหน้าโต้ตอบโดยใช้กราฟตัดซ้ำ อัลกอริทึมที่จำเป็นสำหรับการสกัดเบื้องหน้าด้วยปฏิสัมพันธ์ของผู้ใช้น้อยที่สุดและผลที่ได้ GrabCut

ดูภาพด้านล่าง ผู้เล่นคนแรกและฟุตบอลถูกปิดล้อมอยู่ในกรอบสี่เหลี่ยมสีฟ้า แล้วบาง touchups สุดท้ายกับจังหวะสีขาว (denoting หน้า) และจังหวะสีดำ (พื้นหลัง denoting) จะทำ และเราจะได้รับผลดี
แสดงให้เห็นในภาพด้านล่าง (Image Courtesy: www.cs.ru.ac.za/research/g02m1682/)

Grabcut scheme.jpg


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()

ดูผลการดังต่อไปนี้

มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย