본문 바로가기
OpenCV/OpenCV-Chapter

CH10 OpenCV-Python 배경차분(MOG)

by kiimy 2021. 12. 25.
728x90
728x90

MOG(Mixture of Gauusian)란?

- 각 픽셀에 대해 MOG 확률 모델을 설정하여 배경과 전경을 구분

- 하나의 데이터 분석 기법

영상의 각 Pixel 값을 배경영상을 등록시켜놓고 배경영상과 같냐 다르냐를 판단
= 현재 프레임에 그 객체가 새로 나타난거냐 아니냐를 판단

- 미리 정해둔 배경 영상의 Pixel 값은 이 위치에서 Pixel 값은 100이였다 정의하는 것이

  아니라 100 금방에 어떤 Gaussian을 따르고 있다고 정의

==> Gaussian 분포를 하나만 쓰는 것이 아니라 여러개 사용해서 어떤 위치의 특정 Pixel,

       배경 Pixel값이 어느 Gaussian분포를 따르고 있다라는 모델 형태를 준다.

ex) 흔들리는 나무가 있다할 때 나뭇잎은 배경일수도(하늘색) 나뭇잎일 수도(초록색)
     해당 위치에서 두 개의 Gaussian 배경모델을 등록하는 형태로 만들 수 있다.

Adaptive - Gaussian을 몇 개를 쓸거냐, 프로그램이 재생되는 속성을 보고 자동으로 판단
이동평균과 비슷하지만 성능이 더 좋고, 간단한 사용

cap = cv2.VideoCapture('ch10\\videos\\PETS2000.avi')

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

# 배경 차분 알고리즘 객체 생성(MOG class 객체화)
# bs = cv2.createBackgroundSubtractorMOG2()
bs = cv2.createBackgroundSubtractorKNN()
'''
cv2.createBackgroundSubtractorMOG2(, history=None, varThreshold=None, 
                                    detectShadows=None) -> dst
* 멤버함수
+ apply()
+ getBackgroundImage()
varThreshold : 새로 들어온 영상의 pixel 값이 배경영상의 pixel 값에 부합하는지판단
detecShadows: 그림자 검출 여부, 기본값은 True
'''

# Shadow 지정 ==> mask 0, 128(회색), 255
# class default == True
# bs.setDetectShadows(False)

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

    if not ret:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # fgmask = 0, 128, 255 값을 가짐
    # 그림자를 표현한다면 128값을 가지는 것이다
    fgmask = bs.apply(gray)
    '''
    cv2.BackgroundSubtractor.apply(image, fgmask=None, learningRate=None) 
                            -> fgmask

    fgmask: (출력)전경 마스크영상.8bit 이진 영상
    '''

    # 학습된 배경 출력
    back = bs.getBackgroundImage()

    cnt, _, stats, _ = cv2.connectedComponentsWithStats(fgmask)

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

        if area < 100:
            continue

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

    cv2.imshow('frame', frame)
    cv2.imshow('back', back)
    cv2.imshow('fgmask', fgmask)

    if cv2.waitKey(10) == ord('q'):
        break

cap.release()

fgmask(회색: 그림자) / back

728x90

댓글