Python OpenCV

배경 제거 (배경 차분, cv2.absdiff())

PyExplorer 2025. 3. 10. 10:17
728x90

배경 제거 (배경 차분, cv2.absdiff())

배경 제거는 영상 처리에서 중요한 기술 중 하나로, 움직이는 객체를 추출하거나 특정 배경을 제거하는 데 사용됩니다. OpenCV에서는 여러 가지 방법으로 배경을 제거할 수 있으며, 그중 하나가 배경 차분 기법입니다. 본 포스팅에서는 cv2.absdiff() 함수를 활용한 배경 제거 방법을 설명하고, 예제 코드를 통해 실습해보겠습니다.

1. 배경 제거란?

배경 제거(Background Subtraction)는 영상에서 고정된 배경을 제거하고 변화하는 객체(예: 사람, 자동차)를 추출하는 과정입니다. 이 기법은 다양한 영상 처리 및 컴퓨터 비전 응용 분야에서 활용되며, 예를 들면 다음과 같은 곳에서 사용됩니다.

  • 보안 감시 시스템: 움직이는 객체(사람, 차량) 검출
  • 스포츠 분석: 선수의 움직임 추적
  • 증강 현실 (AR): 사용자의 배경을 제거하여 합성 영상 적용
  • 교통 모니터링: 도로에서 차량 탐지

배경 제거를 수행하는 여러 가지 방법이 있지만, 가장 기본적인 기법 중 하나가 배경 차분(Background Differencing)입니다.

2. 배경 차분(Background Differencing) 기법

배경 차분 기법은 현재 프레임에서 기준이 되는 배경 프레임을 빼는 방식으로 동작합니다. 즉, 두 이미지 간의 차이를 계산하여 움직이는 객체를 감지하는 방식입니다.

이를 구현하기 위해 OpenCV의 cv2.absdiff() 함수를 사용할 수 있습니다. cv2.absdiff() 함수는 두 개의 영상을 입력으로 받아 픽셀 간 차이의 절댓값을 계산합니다. 이를 통해 배경과의 차이가 큰 부분(즉, 움직이는 객체)을 강조할 수 있습니다.

cv2.absdiff() 함수

cv2.absdiff(src1, src2)
  • src1: 첫 번째 입력 영상 (배경 이미지)
  • src2: 두 번째 입력 영상 (현재 프레임)
  • 반환값: 두 영상 간 차이의 절댓값을 계산한 결과 영상

이제, 이를 활용한 실습을 진행해보겠습니다.

3. OpenCV를 활용한 배경 제거 실습

다음은 cv2.absdiff()를 이용하여 배경 제거를 수행하는 코드입니다.

(1) 기본 배경 제거 코드

import cv2
import numpy as np

# 비디오 캡처 객체 생성
cap = cv2.VideoCapture("video.mp4")  # 웹캠을 사용할 경우 0으로 설정

# 첫 번째 프레임을 배경으로 설정
ret, background = cap.read()
if not ret:
    print("영상을 불러올 수 없습니다.")
    cap.release()
    exit()

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 배경 차분 수행
    diff = cv2.absdiff(background, frame)

    # 그레이스케일 변환
    gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

    # 이진화 (Thresholding)
    _, thresh = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)

    # 결과 출력
    cv2.imshow("Original", frame)
    cv2.imshow("Difference", diff)
    cv2.imshow("Threshold", thresh)

    if cv2.waitKey(30) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

(2) 코드 설명

  1. 비디오를 로드하거나 웹캠에서 영상을 받아옵니다.
  2. 첫 번째 프레임을 배경으로 설정합니다.
  3. 각 프레임마다 배경과의 차이를 계산(cv2.absdiff())합니다.
  4. 차분된 결과를 그레이스케일로 변환하여 객체 영역을 강조합니다.
  5. 이진화(cv2.threshold())를 수행하여 움직이는 객체를 명확하게 구분합니다.
  6. 결과 영상을 출력합니다.

4. 배경 차분 기법의 한계와 개선 방법

(1) 한계점

  • 배경이 변하면 정확도가 낮아짐: 배경이 고정되어 있어야 정확하게 동작하지만, 조명 변화나 배경의 일부 변화에도 영향을 받을 수 있습니다.
  • 노이즈가 포함될 수 있음: 작은 픽셀 변화도 차이로 인식될 수 있어 불필요한 노이즈가 발생할 수 있습니다.

(2) 개선 방법

  • 배경 모델을 업데이트: 배경을 하나의 고정된 프레임이 아닌, 여러 프레임의 평균을 이용하여 동적으로 변경할 수 있습니다.
  • 모폴로지 연산 적용: cv2.morphologyEx() 함수를 활용하여 노이즈를 제거하고 결과를 부드럽게 할 수 있습니다.
  • 가우시안 블러 적용: cv2.GaussianBlur()를 사용하여 차분 결과에서 작은 변화를 줄이고 더 부드러운 결과를 얻을 수 있습니다.

다음은 모폴로지 연산을 적용하여 노이즈를 제거하는 코드입니다.

kernel = np.ones((5,5), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

이 코드를 추가하면 작은 노이즈를 효과적으로 제거할 수 있습니다.

5. 결론

이 포스팅에서는 cv2.absdiff()를 활용한 배경 제거 기법을 살펴보았습니다. 배경 차분 기법은 간단하면서도 유용한 방법이지만, 정확도를 높이기 위해 여러 가지 추가적인 기법을 적용해야 합니다.

핵심 정리

  • 배경 제거는 움직이는 객체를 추출하는 중요한 기술이다.
  • cv2.absdiff()를 사용하면 배경과 현재 프레임 간의 차이를 쉽게 계산할 수 있다.
  • 이진화 및 모폴로지 연산을 활용하면 결과를 더욱 개선할 수 있다.

배경 제거는 객체 추적, 감시 시스템, 증강 현실 등 다양한 분야에서 활용되므로, 본 포스팅의 내용을 참고하여 실습해보시길 바랍니다.