Background subtraction
Peponi │ 7/28/2025 │ 5m
C#
NugetPackageOpenCvSharp4BackgroundSubtractorMOG2BackgroundSubtractorKNNBackgroundSubtractorGMG
Background subtraction
7/28/2025
5m
Peponi
C#
NugetPackageOpenCvSharp4BackgroundSubtractorMOG2BackgroundSubtractorKNNBackgroundSubtractorGMG
1. Introduction
Background subtraction
은 이미지 또는 비디오의 배경을 분리하는 데 사용되는 기술이다. 주로 CCTV와 같은 고정된 영상에서 움직이는 사람, 차량 등을 감지할 때 중요한 전처리 단계로 활용된다. Background subtraction은 기본적으로 현재 프레임과 배경 모델을 비교하여 전경 요소만을 따로 분리해내며 주로 다음과 같은 단계를 거친다.
- 배경 모델링
정적인 배경 이미지를 사용하거나 여러 이미지 프레임을 활용해 통계적 특성을 학습한다. - 현재 프레임 비교
배경 모델과 현재 프레임을 비교하여 배경과 다른 픽셀을 식별하여 전경으로 분류한다. 이를 이용하여 전경 마스크를 생성하며, 보통 binary 이미지로 구성된다. - 배경 모델 업데이트
알고리즘에 따라 다르지만, 많은 알고리즘은 배경 모델을 지속적으로 업데이트 하는 기능을 자체적으로 내장하고 있다.
OpenCV는 BackgroundSubtractor
클래스를 제공하여 MOG2
, KNN
, GMG
알고리즘을 이용한 background subtraction을 쉽게 수행할 수 있다. 이 문서에서는 KNN
알고리즘을 이용하여 고속도로의 차량을 식별하는 예시를 보여준다.
실습에 사용할 동영상은 다음과 같다.

2. Example



이 예제에서는 다음 과정을 거쳐 차량을 인식한다.
- Background remove
BackgroundSubtractorKNN
을 이용하여 그림자가 포함된 전경 마스크를 생성한다. - Pre-process
Threshold와 morphological transformation을 이용하여 그림자, 노이즈를 제거한다. - 객체 검출
Contour detection을 이용하여 차량의 윤곽선을 찾으며, 면적을 기준으로 객체 필터링을 수행한다.
private void Perform(VideoCapture video)
{
// OpenCV 제공 window
Window processed = new("Processed");
Window result = new("Result");
// BackgroundSubtractor 생성
// history : 배경 모델링에 사용할 프레임 수 설정
// dist2Threshold : 이웃 거리에 대한 임계값
// detectShadows : 그림자 검출 여부 설정 (그림자는 전경과 구분 가능하게 출력됨)
using var backgroundSubtractor = BackgroundSubtractorKNN.Create(100, 500);
while (true)
{
using var frame = new Mat();
video.Read(frame);
// 동영상이 끝나면 frame.Empty 가 true로 바뀜
if (frame.Empty())
break;
// 배경 분리
using var backgroundRemoved = new Mat();
backgroundSubtractor.Apply(frame, backgroundRemoved);
// 그림자 제거
using var shadowRemoved = backgroundRemoved.Threshold(200, 255, ThresholdTypes.Binary);
// 객체 보존하면서 노이즈 제거
using var kernel = Mat.Ones(3, 3, MatType.CV_8UC1);
using var morphed = shadowRemoved.MorphologyEx(MorphTypes.Open, kernel);
// 객체 찾기
morphed.FindContours(out var contours, out var hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxTC89L1);
// 면적을 기준으로 객체 필터링
var filtered = contours.Where(contour => Cv2.ContourArea(contour) > 100);
// 최종 객체 표시
foreach (var contour in filtered)
{
var rect = Cv2.BoundingRect(contour);
frame.Rectangle(rect, Scalar.Crimson, 3);
}
processed.ShowImage(morphed);
result.ShowImage(frame);
Cv2.WaitKey(10);
}
}
3. 참조 자료
- OpenCV Tutorials - How to Use Background Subtraction Methods
- OpenCV docs - cv::BackgroundSubtractorMOG2 Class Reference
- OpenCV docs - cv::BackgroundSubtractorKNN Class Reference
- OpenCV docs - cv::bgsegm::BackgroundSubtractorGMG Class Reference
- Thresholding (Binarization)
- Morphological transformations
- Contour detection