主要介绍四种运动目标检测的算法代码,每段代码博主实测可运行。当前主流的混合高斯背景模型,VIBE算法代码转载自他处。另外GMG算法,KNN算法在朱伟的书中也有讲,opencv3.0中,有专门的背景模型类BackgroundSubtractor。详情请下载朱伟《图像处理编程实例》源代码–下载资源

原理在另一篇文章中有些《运动目标检测》
1、帧间差分法求前景
帧间差分主要思想为两帧图像灰度化后相减得绝对值函数矩阵,然后二值化(注意阈值选择),得到前景图像。

#include "stdafx.h"
#include"opencv2\opencv.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{Mat img_src1, img_src2, gray1, gray2, gray_diff;int thvalue = 30;img_src1 = imread("F:\\毕业论文相关\\机场视频\\图片5帧\\density_img_5.jpg");img_src2 = imread("F:\\毕业论文相关\\机场视频\\图片5帧\\density_img_30.jpg");if (!img_src1.data || !img_src2.data)return -1;cvtColor(img_src1, gray1, CV_RGB2GRAY);cvtColor(img_src2, gray2, CV_RGB2GRAY);Mat img_dst(img_src1.rows, img_src1.cols, CV_8UC1);IplImage* Tsrcimage = &IplImage(gray1);//取指针IplImage* Tdstimage = &IplImage(gray2);IplImage* Tdif = &IplImage(img_dst);cvAbsDiff(Tsrcimage, Tdstimage, Tdif);//背景相减得灰度图cvThreshold(Tdif, Tdif, thvalue, 255, CV_THRESH_BINARY); //如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;cvShowImage("foreground", Tdif);//imshow("foreground", img_dst);waitKey();return 0;
}

2、三帧差分法求前景
第二帧减第一帧,第三帧减第二帧,结果相加,得到三帧差分图像。

#include "stdafx.h"
#include"opencv2\opencv.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;
using namespace std;int _tmain(int argc, _TCHAR* argv[])
{Mat img_src1, img_src2, img_src3;Mat gray1, gray2, gray3;int thvalue = 30;img_src1 = imread("F:\\毕业论文相关\\机场视频\\图片5帧\\density_img_5.jpg");img_src2 = imread("F:\\毕业论文相关\\机场视频\\图片5帧\\density_img_40.jpg");img_src3 = imread("F:\\毕业论文相关\\机场视频\\图片5帧\\density_img_65.jpg");if (!img_src1.data || !img_src2.data)return -1;cvtColor(img_src1, gray1, CV_RGB2GRAY);cvtColor(img_src2, gray2, CV_RGB2GRAY);cvtColor(img_src3, gray3, CV_RGB2GRAY);Mat result1(img_src1.rows, img_src1.cols, CV_8UC1);Mat result2(img_src1.rows, img_src1.cols, CV_8UC1);Mat gray_diff(img_src1.rows, img_src1.cols, CV_8UC1);IplImage* Tgray1 = &IplImage(gray1);//取指针IplImage* Tgray2 = &IplImage(gray2);IplImage* Tgray3 = &IplImage(gray3);IplImage* Tresult1 = &IplImage(result1);IplImage* Tresult2 = &IplImage(result2);IplImage* Tdif = &IplImage(gray_diff);cvAbsDiff(Tgray1, Tgray2, Tresult1);//背景相减得灰度图cvAbsDiff(Tgray2, Tgray3, Tresult2);//背景相减得灰度图cvThreshold(Tresult1, Tresult1, thvalue, 255, CV_THRESH_BINARY); //如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;cvThreshold(Tresult2, Tresult2, thvalue, 255, CV_THRESH_BINARY);cvAdd(Tresult1, Tresult2,Tdif);cvShowImage("foreground", Tdif);cvErode(Tdif, Tdif);   //腐蚀  cvShowImage("腐蚀后", Tdif);cvDilate(Tdif, Tdif);  //膨胀  cvShowImage("膨胀后", Tdif);//imshow("foreground", img_dst);waitKey();return 0;
}

3、混合高斯背景模型实现

// 功能:代码 9-5 高斯混合背景建模
// 作者:朱伟 zhu1988wei@163.com
// 来源:《OpenCV图像处理编程实例》
// 博客:http://blog.csdn.net/zhuwei1988
// 更新:2016-8-1
// 说明:版权所有,引用或摘录请联系作者,并按照上面格式注明出处,谢谢。//
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
Mat frame;
Mat fgMaskMOG2;
Ptr<BackgroundSubtractor> pMOG2;
int keyboard;
void processVideo(string videoFilename)
{// 视频获取VideoCapture capture(videoFilename);if(!capture.isOpened()){// 输出视频文件打开错误信息cerr << "Unable to open video file: " << videoFilename << endl;exit(EXIT_FAILURE);}// 按下q键和esc退出while( (char)keyboard != 'q' && (char)keyboard != 27 ){// 读取当前帧if(!capture.read(frame)) {cerr << "Unable to read next frame." << endl;cerr << "Exiting..." << endl;exit(EXIT_FAILURE);}// 图像尺寸缩小cv::resize(frame, frame,cv::Size(), 0.25,0.25);//  背景模型生成pMOG2->apply(frame, fgMaskMOG2);// 输出当前帧号stringstream ss;rectangle(frame, cv::Point(10, 2), cv::Point(100,20),cv::Scalar(255,255,255), -1);ss << capture.get(CAP_PROP_POS_FRAMES);string frameNumberString = ss.str();// 左上角显示帧号putText(frame, frameNumberString.c_str(), cv::Point(15, 15),FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));// 输出结果imshow("Frame", frame);imshow("FG Mask MOG 2", fgMaskMOG2);keyboard = waitKey(30);}capture.release();
}
int main(int argc, char* argv[])
{// 创建背景建模类pMOG2 = createBackgroundSubtractorMOG2(); string inputPath = "F:\\毕业论文相关\\机场视频\\机场.avi";processVideo(inputPath);return 0;
}

4、vibe算法

(算法程序出处找不到了,如果恰好作者看到,留言一下我给加上,实在抱歉。)
主函数代码如下

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include "highgui.h"
#include "hanshu.h"
#include <iostream>using namespace std;
using namespace cv;int nFrmNum = 0;//记录帧数
int Width;//记录帧的宽度
int Height;//记录帧的高度
int FrameRate;//记录视频帧率int main(int argc, char* argv[])
{IplImage* pFrame = NULL; CvMat* pFrameMat = NULL;//pFrame对象IplImage* pAfter = NULL; CvMat* pAfterMat = NULL;//保存pFrame对应的灰度图像IplImage* segMap = NULL; CvMat* segMat = NULL;//保存处理后的信息//要读取的视频文件和保存的视频文件路径char* openfile = "F:\\毕业论文相关\\机场视频\\密度人群.ts";char* outfile = "E:\\View004.avi";//检测结果输出位置char filename[100];//保存的图像位置和名称//打开视频文件CvCapture* pCapture = cvCreateFileCapture(openfile);if (pCapture == NULL) {cout << "video file open error!" << endl;return -1;}//获取视频相关信息,帧率和大小double fps = cvGetCaptureProperty(pCapture, CV_CAP_PROP_FPS);CvSize size = cvSize((int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_WIDTH) * 2,(int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_HEIGHT));//创建输出视频文件CvVideoWriter* Save_result = NULL;Save_result = cvCreateVideoWriter(outfile, CV_FOURCC('X', 'V', 'I', 'D'), fps, size, 1);IplImage* dstImg = cvCreateImage(size, IPL_DEPTH_8U, 3);//创建要保存的图像//创建窗口cvNamedWindow("video", CV_WINDOW_AUTOSIZE);//创建一个随机数生成器RNG rng(0xFFFFFFFF);//定义字体CvFont font;cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX_SMALL, 1, 1, 0, 1, 8);//逐帧读取视频并进行处理   pFrame为取出原始帧while (pFrame = cvQueryFrame(pCapture)){nFrmNum++;//如果是第一帧,申请内存并进行初始化if (nFrmNum == 1){segMap = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U, 1); //保存处理后的信息segMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//保存处理后的信息pAfter = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U, 1);//保存pFrame对应的灰度图像pAfterMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//保存pFrame对应的灰度图像//转化成单通道图像再处理cvCvtColor(pFrame, pAfter, CV_BGR2GRAY);cvConvert(pAfter, pAfterMat);//Initialize(pAfterMat, rng);//以一个随机数生成器初始化灰度图像}else {if (nFrmNum%30==0)//此处为每30帧读取一次{cvCvtColor(pFrame, pAfter, CV_BGR2GRAY);//RGB空间转换为RAY空间cvConvert(pAfter, pAfterMat);//用于图像和矩阵之间的相互转换update(pAfterMat, segMat, rng, nFrmNum);//更新背景cvConvert(segMat, segMap);//用于图像和矩阵之间的相互转换//载入原图像到目标图像cvSetImageROI(dstImg, cvRect(0, 0, pFrame->width, pFrame->height));cvCopy(pFrame, dstImg);cvResetImageROI(dstImg);//将segMap转换成三通道图像存在pFrame中cvCvtColor(segMap, pFrame, CV_GRAY2BGR);//载入检测后的图像到目标图像cvSetImageROI(dstImg, cvRect(pFrame->width, 0, pFrame->width * 2, pFrame->height));cvCopy(pFrame, dstImg);cvResetImageROI(dstImg);//显示提示文字cvPutText(dstImg, "Input Video", cvPoint(0, pFrame->height - 5), &font, CV_RGB(255, 0, 0));cvPutText(dstImg, "Vibe Segmentation", cvPoint(pFrame->width, pFrame->height - 5), &font, CV_RGB(255, 0, 0));//保存视频和输出cvWriteFrame(Save_result, dstImg);/*输出图片if(nFrmNum<11)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\000%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<101)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\00%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<1001)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\0%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<10001)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\%d_Vibe.jpg",nFrmNum-1);cvSaveImage(filename,dstImg);*/cvShowImage("video", dstImg);if (cvWaitKey(5) >= 0) break;}}}cvReleaseImage(&pFrame); cvReleaseMat(&pFrameMat);cvReleaseImage(&pAfter); cvReleaseMat(&pAfterMat);cvReleaseImage(&segMap); cvReleaseMat(&segMat);cvReleaseVideoWriter(&Save_result);cvReleaseImage(&dstImg);cvDestroyWindow("video");return 0;
}

类文件hanshu.h

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include "highgui.h"
#include <iostream>using namespace std;
using namespace cv;#define defaultNbSamples 20     //每个像素点的样本个数
#define defaultReqMatches 2     //#min指数
#define defaultRadius 20        //Sqthere半径
#define defaultSubsamplingFactor 16 //子采样概率
#define background 0        //背景像素
#define foreground 255      //前景像素void Initialize(CvMat* pFrameMat,RNG rng);//初始化
void update(CvMat* pFrameMat,CvMat* segMat,RNG rng,int nFrmNum);//更新

类文件hanshu.cpp

#include "stdafx.h"
#include "hanshu.h"
#include <opencv2/opencv.hpp>
#include "highgui.h"
#include <math.h>
#include <iostream>using namespace std;
using namespace cv;static int c_xoff[9] = {-1,  0,  1, -1, 1, -1, 0, 1, 0};//x的邻居点
static int c_yoff[9] = {-1,  0,  1, -1, 1, -1, 0, 1, 0};//y的邻居点float samples[1024][1024][defaultNbSamples+1];//保存每个像素点的样本值//初始化
void Initialize(CvMat* pFrameMat,RNG rng){//记录随机生成的 行(r) 和 列(c)int rand,r,c;//对每个像素样本进行初始化for(int y=0;y<pFrameMat->rows;y++){//Heightfor(int x=0;x<pFrameMat->cols;x++){//Widthfor(int k=0;k<defaultNbSamples;k++){//随机获取像素样本值rand=rng.uniform( 0, 9 );//b如果是真值,返回a,否则返回(int)(next() % (b - a) + a);r=y+c_yoff[rand]; if(r<0) r=0; if(r>=pFrameMat->rows) r=pFrameMat->rows-1;  //行c=x+c_xoff[rand]; if(c<0) c=0; if(c>=pFrameMat->cols) c=pFrameMat->cols-1;  //列//存储像素样本值samples[y][x][k]=CV_MAT_ELEM(*pFrameMat,float,r,c);}samples[y][x][defaultNbSamples]=0;}}
}//更新函数
void update(CvMat* pFrameMat,CvMat* segMat,RNG rng,int nFrmNum){for(int y=0;y<pFrameMat->rows;y++){ //Heightfor(int x=0;x<pFrameMat->cols;x++){ //Width//用于判断一个点是否是背景点,index记录已比较的样本个数,count表示匹配的样本个数int count=0,index=0;float dist=0;//while((count<defaultReqMatches) && (index<defaultNbSamples)){dist=CV_MAT_ELEM(*pFrameMat,float,y,x)-samples[y][x][index];if(dist<0) dist=-dist;if(dist<defaultRadius) count++;index++;}if(count>=defaultReqMatches){//判断为背景像素,只有背景点才能被用来传播和更新存储样本值samples[y][x][defaultNbSamples]=0;*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=background;int rand=rng.uniform(0,defaultSubsamplingFactor);if(rand==0){rand=rng.uniform(0,defaultNbSamples);samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}rand=rng.uniform(0,defaultSubsamplingFactor);if(rand==0){int xN,yN;rand=rng.uniform(0,9);yN=y+c_yoff[rand];if(yN<0) yN=0; if(yN>=pFrameMat->rows) yN=pFrameMat->rows-1;rand=rng.uniform(0,9);xN=x+c_xoff[rand];if(xN<0) xN=0; if(xN>=pFrameMat->cols) xN=pFrameMat->cols-1;rand=rng.uniform(0,defaultNbSamples);samples[yN][xN][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);} }else {//判断为前景像素*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=foreground;samples[y][x][defaultNbSamples]++;if(samples[y][x][defaultNbSamples]>50){int rand=rng.uniform(0,defaultNbSamples);if(rand==0){rand=rng.uniform(0,defaultNbSamples);samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}}}}}}

运动目标检测代码(帧差、高斯混合、vibe代码实现)相关推荐

  1. 数字图像处理拓展题目——利用Matlab实现动态目标检测 二帧差法、ViBe法、高斯混合模型法,可应用于学生递东西行为检测

    1.二帧差法实现动态目标检测 先上效果图: 利用GUI界面显示出来效果图为: 实现流程 1.利用matlab中的VideoReader函数读取视频流. 2.帧差法:获得视频帧数,用for循环对图像每相 ...

  2. 运动目标检测之帧差法

    原理简介: 所谓帧差法也就是对连续图像帧做差分运算,其结果与定义好的阈值比较,若大于阈值则为运动目标值为1,否则值为0 . 帧差法一般分为两帧差分和三帧差分. 两帧差分: 取连续的两帧序列,用后一帧减 ...

  3. 视频目标跟踪算法matlab仿真,对比二帧差法,三帧差法,混合高斯法以及Vibe算法

    目录 1.算法概述 2.仿真效果 3.MATLAB仿真源码 1.算法概述 1.1二帧差法 帧间差分法是一种通过对视频图像序列的连续两帧图像做差分运算获取运动目标轮廓的方法.当监控场景中出现异常目标运动 ...

  4. python图像差分法目标检测_运动目标检测(2)—帧间差分法

    帧差法依据的原则是:当视频中存在移动物体的时候,相邻帧(或相邻三帧)之间在灰度上会有差别,求取两帧图像灰度差的绝对值,则静止的物体在差值图像上表现出来全是0,而移动物体特别是移动物体的轮廓处由于存在灰 ...

  5. 合成孔径雷达地面运动目标检测技术研究——基于概率图(Matlab代码实现)

     

  6. FPGA运动目标检测,基于米联客FDMA设计开发,A7和zynq两个版本

    FPGA运动目标检测,基于米联客FDMA设计开发,A7和zynq两个版本 开发环境如下: 纯FPGA开发板:米联客MA703FA,A7-35T的FPGA: ZYNQ开发板:米联客MZ7100FA,zy ...

  7. 【opencv】(11) 背景建模,帧差法、混合高斯模型,实战:行人检测,附python完整代码和数据集

    各位同学好,今天和大家分享一下opencv背景建模相关操作.主要介绍两种背景建模方法,帧差法和混合高斯模型. 案例简介:现有一份路口摄像机拍摄的行人流视频,通过背景建模方法,区分背景和前景,完成行人识 ...

  8. 基于高斯核密度估计的背景建模和改进的五帧帧差法相融合的运动目标检测算法

    上篇文章所指定的是对一个不包含动态背景的监控视频进行前景提取,用基于改进的五帧帧差和混合高斯模型相融合的前景提取算法是可以很好实现前景提取的.但本文中要求在包含动态背景的监控视频提取前景目标,虽然上篇 ...

  9. MATLAB运动目标检测系统

    1 绪论 1.1 课题研究背景及意义 运动目标检测是图像处理与计算机视觉的一个分支,在理论和实践上都有重大意义,长久以来一直被国内外学者所关注.在实际中,视频监控利用摄像机对某一特定区域进行监视,是一 ...

最新文章

  1. C#如何在Form中嵌入并且操作Excel表格
  2. 大脑芯片公司Neuralink计划在人脑内植入芯片,他们到底想干什么?
  3. 在家搭建大数据分布式计算环境!
  4. 正则表达的式的基本功能
  5. 【OpenCV】IplImage类型图像ROI矩形区域的快速获取
  6. 【大会】编码、画质评价与网络协议的未来
  7. Pascal's Triangle 2(leetcode java)
  8. C++智能指针(二)模拟实现三种智能指针
  9. 分布式领域CAP理论
  10. [html] 写一个搜索框,聚焦时搜索框向左拉长并有动画效果
  11. Oracle安全漏洞2016.10报告
  12. Directx11教程(65) 渲染到纹理
  13. mysql 取出当前第几列_mysql 获取表有多少列
  14. ORA-01113问题的简单分析
  15. Flowchat 流程图在Markdown中的使用(不同编辑器有细微区别)
  16. ajax 皇马,历史上最伟大11支球队 西班牙国家队在列 皇马两次入选
  17. 让终端窗口“下雪”的有趣指令
  18. 高通SDX12平台:启动流程梳理
  19. 玩转AgiileCDN(十三)——全站加速
  20. 2012 5.4青年节--上海出差

热门文章

  1. 口碑最好的国产蓝牙耳机有哪些?国产蓝牙耳机品牌排行榜前十名
  2. 161018、springMVC中普通类获取注解service方法
  3. 公司局域网上ping www.qq.com
  4. 【ArcGIS】基础教程:全域莫兰指数与局域莫兰指数的计算
  5. 山东高新技术企业申报当年下证的知识产权能用吗?
  6. 一文搞懂主流的扫码登录技术原理(附源码)
  7. 淘宝直播视频回放下载,全程免费(扶摇生财思维)
  8. 默哀1分钟~汶川5.12
  9. EXCEL计算公式之:excel跨文件、跨Sheet的合并计算公式
  10. 人物角色建模—镰刀链男人物模型制作过程分享教程!原来3D建模也不难