Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从静止图像进行OpenCV背景减法_Opencv - Fatal编程技术网

从静止图像进行OpenCV背景减法

从静止图像进行OpenCV背景减法,opencv,Opencv,我正在开发一个应用程序,它将与天花板上的内置摄像头一起工作。其目的是跟踪曲面上的对象 我需要去除背景,这样我就可以得到“diff”的轮廓,但是使用BackgroundSubtractorMOG会让人沮丧,因为我发现它唯一的应用是视频 我需要的是提供一个单一的图像作为背景,然后从一个流的每一帧上计算发生了什么变化 以下是我所拥有的: #include <libfreenect/libfreenect_sync.h> #include <opencv2/opencv.hpp>

我正在开发一个应用程序,它将与天花板上的内置摄像头一起工作。其目的是跟踪曲面上的对象

我需要去除背景,这样我就可以得到“diff”的轮廓,但是使用
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);
  }
}
#包括
#包括
#包括
#包括
const char*kbackgroundindow=“背景”;
const char*kforegroundindow=“前景”;
常量字符*kDiffWindow=“Diff”;
常量cv::Size kCameraSize(cv::Size(640480));
int main(int argc,字符**argv){
uint8_t*原始帧=(uint8_t*)malloc(640*480*3);
uint32_t时间戳;
//首先,我们显示背景窗口。按键将设置背景
//接着是目标检测。
cvNamedWindow(kbackgroundindow);
cv::Mat背景(kCameraSize,cv_8UC3,cv::Scalar(0));
对于(;;){
freenect_sync_get_video((void**)和原始帧,以及时间戳,0,freenect_video_RGB);
background.data=原始帧;
cv::CVT颜色(背景、背景、cv_BGR2RGB);
cv::imshow(KBackgroundindow,背景);
如果(cv::waitKey(10)>0)
打破
}
//创建两个窗口,一个显示当前提要,另一个显示当前提要之间的差异
//背景和提要。
cvNamedWindow(kforegroundindow);
//轨迹栏的Canny阈值
int cannyThresh1=20;
int canny thresh2=50;
cvNamedWindow(kdiff窗口);
cv::createTrackbar(“Canny Thresh 1”,kDiffWindow和Canny Thresh1,5000,NULL);
cv::createTrackbar(“Canny THresh 2”,kDiffWindow和Canny Thresh2,5000,NULL);
//开始捕捉帧。
cv::Mat前景(kCameraSize,cv_8UC3,cv::Scalar(0));
cv::Mat diff(kCameraSize,cv_8UC3,cv::Scalar(0));
cv::背景减法器MOG2 bg_减法器(101100.0,假);
bg_减法器(背景,差异,1);
对于(;;){
freenect_sync_get_video((void**)和原始帧,以及时间戳,0,freenect_video_RGB);
前台数据=原始帧;
cv::CVT颜色(前景、前景、cv_BGR2RGB);
//计算背景之间的差异
//前景是不同的。
bg_减法器(前景,差异,0.01);
//在产生的差异中运行Canny边缘检测器
cv::Canny(diff,diff,cannyThresh1,cannyThresh2);
cv::imshow(KforeGroundindow,前景);
cv::imshow(kDiffWindow,diff);
cv::waitKey(10);
}
}
我如何更改它,使其不“了解”新背景,而只使用存储在
background
中的静态图像


谢谢

如果您确实只想要一张静态图像作为背景,您可以从前景图像中减去背景图像:

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

另外,我认为您对
cv::cvtColor()
的调用是不必要的。OpenCV的本机图像格式是BGR,因此
imshow()
将显示事先转换为RGB时交换的红色和蓝色通道。

背景静止,但提要中的某些颗粒与100%不匹配。感谢您提供的
cv::cvtColor
提示@这可能是因为噪音。你可以通过中值滤波器同时运行
背景
前景
,以减少噪音。对不起,我说得不够清楚。我指的是视频源。它来自一个蹩脚的照相机(Kinect)