opencv实现三帧差法解析

 更新时间:2020年03月21日 06:25:21   作者:xiao__run  
这篇文章主要介绍了opencv实现三帧差法的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

今天和大家谈谈三帧差法来实现运动目标检测吧,其中运动检测画框实现追踪方法多种多样,大家可以自行百度,后面我也会一一实现,今天我先给大家玩玩三帧差法吧;;;;(注释非常清楚哦,程序也极其简单的)

帧差法是最为常用的运动目标检测和分割方法之一,基本原理就是在图像序列相邻两帧或三帧间采用基于像素的时间差分通过闭值化来提取出图像中的运动区域。首先,将相邻帧图像对应像素值相减得到差分图像,然后对差分图像二值化,在环境亮度变化不大的情况下,如果对应像素值变化小于事先确定的阂值时,可以认为此处为背景像素:如果图像区域的像素值变化很大,可以认为这是由于图像中运动物体引起的,将这些区域标记为前景像素,利用标记的像素区域可以确定运动目标在图像中的位置。由于相邻两帧间的时间间隔非常短,用前一帧图像作为当前帧的背景模型具有较好的实时性,其背景不积累,且更新速度快、算法简单、计算量小。算法的不足在于对环境噪声较为敏感,闽值的选择相当关键,选择过低不足以抑制图像中的噪声,过高则忽略了图像中有用的变化。对于比较大的、颜色一致的运动目标,有可能在目标内部产生空洞,无法完整地提取运动目标。

简单说一下程序思路哈,参考了一下opencv官网教程

#include<iostream>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
const unsigned char FORE_GROUD = 255;int thresh = 10;
int main(int argc,char*argv[])
{   
 VideoCapture video(argv[1]); //判断如果video是否可以打开 
 if(!video.isOpened())  
 return -1;  

//用于保存当前帧的图片 

 Mat currentBGRFrame;  
//用来保存上一帧和当前帧的灰度图片 
 Mat previousSecondGrayFrame; Mat previousFirstGrayFrame; Mat currentGaryFrame; 
 //保存两次的帧差 
Mat previousFrameDifference; //previousFrameFirst - previousFrameSecond的差分 
Mat currentFrameDifference;  //currentFrame - previousFrameFirst; 
 //用来保存帧差的绝对值 
Mat absFrameDifferece; 
//用来显示前景 
 Mat previousSegmentation; Mat currentSegmentation; Mat segmentation; 
 //显示前景 
 namedWindow("segmentation",1); 
 createTrackbar("阈值:","segmentation",&thresh,FORE_GROUD,NULL); 
 //帧数 
 int numberFrame = 0; 
//形态学处理用到的算子 
 Mat morphologyKernel = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));  
 for(;;) 
 {  //读取当前帧  
 video >> currentBGRFrame;  
 //判断当前帧是否存在  
 if(!currentBGRFrame.data)   
 break;   
  numberFrame++;  
 //颜色空间的转换  
 cvtColor(currentBGRFrame,currentGaryFrame,COLOR_BGR2GRAY);   
 if( numberFrame == 1)  {  
 //保存当前帧的灰度图   
 previousSecondGrayFrame = currentGaryFrame.clone();    
  //显示视频  
 imshow("video",currentBGRFrame);   continue;  }  
 else if( numberFrame == 2)  
 {   
 //保存当前帧的灰度图  
  previousFirstGrayFrame = currentGaryFrame.clone();   
 //previousFirst - previousSecond   
 subtract(previousFirstGrayFrame,previousSecondGrayFrame,previousFrameDifference,Mat(),CV_16SC1);   
 //取绝对值   
 absFrameDifferece = abs(previousFrameDifference);      
 //位深的改变   
 absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0);   
 //阈值处理  
 threshold(absFrameDifferece,previousSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY);    
  //显示视频  
 imshow("video",currentBGRFrame);   
 continue;  }  
 else  
 {   
 //src1-src2   
subtract(currentGaryFrame,previousFirstGrayFrame,currentFrameDifference,Mat(),CV_16SC1);    
   //取绝对值  
  absFrameDifferece = abs(currentFrameDifference);      
 //位深的改变   absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0); 
   //阈值处理   
 threshold(absFrameDifferece,currentSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY);  //与运算   
 bitwise_and(previousSegmentation,currentSegmentation,segmentation);    //中值滤波   
medianBlur(segmentation,segmentation,3); //形态学处理(开闭运算)   
 //morphologyEx(segmentation,segmentation,MORPH_OPEN,morphologyKernel,Point(-1,-1),1,BORDER_REPLICATE);   
 morphologyEx(segmentation,segmentation,MORPH_CLOSE,morphologyKernel,Point(-1,-1),2,BORDER_REPLICATE);      
      //找边界   
 vector< vector<oint> > contours;   
 vector<Vec4i> hierarchy;   
 //复制segmentation  
  Mat tempSegmentation = segmentation.clone();  
  findContours( segmentation, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );//CV_RETR_TREE  
  vector< vector<oint> > contours_poly( contours.size() );     
  /*存储运动物体*/   
  vector<Rect> boundRect;   
  boundRect.clear();      
 //画出运动物体   
 for(int index = 0;index < contours.size() ;index++)   
 {   
 approxPolyDP( Mat(contours[index]), contours_poly[index], 3, true );   
  Rect rect = boundingRect( Mat(contours_poly[index]) );    
 rectangle(currentBGRFrame,rect,Scalar(0,255,255),2);   }  
 //显示视频  
 imshow("video",currentBGRFrame);      
 //前景检测   
imshow("segmentation",segmentation);   
 //保存当前帧的灰度图   
 previousFirstGrayFrame = currentGaryFrame.clone();      
 //保存当前的前景检测   
 previousSegmentation = currentSegmentation.clone();  
 }    
 if(waitKey(33) == 'q')   
 break; 
 } 
 return 0;
}

编译之后,运行./main.cpp **.avi

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C/C++ QT实现解析JSON文件的示例代码

    C/C++ QT实现解析JSON文件的示例代码

    JSON是一种轻量级的数据交换格式,它是基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。这篇文章主要介绍了QT实现解析JSON文件的示例代码,需要的可以参考一下
    2022-01-01
  • C++调用C#的DLL实现方法

    C++调用C#的DLL实现方法

    这篇文章主要介绍了C++调用C#的DLL实现方法,很有实用价值,需要的朋友可以参考下
    2014-07-07
  • c语言的程序环境与预处理详解

    c语言的程序环境与预处理详解

    大家好,本篇文章主要讲的是c语言的程序环境与预处理详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • 求素数,用vector存储的实现方法

    求素数,用vector存储的实现方法

    本篇文章是对求素数,用vector存储的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 带你分分钟玩转C语言指针

    带你分分钟玩转C语言指针

    c语言指针其实是一个整形变量,与其它数据不同的是,它的作用是用来存储其它变量的地址,下面这篇文章主要给大家介绍了关于C语言指针的相关资料,需要的朋友可以参考下
    2022-06-06
  • C语言错误信息报告strerror函数和perror函数详解

    C语言错误信息报告strerror函数和perror函数详解

    这篇文章主要介绍了C语言错误信息报告strerror函数和perror函数,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • C语言内存操作函数使用示例梳理讲解

    C语言内存操作函数使用示例梳理讲解

    这篇文章主要介绍了C语言库函数中的内存操作函数memcpy()、memmove()、memset()、memcmp()使用示例分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • VisualStudio2022打包项目文件为.exe安装包

    VisualStudio2022打包项目文件为.exe安装包

    本文主要介绍了VisualStudio2022打包项目文件为.exe安装包,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 华为云CodeArts IDE Online快速入门和使用

    华为云CodeArts IDE Online快速入门和使用

    华为云CodeArts IDE Online服务,提供了可随时随地编码的云上开发环境,同时具备开放的生态和独立插件市场,本文主要介绍了华为云CodeArts IDE Online快速入门和使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • 将字符串str1复制为字符串str2的三种解决方法

    将字符串str1复制为字符串str2的三种解决方法

    以下是对将字符串str1复制为字符串str2的三种解决方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10

最新评论