我正在开发一个可以与天花板上的内置摄像头一起使用的应用程序。目的是让它跟踪表面上的对象。
我需要删除背景,这样我才能得到那里“差异”的轮廓,但是使用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, ×tamp, 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, ×tamp, 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
?
谢谢!