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