背景剪除和OpenCV中的實現


轉載請注明出處!

http://blog.csdn.net/zhonghuan1992




背景剪除和OpenCV中的實現







         背景與前景都是相對的概念。以快速公路為例:有時我們對快速公路上來來往往的汽車感興趣,這時汽車是前景。而路面以及周圍的環境是背景。有時我們只對闖入快速公路的行人感興趣,這時闖入者是前景,而包含汽車之類的其它東西又成了背景。背景剪除是使用很廣泛的攝像頭視頻中探測移動的物體。這樣的在不同的幀中檢測移動的物體叫做背景模型,事實上背景剪除也是前景檢測。

         一個強勁的背景剪除算法應當可以解決光強的變化,雜波的反復性運動,和長期場景的變動。以下的分析中會是用函數V(x,y,t)表示視頻流,t是時間。x和y代表像素點位置。

比如,V(1,2,3)是在t=3時刻。像素點(1,2)的光強。

以下介紹幾種背景剪除的方法。

 

1 利用幀的不同

         該方法假定是前景是會動的。而背景是不會動的。而兩個幀的不同能夠用以下的公式:

         從公式我們能夠體會出D(t+1)的含義來,用它來表示同個位置前后不同一時候刻的光強僅僅差。僅僅要把那些D是0的點取出來。就是我們的前景,同一時候也完畢了背景剪除。當然。這里的能夠稍作改進,不一定說背景是一定不會動的。能夠用一個閥值來限定。

看以下的公式:

         通過Th這個閥值來進行限定,把大於Th的點給去掉,留下的就是我們想要的前景。

2 均值濾波(Mean filter)

         首先。名字里有Mean了嘛,一般和Mean這個有關系了,那么這個關系是怎么聯系上的呢?看以下的公式:

         公式用無聲的語言來表達了B(x,y)的意思,同一個點在過去N個幀中的平均光強。好了,有了這個公式,我們就有了均值了。以下看怎么用這個B(x,y)。使用方法非常easy。就是把上面1中的V(x,y,t+1)改為B(x,y),所以公司例如以下:

         恩,我想大家可以感受到這個的作用了。不是通過當前幀和上一幀的區別,而是當前幀和過去一段時間的平均區別來進行比較,同一時候通過閥值Th來進行控制。當大於閥值的點去掉。留下的就是我們要的前景了。

3 使用高斯均值:

         數學不是太好。遇上高斯這個名字,就認為非常唬人,事實上為什么要這樣我不太清楚,求人給出好的簡單易懂的解釋,而我對這樣的情況的做法就是,就是一些規則。這樣做的優點我說不上來,以后了解很多其它了,我再回來補充。讓我們直接看看它是怎么做的。

         首先是均值, 是方差。

看以下的初始化:

         這個還是比較明確的。一開始均值就是I0,(開始的時候嘛),方差能夠使某個初始值。后面就是用來進行更新。公式例如以下:

         好了。公式的更新方式如上,我們能夠從效果上來體會上面的公式,以下是一個圖,

         上面的每一個格子。表示的就是一個圖的某部分。每一個像素點的情況。你看。每一個格子就想一個小山,我覺的使用高斯分布也是為了這個原因吧,時間離得近的點,影響比較大。時間比較前的點,影響比較小,你假設把上面的公式多展開幾層就會感受高了。以下就是推斷方式了:

         和上面有些像,只是,多了個除方差的環節。當中K是一個自由的閥值,K大了,就會有一些動的部分當成背景了; K小了。前景會有一些靜態的部分。

利用OpenCV實現上面的最簡單的1中的前景檢測。

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
 
#define threshold_diff 10 //設置簡單幀差法閾值
 
using namespace cv;
using namespace std;
 
int main(int argc, unsigned char* argv[])
{
    Mat img1, img2, gray1, gray2, bac;
    bool pause = false;
 
    VideoCapture capture("G:\\視頻分析入門練習\\視頻分析入門練習 - 附件\\sample.avi");//在這里改對應的文件名稱
    //讀取下一幀 
    if (!capture.read(img1))
    {
        cout << "結束" << endl;
        capture.release();
        return 0;
    }
 
    while (true)
    {
        cvtColor(img1, gray1, CV_BGR2GRAY);
 
        //讀取下一幀 
        if(!capture.read(img2))
        {
            cout << "結束" << endl;
            capture.release();
            return 0;
        }
        cvtColor(img2, gray2, CV_BGR2GRAY);
        imshow("原視頻", img2);
 
        subtract(gray1, gray2, bac);
        for (int i = 0;i<bac.rows; i++)
            for (int j = 0;j<bac.cols; j++)
                if (abs(bac.at<unsigned char>(i, j)) >= threshold_diff)//這里模板參數一定要用unsigned char,否則就一直報錯
                    bac.at<unsigned char>(i, j) = 255;
                else bac.at<unsigned char>(i, j) = 0;
        imshow("背景圖", bac);
        img1 = img2;
        waitKey(20);
    }
    return 0;
}





引用:

         http://en.wikipedia.org/wiki/Background_subtraction

         http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html

S


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM