背景减除法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背景消减法_OpenCV_详解
一.基本概念
背景消减法可以看作一种特殊的帧差法。
基本思想:利用当前帧图像与背景图像对应象素点的灰度差值来检测车辆。如果当前图像的象素点和背景图像的象素点灰度值差别很大,就认为此象素点有车通过;相反,如果当前图像的象素点和背景图像的象素点灰度值差别较小,在一定的阈值范围内,我们就认为此象素点为背景象素点。
背景差值法假定图像背景是静止不变的,即图像背景不随图像帧数而变,可表示为
b(x,y),定义图像序列为f(x,y,i),其中(x,y)为图像位置坐标,i为图像帧数,将每一帧图像的灰度值减去背景的灰度值可得到一个差值图像:id(x,y,i)=f(x,y,i)-b(x,y)
背景差值法检测运动目标速度快,检测准确,易于实现,其关键是背景图像的获取与背景更新。在实际应用中,静止背景是不易直接获得的,同时,由于背景图像的动态变化,需要通过视频序列的帧间信息来估计和恢复背景,即背景重建,所以要选择性的更新背景。然而它对于动态场景的变化,例如光照的变化和阴影的干扰等特别敏感。因此,选取一个可靠的背景模型进行背景的提取与动态更新以适应环境的变化是必要的。
使用背景差分法进行运动检测通常会遇到如下一些问题:
(1)背景获取:最简单的方法是在场景中没有运动目标的情况下进行,但在现实中肯定是无法满足的,如高速公路和城市交通的监控,需要一种方法能在场景存在运动目标的情况下获得背景图像。
(2)背景的扰动:如树叶、树枝等各种东西的摇动
(3)外界光照条件的变化
(4)背景中固定对象的移动
(5)背景的更新
(6)阴影的影响
背景消减法根据其背景模型的不同又可分为:直方图法、平均值法、单分布高斯背景模型、混合高斯分布背景模型、Kalman滤波器法,HMM模型法。
二.下面分享的是两种背景实现方式:
(1)背景即为第一帧图像,简单的先看看程序的基本步骤和实现方法。这种方法适用于第一帧即为全部背景,如果存在不是背景的物体,将出现误差;同时进行了简单的背景更新;
(2)背景为前50帧的平均值,对于高速的车流量较少的地段,背景提取较理想,车辆缓慢移动时会在背景上留下痕迹。同时也进行了背景的简单更新;
(3)同样的方法可以尝试不同的背景提取模型。
三.程序源代码
[cpp]view plaincopy
1.#include "stdafx.h" //背景为第一帧
2.#include "highgui.h"
3.#include "cv.h"
4.#include "cxcore.h"
5.#include "ml.h"
6.
7.int main(int argc, char* argv[])
8.{
9. CvCapture* pCapture = cvCaptureFromFile("video.avi");
10.if( !pCapture) return -1;
11.
12. IplImage* pImgFrame = NULL;
13. IplImage* pImgProcessed = NULL;
14. IplImage* pImgBackground = NULL;
15. IplImage* pyrImage = NULL;
16.
17. CvMat* pMatFrame = NULL;
18. CvMat* pMatProcessed = NULL;
19. CvMat* pMatBackground = NULL;
20.
21. cvNamedWindow("video", 0);
22. cvNamedWindow("background",0);
23. cvNamedWindow("processed",0);
24.
25. cvResizeWindow("video",300,300); //重新定义窗口的大小
26. cvResizeWindow("background",300,300);
27. cvResizeWindow("processed",300,300);
28.
29. cvMoveWindow("video", 0, 100); //设定窗口的位置
30. cvMoveWindow("background", 350, 100);
31. cvMoveWindow("processed", 700, 100);
32.
33.//int thresh_low = 20;
34.//cvCreateTrackbar("Low","processed",&thresh_low,255,NULL); //创建滚动
条,显示阈值
35.
36. pImgFrame = cvQueryFrame( pCapture ); //取第一帧
37. pImgBackground = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->heigh
t), IPL_DEPTH_8U,1);
38. pImgProcessed = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->height
), IPL_DEPTH_8U,1);
39. pyrImage = cvCreateImage(cvSize(pImgFrame->width/2, pImgFrame->height/2)
, IPL_DEPTH_8U,1);
40.
41. pMatBackground = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32F
C1);
42. pMatProcessed = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC
1);
43. pMatFrame = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);
44.
45. cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0); //高斯平滑
46. cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);
47. cvCvtColor(pImgFrame, pImgBackground, CV_BGR2GRAY);
48. cvConvert(pImgProcessed, pMatBackground);
49. cvConvert(pImgProcessed, pMatFrame);
50. cvConvert(pImgProcessed, pMatProcessed);
51.
52. cvSmooth(pMatBackground, pMatBackground, CV_GAUSSIAN, 3, 0, 0);
53.
54.while(pImgFrame = cvQueryFrame( pCapture ))
55. {
56. cvShowImage("video", pImgFrame);
57. cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0);
58.
59. cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);
60. cvConvert(pImgProcessed, pMatFrame);
61.
62. cvSmooth(pMatFrame, pMatFrame, CV_GAUSSIAN, 3, 0, 0);
63. cvAbsDiff(pMatFrame, pMatBackground, pMatProcessed);
64.