Ask Your Question

Background subtraction from a still image

asked 2013-07-26 05:14:27 -0500

changelog gravatar image

I'm working on an application that will work with an inside mounted camera on the ceiling. The purpose is for it to keep track of objects on a surface.

I need to remove the background, so that I can get the contours of the "diff" that's there, but using BackgroundSubtractorMOG gets frustrating, as I find that its only application is for video.

What I need is to provide a single image that will be the background, and then calculate on each frame from a stream what has changed.

Here's what I have:

#include <libfreenect/libfreenect_sync.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

const char *kBackgroundWindow = "Background";
const char *kForegroundWindow = "Foreground";
const char *kDiffWindow = "Diff";

const cv::Size kCameraSize(cv::Size(640, 480));

int main(int argc, char **argv) {
  uint8_t *raw_frame = (uint8_t *)malloc(640 * 480 * 3);
  uint32_t timestamp;

  // First, we show the background window. A key press will set the background
  // and move on to object detection.
  cv::Mat background(kCameraSize, CV_8UC3, cv::Scalar(0));
  for(;;) {
    freenect_sync_get_video((void **)&raw_frame, &timestamp, 0, FREENECT_VIDEO_RGB); = raw_frame;
    cv::cvtColor(background, background, CV_BGR2RGB);

    cv::imshow(kBackgroundWindow, background);
    if(cv::waitKey(10) > 0)

  // Create two windows, one to show the current feed and one to show the difference between
  // background and feed.

  // Canny threshold values for the track bars
  int cannyThresh1 = 20;
  int cannyThresh2 = 50;
  cv::createTrackbar("Canny Thresh 1", kDiffWindow, &cannyThresh1, 5000, NULL);
  cv::createTrackbar("Canny THresh 2", kDiffWindow, &cannyThresh2, 5000, NULL);

  // Start capturing frames.
  cv::Mat foreground(kCameraSize, CV_8UC3, cv::Scalar(0));
  cv::Mat diff(kCameraSize, CV_8UC3, cv::Scalar(0));

  cv::BackgroundSubtractorMOG2 bg_subtractor(101, 100.0, false);
  bg_subtractor(background, diff, 1);

  for(;;) {
    freenect_sync_get_video((void **)&raw_frame, &timestamp, 0, FREENECT_VIDEO_RGB); = raw_frame;
    cv::cvtColor(foreground, foreground, CV_BGR2RGB);
    // Calculate the difference between the background
    // and the foreground into diff.
    bg_subtractor(foreground, diff, 0.01);

    // Run the Canny edge detector in the resulting diff
    cv::Canny(diff, diff, cannyThresh1, cannyThresh2);

    cv::imshow(kForegroundWindow, foreground);
    cv::imshow(kDiffWindow, diff);


How can I change this so that it doesn't "learn" about the new background, but just uses the static image stored in background?


edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2013-07-29 17:17:35 -0500

When you use the appy function (or operator() in your case) the last parameter is used for the update of the background. It is not really documented, I'm afraid, but, in the sample cpp/bgfg_segm.cpp, you could see that -1 if for updating the background, and 0 for no update. This probably means that 0.01 as you used is for updating background. Keep in mind that the history is also playing a role in your background update. See the reference papers for more information.

edit flag offensive delete link more

answered 2013-07-29 10:00:42 -0500

tenta4 gravatar image

What's stopping you subtract the background independently

cv::Mat temp;

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2013-07-26 05:14:27 -0500

Seen: 2,773 times

Last updated: Jul 29 '13