Computer Vision/opencv(python)

[64] 2) 배경 차분: 이동 평균 배경

jwjwvison 2021. 3. 27. 00:51
  • 정적 배경 모델 사용 시 문제점
    • 미리 등록된 기준 영상이 실제 배경과 크게 달라질 경우 오동작
    • ex) 그림자 등의 영향으로 인한 조도 변경, 새로운 객체가 화면에 고정될 경우
  • 평균 연산에 의한 배경 영상 생성
    • 움직이는 객체가 존재하는 수백 장의 입력 영상으로부터 평균 영상을 구하면?
    • --> 수백 장의 이전 프레임을 버퍼에 저장하려면 대용량 메모리가 필요하다

 

  • 이동 평균(Moving average)이란?
    • 수백 장의 영상을 저장하는 대신 매 프렝미이 들어올 때마다 평균 영상을 갱신

   대용량 버퍼 메모리가 필요하지 않다

 

  • 이동 평균 계산을 위한 가중치 누적 함수
cv2.accumulateWeighted(src,dst,alpha,mask=None) -> dst

 • src: 입력 영상. 1 또는 3채널. 8비트 또는 32비트 실수형
 • dst: 축적 영상. 입력 영상과 동일 채널 개수. 32비트 또는 64비트 실수형
 • alpha: (입력 영상에 대한) 가중치
 • mask: 마스크 영상

 

  • 이동 평균에 의한 배경 차분 예제
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:uint8 배경, fback=float32배경
back=cv2.cvtColor(back,cv2.COLOR_BGR2GRAY)
back=cv2.GaussianBlur(back,(0,0),1.0)
fback=back.astype(np.float32)

# 비디오 매 프레임 처리
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)

    #fback: float32, back= uint8 배경
    cv2.accumulateWeighted(gray,fback,0.01)   # fback==>입력과 동시에 출력을 함
    back=fback.astype(np.uint8)

    diff=cv2.absdiff(gray,back)               # 인자로 들어오는 두 영상의 type이 같아야한다 ex)gray 이면 gray int형이면 int
    _,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)
    cv2.imshow('back',back)

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

cv2.destroyAllWindows()