目标跟踪之高斯混合模型---cv实现
#include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <cvaux.h>//必须引此头文件
void main( )
{
//参数初始化定义
IplImage* pFrame = NULL;
IplImage* pFrImg = NULL;
IplImage* pBkImg = NULL;
CvCapture* pCapture = NULL;
IplImage* origin_rgb = NULL ;//定义rgb空间的存储
IplImage* origin_ycc = NULL ;//定义转换成YCrCb空间的存储
IplImage* lumi = NULL ;//定义亮度分量的存储空间
//定义窗口
cvNamedWindow("lumi",1);//定义显示窗口的名字,显示原始的视频
cvMoveWindow("lumi",30,0);//定义显示窗口的位置
cvNamedWindow("background",1);//显示经过转换格式的视频
cvMoveWindow("background",360,0);
cvNamedWindow("foreground",1);//显示经过亮度提取的视频
cvMoveWindow("foreground",690,0);
//读取一帧视频文件作为初始化
pCapture = cvCaptureFromFile("video.long.xvid.avi") ;
pFrame = cvQueryFrame(pCapture);
int i ;
for (i=0;i<2;i++)
{
pFrame = cvQueryFrame(pCapture);
}
//RGB转换成亮度
origin_rgb = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 3 );
origin_ycc = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 3 );
lumi = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1 );
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1 );
pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1 );
//origin_rgb = cvCloneImage(pFrame) ;//或者 cvCopy(pFrame,origin_rgb,NULL) ;
cvCopy(pFrame,origin_rgb,NULL) ;//复制视频
cvCvtColor(origin_rgb,origin_ycc,CV_BGR2YCrCb) ; //实现视频格式转换
cvSplit(origin_ycc,lumi,NULL,NULL,NULL); //获取亮度分量
//为高斯模型设置初时参数
CvGaussBGStatModelParams* params = new CvGaussBGStatModelParams;
params->win_size = 50;
params->n_gauss = 3;
params->bg_threshold = 0.7;
params->std_threshold = 3.5;
params->minArea = 15;
params->weight_init = 0.333;
params->variance_init = 30;
CvBGStatModel* bgModel = cvCreateGaussianBGModel(lumi,params);
int key=-1;
while(key != 'q')
{
//获取下一帧视频
pFrame = cvQueryFrame(pCapture);
cvCopy(pFrame,origin_rgb,NULL) ;//复制视频
cvCvtColor(origin_rgb,origin_ycc,CV_BGR2YCrCb) ; //实现视频格式转换
cvSplit(origin_ycc,lumi,NULL,NULL,NULL); //获取亮度分量
if( !pFrame )
break;
//更新高斯模型
cvUpdateBGStatModel(lumi,bgModel);
pFrImg = bgModel->foreground ;//前景图象
pBkImg = bgModel->background ; //背景图象
//将图象倒转过来
pBkImg->origin = 1 ;
pFrImg->origin = 1 ;
lumi->origin = 1 ;
//显示结果
cvShowImage("lumi",lumi);
cvShowImage("background",pBkImg);
cvShowImage("foreground",pFrImg);
key = cvWaitKey(10);
}
// cvWaitKey(0) ;//窗口的回调函数,必须要的,不然窗口的显示会不正常
//释放窗口内存资源
cvDestroyWindow("lumi");
cvDestroyWindow("background");
cvDestroyWindow("foreground");
//释放图象占用的内存资源
cvReleaseImage(&lumi);
cvReleaseImage(&pBkImg);
cvReleaseImage(&pFrImg);
cvReleaseCapture(&pCapture);
cvReleaseBGStatModel( &bgModel );
}
创建高斯背景模型
cvCreateGaussianBGModel( IplImage* first_frame, CvGaussBGStatModelParams* parameters )
{
//CvGaussBGModel在cvaux.h中有定义,是一个结构体
CvGaussBGModel* bg_model = 0;
CV_FUNCNAME( "cvCreateGaussianBGModel" );//在cxerror.h定义,定义cvFuncName宏变量
//cvFuncName定义为和函数名称相同cvCreateGaussianBGModel
__BEGIN__;//开始处理(是必须接在这个CV_FUNCNAME之后的)
double var_init;
CvGaussBGStatModelParams params;//定义初始化变量,在cvaux.h中定义的结构体CvGaussBGStatModelParams
int i, j, k, n, m, p;
//init parameters
if( parameters == NULL )
{
params.win_size = CV_BGFG_MOG_WINDOW_SIZE;//CV_BGFG_MOG_WINDOW_SIZE=200,和学习率的关系1/200=0.005
params.bg_threshold = CV_BGFG_MOG_BACKGROUND_THRESHOLD;//CV_BGFG_MOG_BACKGROUND_THRESHOLD=0.7(判断是否为背景点的阈值)
params.std_threshold = CV_BGFG_MOG_STD_THRESHOLD;//CV_BGFG_MOG_STD_THRESHOLD=2.5(标准阈值)
params.weight_init = CV_BGFG_MOG_WEIGHT_INIT;//CV_BGFG_MOG_WEIGHT_INIT=0.05(权值)
params.variance_init = CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;//CV_BGFG_MOG_SIGMA_INIT=30(方差)
params.minArea = CV_BGFG_MOG_MINAREA;//CV_BGFG_MOG_MINAREA=15.f(这个不知道?)
params.n_gauss = CV_BGFG_MOG_NGAUSSIANS;//CV_BGFG_MOG_NGAUSSIANS=5(高斯模型数量)
}
else
{
params = *parameters;
}
//CV_IS_IMAGE在cxtypes.h中定义,在这里估计是判断是否有读入图象帧
//CV_StsBadArg=-5,代表函数有问题,或者输入的参数有问题
if( !CV_IS_IMAGE(first_frame) )
CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );
//CV_CALL在cxerror.h中有定义,这里用来确认一下调用是否正确
CV_CALL( bg_model = (CvGaussBGModel*)cvAlloc( sizeof(*bg_model) ));
memset( bg_model, 0, sizeof(*bg_model) );
bg_model->type = CV_BG_MODEL_MOG;//这个在cvGaussBGModel中定义的CV_BG_STAT_MODEL_FIELDS()函数中都有,存在type,release,update,foreground,background等
bg_model->release = (CvReleaseBGStatModel)icvReleaseGaussianBGModel;
bg_model->update = (CvUpdateBGStatModel)icvUpdateGaussianBGModel;
bg_model->params = params;
//分配存储空间
CV_CALL( bg_model->g_point = (CvGaussBGPoint*)cvAlloc(sizeof(CvGaussBGPoint)*
((first_frame->width*first_frame->height) + 256)));//这个是参与的点数,以及存放这些点需要的空间
CV_CALL( bg_model->background = cvCreateImage(cvSize(first_frame->width,
first_frame->height), IPL_DEPTH_8U, first_frame->nChannels));//给背景分配存储空间
CV_CALL( bg_model->foreground = cvCreateImage(cvSize(first_frame->width,
first_frame->height), IPL_DEPTH_8U, 1));//给前景分配存储空间
CV_CALL( bg_model->storage = cvCreateMemStorage());//分配存储空间
//初始化
var_init = 2 * params.std_threshold * params.std_threshold;
CV_CALL( bg_model->g_point[0].g_values =
(CvGaussBGValues*)cvAlloc( sizeof(CvGaussBGValues)*params.n_gauss*
(first_frame->width*first_frame->height + 128)));//这个是给g_value分配足够的存储空间
//程序说明
//g_values[0],g_values[1],g_values[2]存放3个高斯混合模型的变量
//g_values[].weight(权重) g_values[].mean[](均值) g_values[].variance[](方差)
//具体安排是每一个象素点都有3个模型,
//然后每一个象素点的三个模型
//模型0的权重为1,方差为2倍的标准差的平方,均值为当前象素点的值
//模型1的权重为0,方差为2倍的标准差的平方,均值为0
//模型2的权重为0,方差为2倍的标准差的平方,均值为0
//g_point指的是参加高斯背景建模的象素点的个数
for( i = 0, p = 0, n = 0; i < first_frame->height; i++ )
{
for( j = 0; j < first_frame->width; j++, n++ )
{
bg_model->g_point[n].g_values =
bg_model->g_point[0].g_values + n*params.n_gauss;
bg_model->g_point[n].g_values[0].weight = 1; //the first value seen has weight one
bg_model->g_point[n].g_values[0].match_sum = 1;
for( m = 0; m < first_frame->nChannels; m++)
{
bg_model->g_point[n].g_values[0].variance[m] = var_init;
bg_model->g_point[n].g_values[0].mean[m] = (unsigned char)first_frame->imageData[p + m];
}
for( k = 1; k < params.n_gauss; k++)
{
bg_model->g_point[n].g_values[k].weight = 0;
bg_model->g_point[n].g_values[k].match_sum = 0;
for( m = 0; m < first_frame->nChannels; m++){
bg_model->g_point[n].g_values[k].variance[m] = var_init;
bg_model->g_point[n].g_values[k].mean[m] = 0;
}
}
p += first_frame->nChannels;
}
}
bg_model->countFrames = 0;
__END__;
if( cvGetErrStatus() < 0 )
{
CvBGStatModel* base_ptr = (CvBGStatModel*)bg_model;
if( bg_model && bg_model->release )
bg_model->release( &base_ptr );
else
cvFree( &bg_model );
bg_model = 0;
}
return (CvBGStatModel*)bg_model;
}
这整个函数就是对结构体cvGaussBGModel里面的参数:CV_BG_STAT_MODEL_FIELDS(),params,g_point,countFrames赋值,实际上也是可以把其复制过来,自己修改初时的参数。
高斯背景模型
运动检测的一般方法
目前,运动物体检测的问题主要分为两类,摄像机固定和摄像机运动。对于摄像机运动的运动物体检测问题,比较著名的解决方案是光流法,通过求解偏微分方程求 的图像序列的光流场,从而预测摄像机的运动状态。对于摄像机固定的情形,当然也可以用光流法,但是由于光流法的复杂性,往往难以实时的计算,所以我采用高 斯背景模型。因为,在摄像机固定的情况下,背景的变化是缓慢的,而且大都是光照,风等等的影响,通过对背景建模,对一幅给定图像分离前景和背景,一般来 说,前景就是运动物体,从而达到运动物体检测的目的。
单分布高斯背景模型
单分布高斯背景模型认为,对一个背景图像,特定像素亮度的分布满足高斯分布,即对背景图像B,(x,y)点的亮度满足:
IB(x,y) ~ N(u,d)
这样我们的背景模型的每个象素属性包括两个参数:平均值u 和 方差d。
对于一幅给定的图像G,如果 Exp(-(IG(x,y)-u(x,y))^2/(2*d^2)) > T,认为(x,y)是背景点,反之是前景点。
同时,随着时间的变化,背景图像也会发生缓慢的变化,这时我们要不断更新每个象素点的参数
u(t+1,x,y) = a*u(t,x,y) + (1-a)*I(x,y)
这里,a称为更新参数,表示背景变化的速度,一般情况下,我们不更新d(实验中发现更不更新d,效果变化不大)。
目标跟踪之高斯混合模型---cv实现的更多相关文章
- GMM+Kalman Filter+Blob 目标跟踪
转 http://www.cnblogs.com/YangQiaoblog/p/5462453.html ==========图片版================================== ...
- 高斯混合模型(GMM) - 混合高斯回归(GMR)
http://www.zhihuishi.com/source/2073.html 高斯模型就是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲 ...
- 高斯混合模型(理论+opencv实现)
查资料的时候看了一个不文明的事情,转载别人的东西而不标注出处,结果原创无人知晓,转载很多人评论~~标注了转载而不说出处这样的人有点可耻! 写在前面: Gaussian Mixture Model (G ...
- 目标跟踪之ECO:Efficient Convolution Operators for Tracking
一. 相关滤波算法总结 作者首先分析了 影响相关滤波算法效率 和 导致过拟合 的几个原因: 1)Model Size (模型大小) 包括两个方面: - 模型层数,对应多分辨率 Sample,比如多层 ...
- 目标跟踪之粒子滤波---Opencv实现粒子滤波算法
目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方 ...
- 高斯混合模型(GMM)
复习: 1.概率密度函数,密度函数,概率分布函数和累计分布函数 概率密度函数一般以大写“PDF”(Probability Density Function),也称概率分布函数,有的时候又简称概率分布函 ...
- KCF目标跟踪方法分析与总结
KCF目标跟踪方法分析与总结 correlation filter Kernelized correlation filter tracking 读"J. F. Henriques, R. ...
- GMM高斯混合模型学习笔记(EM算法求解)
提出混合模型主要是为了能更好地近似一些较复杂的样本分布,通过不断添加component个数,能够随意地逼近不论什么连续的概率分布.所以我们觉得不论什么样本分布都能够用混合模型来建模.由于高斯函数具有一 ...
- 高斯混合模型的EM算法
高斯混合模型的EM算法 混合高斯模型 高斯混合模型的概率分布可以写成多个高斯分布的线形叠加,即 \[ p(\mathbf x) = \sum_{k=1}^{K}\pi_k\mathcal N(\mat ...
随机推荐
- Linux基础学习-通过VM安装RHEL7.4
虚拟机安装RHEL7.4 1.VM虚拟机设置 这里我们配置的虚拟机为1核1G,50G硬盘,NAT模式 2.Linux安装 这里时区我们选择中国上海,时间需要调整一下相差8小时. 这里添加一下中文语言支 ...
- (二十三)Python 3 文件操作
文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 打开文件的模式有三种: 只读模式(默认) 只写模式(不可读,不存在则创建,存在则覆盖) 追加模式(可读,不存在则 ...
- Nginx的启动过程
主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: View Code Ngin ...
- 大数据学习——mapreduce程序单词统计
项目结构 pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...
- 学渣乱搞系列之扩展KMP的那点事
扩展KMP牵涉了一些相对运动的姿势,比较费解!本学渣看了一天的扩展KMP,打算写点东西...本文看后,出现的后果本人一概不负责.毕竟我不是很会表达. 扩展KMP是搞什么灰机的?本学渣所知道的扩展KMP ...
- nginx1.6.3
Nginx1.6.3安装配置 安装时关闭防火墙和selinuxservice iptables stopsed -i "s/selinux=enabled/selinux=disable/g ...
- cp: omitting directory解决方案
cp: omitting directory是因为目录下面还有目录.应该使用递归方法.需要加入-r参数. 及:cp -r 该目录名.
- mappedBy的具体使用及其含义
mappedBy: 1>只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性: 2>mappedBy标签一定是定义在被拥 ...
- 【HDOJ6319】Ascending Rating(单调队列)
题意: 思路: 倒着来是因为这样可以维护每一个当过最大值的数,而正着不行 #include<cstdio> #include<cstring> #include<stri ...
- 【POJ1185】炮兵阵地(状压DP)
题意: 思路:状压DP经典题 可以预处理下每一行内合法的状态,发现很少 所以转移时可以使用状态的编号而不是状态本身 DP时记录前两行状态的编号进行转移和判断 #include<cstdio> ...