Background Subtraction

จาก Morange Wiki

Background Subtraction

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

  • เพื่อคุ้นเคยการการลบ Background ใน OpenCV

พื้นฐาน

  • การลบฉากหลังเป็นขั้นตอนที่สำคัญ Preprocessing ในการวิเคราห์ทีละเยอะๆของโปรแกรมเราเขียน (คือเอาไป Compute ให้เสร็จก่อนมาแสดง) ยกตัวอย่างการพิจารณาเช่น นับคนเข้างาน ที่ใช้กล้องถ่ายคนนับคนเข้าและออกงาน หรือ ภายในห้อง หรือ การจราจรบนท้องถนนในกรณีเหล่านั้นคุณจะต้องนำเอาบุคคลหรือรถมาเพียงอย่างเดียวเพื่อนับ โดยเทคนิคการแยก Foreground นั้นจะต้องแยกมาจาก static background
  • ถ้าหากมีภาพของพื้นหลังเพียงอย่างเดียว เช่นเดียวกันับคนของห้องพัก หรือ บนท้องถนนที่ไม่มีรถยนต์เลย นั้นจะทำให้เป็นงานง่ายมาก เพียงแค่ลบภาพใหม่จาก Background คุณสามารถหา Foreground object หรือ คน , รถยนต์ , สิ่งที่เคลื่อนไหวไม่ใช่พื้นหลัง แต่ในส่วนของกรณีที่ไม่อาจมีภาพดังกล่างมานั้น จึงต้องแยก Background และ สิ่งที่มี โดยมักจะซับซ้อนมากขึ้ยเมื่อมีเงาของยานพาหนะ ทั้งเงาที่เคลื่อนไหว โดยการลแบบง่ายๆนั้น จะสามารถทำได้หลายวิธี
  • โดย OpenCV ได้ดำเนินการเตรียมคำสั่งและฟังก์ชั่นมาไว้ให้แล้วโดยสามารถเห็นได้แบบ One-By-One เลยทีเดียว

BackgroundSubtractorMOG

  • นี่คือวิธี Gaussian Mixture-based สำหรับการแยก Background/Forefround Segmentation Algorithm นั้นถูกคิดไว้ว่า "รูปแบบการผสมที่ดีขึ้นโดยการปรับตัวสำหรับการติดตามในเวลาจริงโดยการตรวจจับเงา" โดยผู้พัฒนาคือ P.LadewTraKuPong และ R.Bowden ในปี 2001 นั้นคือการใช้ method ที่ทำโดยวิธีการจำลองแต่ละพิกเซลของพื้นหลังโดยมีส่วนผสมของการกระจ่ายค่า (K = 3 to 5) โดยน้ำหนักของส่วนผสมแทนเวลาสัดส่วนที่สีเหล่านั้นอยู่ในที่เกิดเหตุ
  • ในขณะที่กำลังเขียน CODE นั้น มีความจำเป็นอย่างมากที่จะต้องสร้างวัตถุพื้นหลังโดยใช้ฟังก์ชั่น cv2.createBackgroundSubtractorMOG(). โดยจะมี พารามิเตอร์ที่ไม่จำเป็นบางอย่างเช่น ความยาวของ history , number of gaussian mixtures threshold และทั้งหมดนี้สามารถตั้งเป็น default value จากนั้นใช้ฟังก์ชั่น Video loop โดย backgroundsubtractor.apply() เพื่อหา foreground mask

ยกตัวอย่าง

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.BackgroundSubstractor()

while(1):
    ret, frame = cap.read()

    fgmask = fgbg.apply(frame)

    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

BackgroundSubtractorMOG2

  • นอกจากนี้ ในการผสมตามแบบเกาส์ (Gasuusian Mixture-based Background / ForeFround ) นั้น จะมีอีกวิจัยหนึ่งที่เขียนไว้โดย Z.Zivkovic "การปรับตัวที่ดีขึ้นของรูปแบบ Gausian" โดยมีส่วนผสมสำหรับการลบฉากหลังในปี 2004 และ "มีประสิทธิภาพประมาณความหนาแน่น โดยการปรับตัวต่อพิกเซลของภาพด้วยการลบพื้นหลัง" ในปี 2006 โดยหนึ่งในคุณลักษณะที่สำคัญของขั้นตอนวิธีการนี้ ก็คือว่า จะเลือกจำนวนที่เหมาะสมของการกระจายแบบ Gaussian สำหรับแต่ละพิกเซล (อย่าลืมว่ากรณีที่ผ่านมาเราเอา K ไปใช้ Gaussian ตลอดขั้นตอน) จะดีกว่าที่จะ adaptibillity ของแต่ละฉากที่แตกต่างกัน เพราะความเปลี่ยนแปลงการส่องสว่าง
  • เช่นกรณีก่อนหน้านี้เรามีการสร้างวัตถุพื้นหลังโดยลบพื้นหลังนั้น Background Subtractor ต่อไปนี้จะเป็นการเลือกว่าจะตรวจหาเงาด้วยหรือไม่โดยใช้ detectShadows = True โดยตรวจสอบและหาเงา โดยลดความเร็วลง และเงาจะถูกแทนทีด้วยโหมดสีเทา

ยกตัวอย่าง

import numpy as np
import cv2
 
cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.createBackgroundSubtractorMOG2()
 
while(1):
    ret, frame = cap.read()
 
    fgmask = fgbg.apply(frame)
 
    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
 
cap.release()
cv2.destroyAllWindows()

BackgroundSubtractorGMG

  • อัลกอริทึมนี้รวมค่าทาง statistical background image โดยจะประเมินค่า พิกเซลต่อพิกเซและแบ่งส่วนเบส์ วิธีนี้คิดค้นโดย Andrew B. Godbehere และ Akihiro Matsukawa , Ken Goldberg และอยู่ใน วิจัยนั้นชื่อว่า "Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive Audio Art Installation" ในปี 2012 โดยในวิจัยนั้นจะเป็นระบเสียงตอบโต้ที่ประสบความสำเร็จ โดยค่ายศิลปะเรียกว่า "Are We There Yet?" จาก 31 มีนา ถึง 31 กรกฏาคม 2011 ที่พิพิธภัณฑ์ยิวร่วมสมัยในซานฟรานซิส , แคลิฟอร์เนีย
  • โดยการใช้งานนั้น จะมีไม่กี่ตอนโดยจะใช้ไม่กี่ครั้งแรก (120 โดยค่าเริ่มต้น) โดย frame สำหรับ background นั้นจะจำลองพื้นหลัง โดนมีส่วนของขั้นตอนวิธีการแบ่งส่วนความน่าจะเป็นเของ foreground โดยที่ระบุวัตถุเบื้องต้นหน้าไปได้โดยใช้การอนุมานแบบเบน? โดยประมาณการมีการปรับตัว ข้อสังเกตที่ใหม่กว่านี้จะมีน้ำหนักมากกว่าที่สังเกตที่ใหม่ การดำเนินทางสัณฐานวิทยากรองหลายประการเช่น การปิดและเปิดจะดำเนินการเพื่อลบเสียงที่ไม่พึงประสงค์ คโดยจะได้รับหน้าต่างสีดำในช่วงไม่กี่เฟรม

ยกตัวอย่าง

import numpy as np
import cv2
 
cap = cv2.VideoCapture('vtest.avi')
 
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
fgbg = cv2.createBackgroundSubtractorGMG()
 
while(1):
    ret, frame = cap.read()
 
    fgmask = fgbg.apply(frame)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
 
    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
 
cap.release()
cv2.destroyAllWindows()

Result

Original Frame

Frame 092.png

Result of BackgroundSubtractorMOG

Frame 093.png