2

我正在开发一个可以与天花板上的内置摄像头一起使用的应用程序。目的是让它跟踪表面上的对象。

我需要删除背景,这样我才能得到那里“差异”的轮廓,但是使用BackgroundSubtractorMOG会令人沮丧,因为我发现它的唯一应用是视频。

我需要的是提供一个将作为背景的图像,然后从流中计算每一帧的变化。

这是我所拥有的:

#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.
  cvNamedWindow(kBackgroundWindow);
  cv::Mat background(kCameraSize, CV_8UC3, cv::Scalar(0));
  for(;;) {
    freenect_sync_get_video((void **)&raw_frame, &timestamp, 0, FREENECT_VIDEO_RGB);
    background.data = raw_frame;
    cv::cvtColor(background, background, CV_BGR2RGB);

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

  // Create two windows, one to show the current feed and one to show the difference between
  // background and feed.
  cvNamedWindow(kForegroundWindow);


  // Canny threshold values for the track bars
  int cannyThresh1 = 20;
  int cannyThresh2 = 50;
  cvNamedWindow(kDiffWindow);
  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);
    foreground.data = 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);

    cv::waitKey(10);
  }
}

我怎样才能改变它,使它不会“了解”新背景,而只是使用存储在 中的静态图像background

谢谢!

4

1 回答 1

1

如果你真的只想要一个静态图像作为背景,你可以简单地从前景图像中减去背景图像:

cv::Mat diff;
cv::absdiff(foreground, background, diff);

作为旁注,我认为您的电话cv::cvtColor()是不必要的。OpenCV 的原生图像格式是 BGR,因此imshow()如果您事先转换为 RGB,则会显示交换的红色和蓝色通道。

于 2013-07-26T15:01:32.127 回答