2013-07-26 154 views
2

我正在研究一個應用程序,該應用程序將與天花板上的內置攝像頭一起使用。目的是爲了跟蹤表面上的物體。從靜止圖像中減去OpenCV背景

我需要刪除背景,以便我可以得到那裏的「差異」的輪廓,但使用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靜態圖像?

謝謝!

回答

1

如果你真的只想要一個靜態圖像作爲背景,你可以簡單地從前景圖像減去背景圖像:

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

作爲一個方面說明,我覺得你要cv::cvtColor()電話是不必要的。 OpenCV的原生圖像格式是BGR,因此如果您事先轉換爲RGB,則imshow()將顯示交換的紅色和藍色通道。

+0

背景仍然是,但飼料有一些糧食不完全匹配100%。感謝'cv :: cvtColor'提示! – changelog

+0

@changelog這可能是因爲噪音。你可以通過一箇中值濾波器來運行'background'和'foreground'來減少噪音。 – Aurelius

+0

對不起,我沒有說清楚。我的意思是視頻Feed。它來自一個糟糕的相機(Kinect) – changelog