三帧差法的实现
来源:互联网 发布:数控车螺纹编程实例 编辑:程序博客网 时间:2024/06/05 01:52
帧差法是最为常用的运动目标检测和分割方法之一,基本原理就是在图像序列相邻两帧或三帧间采用基于像素的时间差分通过闭值化来提取出图像中的运动区域。首先,将相邻帧图像对应像素值相减得到差分图像,然后对差分图像二值化,在环境亮度变化不大的情况下,如果对应像素值变化小于事先确定的阂值时,可以认为此处为背景像素:如果图像区域的像素值变化很大,可以认为这是由于图像中运动物体引起的,将这些区域标记为前景像素,利用标记的像素区域可以确定运动目标在图像中的位置。由于相邻两帧间的时间间隔非常短,用前一帧图像作为当前帧的背景模型具有较好的实时性,其背景不积累,且更新速度快、算法简单、计算量小。算法的不足在于对环境噪声较为敏感,闽值的选择相当关键,选择过低不足以抑制图像中的噪声,过高则忽略了图像中有用的变化。对于比较大的、颜色一致的运动目标,有可能在目标内部产生空洞,无法完整地提取运动目标。
环境:vs2010+opencv2.3
//自己写的帧差法
#include <highgui.h>#include <cv.h>
#include <math.h>
#include <cxcore.h>
#define threshold_diff1 45 //设置简单帧差法阈值
#define threshold_diff2 45 //设置简单帧差法阈值
void ImageGray(IplImage *sourceImage, IplImage *grayImage);
int main(int argc, char* argv[])
{
cvNamedWindow("src",CV_WINDOW_AUTOSIZE); //建立窗口
cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);
CvCapture *capture=cvCreateFileCapture("E:\\新建文件夹\\行车视频.avi"); //读取视频
IplImage *mframe=NULL; //读入视频帧
IplImage *gray_diff,*gray_diff1, *gray_diff2,*img1,*img2,*img3,*gray1,*gray2,*gray3,*gray;
int ncount=0; //帧计数
while(mframe=cvQueryFrame(capture))
{
ncount+=1;
if(ncount==1)
{
img1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
img2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
img3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray_diff1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray_diff2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
gray_diff=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
ImageGray(mframe,gray1);
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img1->imageData[j *mframe->width + i]=gray1->imageData[j *mframe->width + i] ;
}
}
}
if(ncount==2)
{
//灰度化
ImageGray(mframe,gray2);
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img2->imageData[j *mframe->width + i]=gray2->imageData[j *mframe->width + i] ;
}
}
}
if(ncount>=3)
{
if(ncount==3)
{
//灰度化
ImageGray(mframe,gray3);
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img3->imageData[j *mframe->width + i]=gray3->imageData[j *mframe->width + i] ;
}
}
}
else
{
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img1->imageData[j *mframe->width + i]=img2->imageData[j *mframe->width + i] ;
}
}
//*img1=*img2; //把原先第二帧放在第一帧存放的地方img1覆盖掉
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img2->imageData[j *mframe->width + i]=img3->imageData[j *mframe->width + i] ;
}
}
//*img2=*img3; //把原先第三帧放在第二帧存放的地方img2覆盖掉
//灰度化
ImageGray(mframe,gray);
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
img2->imageData[j *mframe->width + i]=gray->imageData[j *mframe->width + i] ;
}
}
//*img3=*img;//把当前帧放在第三帧存放的地方img3覆盖掉
}
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
gray_diff1->imageData[j *mframe->width + i]=(unsigned char)abs((int)img1->imageData[j *mframe->width + i]-(int)img2->imageData[j *mframe->width + i]);
gray_diff2->imageData[j *mframe->width + i]=(unsigned char)abs((int)img1->imageData[j *mframe->width + i]-(int)img2->imageData[j *mframe->width + i]);
}
}
for (int j = 0; j < mframe->height; ++j)
{
for (int i= 0; i< mframe->width; ++i)
{
if(gray_diff1->imageData[j *mframe->width + i]>threshold_diff1)
gray_diff1->imageData[j *mframe->width + i]=255; //第一次相减阈值处理
else
gray_diff1->imageData[j *mframe->width + i]=0;
if(gray_diff2->imageData[j *mframe->width + i]>threshold_diff2)
gray_diff2->imageData[j *mframe->width + i]=255;
else
gray_diff2->imageData[j *mframe->width + i] =0; //第二次相减阈值处理
gray_diff->imageData[j *mframe->width + i]= gray_diff1->imageData[j *mframe->width + i]&gray_diff2->imageData[j *mframe->width + i]; // gT2[i],gT1[i]求与
}
}
cvShowImage("src",mframe);
cvShowImage("dst", gray_diff);
}
char c = cvWaitKey(30);
if(c==27)
break;
} //while循环结束
cvReleaseImage(&mframe);
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvReleaseImage(&gray1);
cvReleaseImage(&gray2);
cvReleaseImage(&gray3);
cvReleaseImage(&gray);
cvReleaseImage(&gray_diff);
cvReleaseImage(&gray_diff1);
cvReleaseImage(&gray_diff2);
cvDestroyWindow("src");
cvDestroyWindow("dst");
return 0;
}
void ImageGray(IplImage *sourceImage, IplImage *grayImage)
{
for(int i = 0; i < sourceImage->height; i++)
{
for(int j = 0; j < sourceImage->width; j++)
{
unsigned char b = (unsigned char)sourceImage->imageData[(i * sourceImage->width + j) * 3 + 0];
unsigned char g = (unsigned char)sourceImage->imageData[(i * sourceImage->width + j) * 3 + 1];
unsigned char r = (unsigned char)sourceImage->imageData[(i * sourceImage->width + j) * 3 + 2];
unsigned char gray = 0.299 * r + 0.587 * g + 0.114 * b;
grayImage->imageData[i * sourceImage->width + j] = gray;
}
}
}
0 0
- 三帧差法的实现
- 三子棋的实现的实现的实现
- JAVA实现的时钟实现
- 模态框的的实现
- 杀毒软件的简单实现的简单实现
- android的实现电话号码的实现
- 音频的实现音乐声音的实现
- malloc的实现、内存池的实现
- 异形窗体的实现
- 个性化的分页实现
- ASP数据库连接的实现
- Struts单选框的实现
- 梅西迭代算法的实现
- 翻页功能的实现
- Struts,MVC 的实现
- 实现JavaScript的继承
- 接口的显示实现
- TTerm的实现( 一)
- c#+oracle存储过程实现分页
- QCombobox 设置item的高度 样式表
- 运行程序exe无法启动,dll找不到
- ViewHolder的另一种简化的巧妙写法
- hadoop,学习心得
- 三帧差法的实现
- MSP430仿真器降级失败的解决办法
- tju3243 Blocked Road
- (4)LinuxI2C驱动--从两个访问eeprom的例子开始
- rust 用指针类型转换的方法将u8数组(或slice)转换成u32
- Unix NetWork Programming——环境搭建(解决unp.h等源码编译问题)
- UVA - 1374 Power Calculus
- priority inversion
- XCODE中添加pch文件