• 前景检测算法_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 }

       实验结果如下:

      

      可以看出,效果并没怎么变好,只是影子轮廓确实变细了,”空洞”现象也没有改善,当然这只是个简单的实验,也没有优化或改进,用的是最原始的思想,没有使用形态学做后期处理。

  • 相关阅读:
    getText() 获取properties中的变量
    Vue----渐进式框架的理解
    appium---学习
    css----overflow(布局)
    css----display(显示) 与 Visibility(可见性)
    css----position(定位)
    中秋节
    找工作清闲的一天
    两天没有好好休息的感觉
    开始正式步入找工作的节奏
  • 原文地址:https://www.cnblogs.com/tornadomeet/p/2477629.html
Copyright © 2020-2023  润新知