Computer Vision/opencv(python)

[63] 10.객체 추적과 모션 벡터 1) 배경 차분: 정적 배경 차분

jwjwvison 2021. 3. 27. 00:35
  • 배경 차분(Background Subtraction:BS)
    • 등록된 배경 모델과 현재 입력 프레임과의 차영상을 이용하여 전경 객체를 검출
    • 움직이는 전경 객체 검출을 위한 기본적인 방법

 

  • 정적 배경을 이용한 전경 객체 검출

 처음 프레임을 배경으로 설정하고 이후 들어오는 영상과의 차이를 비교하는 방법은 그렇게 까지 좋은방식은 아니다.
이 방식은 조명의 변화, 예를 들어서 그림자가 지거나 해의 밝이에 따라 민감하게 반응하고 자동차가 새롭게 들어와서 주차를 했는데도 계속 검출이 되기 때문에 배경모델을 점진적으로 업데이트를 해서 조금 더 적응하는 형태로 동작시키는 방법이 더 좋다

import sys
import numpy as np
import cv2


# 비디오 파일 열기
cap = cv2.VideoCapture('PETS2000.avi')

if not cap.isOpened():
    print('Video open failed!')
    sys.exit()

ret,back=cap.read()  #컬러영상인데 컬러값이 꼭 필요한 상황이 아니고 연산속도를 빠르게 증가시키기 위해 grayscale 이용
back=cv2.cvtColor(back,cv2.COLOR_BGR2GRAY)
back=cv2.GaussianBlur(back,(0,0),1)                # 가우시안 블러링으로 흰색 튀는값을 잡아줌

while True:
    _,frame=cap.read()

    frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    frame=cv2.GaussianBlur(frame,(0,0),1)           # 가우시안 블러링으로 흰색 튀는값을 잡아줌
    
    diff=cv2.absdiff(back,frame)  # 배경 영상과 현재 영상의 차이점
    _, diff=cv2.threshold(diff,30,255,cv2.THRESH_BINARY)        # 차이값이 30 이상이면 255로 만들고 30보다 작으면 0으로 만든다

    cv2.imshow('diff',diff)
    cv2.imshow('frame',frame)

    if cv2.waitKey(30)==27:
        break

cv2.destroyAllWindows()    

  • 정적 배경을 이용한 전경 객체 검출 후 주요 객체 바운딩 박스 표시
    • 레이블링 수행 후 픽셀 개수가 100이상인 객체에 바운딩 박스 표시
import sys
import numpy as np
import cv2


# 비디오 파일 열기
cap = cv2.VideoCapture('PETS2000.avi')

if not cap.isOpened():
    print('Video open failed!')
    sys.exit()

# 배경 영상 등록
ret, back = cap.read()

if not ret:
    print('Background image registration failed!')
    sys.exit()

back = cv2.cvtColor(back, cv2.COLOR_BGR2GRAY)
back = cv2.GaussianBlur(back, (0, 0), 1.0)

# 비디오 매 프레임 처리
while True:
    ret, frame = cap.read()

    if not ret:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (0, 0), 1.0)

    # 차영상 구하기 & 이진화
    diff = cv2.absdiff(gray, back)
    _, diff = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)

    # 레이블링을 이용하여 바운딩 박스 표시
    cnt,_,stats,_=cv2.connectedComponentsWithStats(diff)

    for i in range(1,cnt):
        x,y,w,h,s=stats[i]

        if s<100:
            continue

        cv2.rectangle(frame,(x,y,w,h),(0,0,255),2)

    cv2.imshow('frame',frame)
    cv2.imshow('diff',diff)
    if cv2.waitKey(40)==27:
        break
cv2.destroyAllWindows()