前景檢測算法_2(幀差法1)


  幀差法是背景減圖法中的一種,只不過是幀差法不需要建模,因為它的背景模型就是上一幀的圖,所以速度非常快,另外幀差法對緩慢變換的光照不是很敏感,所以其用途還是有的,有不少學者對其做出了出色的改進。

  其基本原理可以用下面公式看出:

  |i(t)-i(t-1)|<T             背景

  |i(t)-i(t-1)|>=T           前景

  其中i(t),i(t-1)分別為t,t-1時刻對應像素點的像素值,T為閾值。

  當然其缺點也不少,容易出現”雙影”和”空洞”現象。

  用opencv2.3.1+vs2010做了個簡單的實驗,其實驗代碼如下:

 1 // frame_diff.cpp : 定義控制台應用程序的入口點。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <opencv2/highgui/highgui.hpp>
 6 #include <opencv2/imgproc/imgproc.hpp>
 7 #include <opencv2/core/core.hpp>
 8 
 9 #define threshold_diff 20 //設置簡單幀差法閾值
10 
11 using namespace cv;
12 using namespace std;
13 
14 int main(int argc,unsigned char* argv[])
15 {
16     Mat img_src1,img_src2,img_dst,gray1,gray2,gray_diff;
17     bool pause=false;
18 
19     VideoCapture vido_file("IndoorGTTest1.avi");//在這里改相應的文件名
20     namedWindow("foreground",0);
21     for (;;)
22     {
23         if(!pause)
24         {
25             vido_file >>img_src1;        //因為視頻文件幀數已經固定了,所以每次到這句語句都是讀取相鄰的幀數,沒到時間視頻並不向前走
26             cvtColor(img_src1,gray1,CV_BGR2GRAY);
27             imshow("video_src",img_src1);//可以事先不用新建一個窗口
28             waitKey(5);
29 
30             vido_file >>img_src2;
31             cvtColor(img_src2,gray2,CV_BGR2GRAY);
32             imshow("video_src",img_src2);//可以事先不用新建一個窗口
33 
34             waitKey(5);
35             subtract(gray1,gray2,gray_diff);
36             for(int i=0;i<gray_diff.rows;i++)
37                 for(int j=0;j<gray_diff.cols;j++)
38                     if(abs(gray_diff.at<unsigned char>(i,j))>=threshold_diff)//這里模板參數一定要用unsigned char,否則就一直報錯
39                         gray_diff.at<unsigned char>(i,j)=255;
40                     else gray_diff.at<unsigned char>(i,j)=0;
41 
42             imshow("foreground",gray_diff);
43         }
44         char c=(char)waitKey(10);
45         if (c==27)
46         {
47             break;    
48         }
49         if(c==' ')
50             pause=!pause;
51     }
52     return 0;
53 }

   實驗結果如下:

    

  可以看出其“雙影”和”空洞”比較明顯。雙影是由於幀差法有2個影子,在該試驗中就是輪廓變得很粗,”空洞”是由於物體內部顏色相近,檢測不出來。當然幀差法還有個致命的缺點那就是閾值T需要人工設定。

  對於幀差法的”雙影”現象,有人提出來了三幀差法。其原理如下所示:

  1. 由i(t)-i(t-1)得到前景圖     F1

  2. 由i(t+1)-i(t)得到前景圖    F2

  3.  F1 ∩ F2得到前景圖     F3

  4.  形態學處理

  也就是利用2次相鄰幀的差,然后去與操作,就得到了真正的那個影子了。

  這個在一定程度上可以解決”雙影”現象。

  同樣做了個簡單的實驗,代碼如下:

 1 // frame_3diff.cpp : 定義控制台應用程序的入口點。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <opencv2/highgui/highgui.hpp>
 6 #include <opencv2/imgproc/imgproc.hpp>
 7 #include <opencv2/core/core.hpp>
 8 
 9 #define threshold_diff1 10 //設置簡單幀差法閾值
10 #define threshold_diff2 10 //設置簡單幀差法閾值
11 
12 using namespace cv;
13 using namespace std;
14 
15 int main(int argc,unsigned char* argv[])
16 {
17     Mat img_src1,img_src2,img_src3;//3幀法需要3幀圖片
18     Mat img_dst,gray1,gray2,gray3;
19     Mat gray_diff1,gray_diff2;//存儲2次相減的圖片
20     Mat gray;//用來顯示前景的
21     bool pause=false;
22 
23     VideoCapture vido_file("IndoorGTTest1.avi");//在這里改相應的文件名
24     namedWindow("foreground",0);
25     for (;;)
26     {
27         if(!false)
28         {
29             vido_file >>img_src1;
30             cvtColor(img_src1,gray1,CV_BGR2GRAY);
31         
32             waitKey(5);
33             vido_file >>img_src2;
34             cvtColor(img_src2,gray2,CV_BGR2GRAY);
35             imshow("video_src",img_src2);//
36 
37             waitKey(5);
38             vido_file >>img_src3;
39             cvtColor(img_src3,gray3,CV_BGR2GRAY);
40 
41             subtract(gray2,gray1,gray_diff1);//第二幀減第一幀
42             subtract(gray3,gray2,gray_diff2);//第三幀減第二幀
43 
44             for(int i=0;i<gray_diff1.rows;i++)
45                 for(int j=0;j<gray_diff1.cols;j++)
46                 {
47                     if(abs(gray_diff1.at<unsigned char>(i,j))>=threshold_diff1)//這里模板參數一定要用unsigned char,否則就一直報錯
48                         gray_diff1.at<unsigned char>(i,j)=255;            //第一次相減閾值處理
49                     else gray_diff1.at<unsigned char>(i,j)=0;
50 
51                     if(abs(gray_diff2.at<unsigned char>(i,j))>=threshold_diff2)//第二次相減閾值處理
52                         gray_diff2.at<unsigned char>(i,j)=255;
53                     else gray_diff2.at<unsigned char>(i,j)=0;
54                 }
55             bitwise_and(gray_diff1,gray_diff2,gray);
56             imshow("foreground",gray);
57         }
58         char c=(char)waitKey(10);
59         if (c==27)
60         {
61             break;    
62         }
63         if(c==' ')
64             pause=!pause;//為什么暫停不了??
65     }
66     return 0;
67 }

   實驗結果如下:

  

  可以看出,效果並沒怎么變好,只是影子輪廓確實變細了,”空洞”現象也沒有改善,當然這只是個簡單的實驗,也沒有優化或改進,用的是最原始的思想,沒有使用形態學做后期處理。

 

 

 

 


免責聲明!

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



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