[OpenCV] Background Subtraction 배경 제거
Computer Vision 2026. 5. 13. 11:42 |반응형
배경을 제거하고 전경(마스크)만 남겨 보자.
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture cap("Cars_On_Highway.mp4");
if (!cap.isOpened())
{
std::cerr << "Error opening video stream or file" << std::endl;
return -1;
}
int fps = static_cast<int>(cap.get(cv::CAP_PROP_FPS));
cv::Ptr<cv::BackgroundSubtractor> pBgSub = cv::createBackgroundSubtractorMOG2(500, 16.0, false);
// history: 모델이 배경으로 간주하기 위해 고려하는 프레임 수. 기본값은 500.
// 최초 500 프레임이 배경 모델을 구축하는 데 사용되고, 이후 프레임은 모델 업데이트에 영향을 미친다.
// 그러므로 최초에는 배경 모델이 구축될 수 있도록 충분한 프레임이 필요하다. history가 너무 작으면 모델이
// 빠르게 업데이트되어 일시적인 변화에 민감해질 수 있고, 너무 크면 모델이 느리게 업데이트되어 변화에
// 적응하는 데 시간이 걸릴 수 있다.
// varThreshold: 픽셀이 배경 모델과 일치하는지 여부를 결정하는 분산 임계값. 기본값은 16.0.
// 분산 임계값이 낮을수록 모델과 일치하는 픽셀이 더 많아지고, 높을수록 모델과 일치하는 픽셀이 더 적어진다.
// detectShadows: 그림자 감지를 활성화할지 여부를 결정하는 부울 값. 기본값은 true.
// 이 예에서는 detectShadows만 false로 설정하여 그림자 감지를 비활성화했다.
// 배경은 0으로 표시되고 전경은 255, 그림자는 128로 표시된다.
// 그림자는 배경 모델이 그림자를 배경으로 간주하지 않도록 도와주지만, 그림자 감지를 활성화하면 속도가 느려질 수 있다.
cv::Mat frame;
cv::Mat fgMask;
while (true)
{
cap >> frame;
if (frame.empty())
break;
cv::resize(frame, frame, cv::Size(), 0.5, 0.5);
pBgSub->apply(frame, fgMask);
// apply 메서드는 프레임을 입력으로 받아 fgMask에 전경 마스크를 출력한다.
// fgMask는 8비트 단일 채널 이미지로, 배경 픽셀은 0, 전경 픽셀은 255로 표시된다.
// apply 메서드는 또한 배경 모델을 업데이트한다. learningRate 매개변수를 사용하여 업데이트 속도를 제어할 수 있다.
// learningRate가 음수이면 알고리즘이 자동으로 학습 속도를 선택한다. 0이면 모델이 업데이트되지 않고, 1이면 모델이
// 마지막 프레임에서 재초기화된다.
// 노이즈가 많을 경우, 노이즈 제거를 위해 모폴로지 연산을 적용한다. (열림 연산)
//cv::Mat mask = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
//cv::morphologyEx(fgMask, fgMask, cv::MORPH_OPEN, mask);
cv::imshow("Frame", frame);
cv::imshow("FG Mask", fgMask);
if (cv::waitKey(1000 / fps) >= 0)
break;
}
cv::Mat bgImage;
pBgSub->getBackgroundImage(bgImage);
// getBackgroundImage 메서드는 현재 배경 모델을 기반으로 배경 이미지를 반환한다.
// 이 이미지는 배경 모델이 구축된 후에 호출해야 한다. 배경 제거 알고리즘이 배경으로 간주하는 픽셀의 평균값을 포함하는
// 이미지를 확인할 수 있다. 이 이미지는 때때로 매우 흐릿할 수 있으며, 배경 통계가 포함되어 있기 때문이다.
cv::imshow("BG Image", bgImage);
cv::waitKey(0);
cap.release();
cv::destroyAllWindows();
return 0;
}


영상의 초반(이 예의 경우 500프레임)에 배경만 나오는 영상을 사용한다면 훨씬 나은 결과를 보일 것으로 생각된다.

※ 참고
Background Subtraction with OpenCV and BGS Libraries
Improved Background-Foreground Segmentation Methods
반응형
'Computer Vision' 카테고리의 다른 글
| [CUDA] Device Properties 디바이스 정보 확인 (0) | 2026.04.29 |
|---|---|
| [CUDA] C++ with CUDA (0) | 2026.04.28 |
| [OpenCV] OpenCV and memcpy (feat.CUDA) (0) | 2026.04.27 |
| [OpenCV] CPU, GPU Image Processing Comparison 이미지 처리 속도 비교 (0) | 2026.04.26 |
| [OpenCV] OpenCV with CUDA Build (0) | 2026.04.26 |
