自己写的运动目标检测算法汇总

  • t1_446296
    了解作者
  • 15.8KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-06 10:01
    上传日期
压缩包里共包含4种最常用的运动目标检测算法:混合高斯模型 相邻帧差法 运行期均值法 自适应阈值的三帧差分法 ;全部是自己总结和写的,绝对可以运行。
运动目标检测算法研究总结.rar
  • 运动目标检测算法研究总结
  • 相邻帧差法
  • 相邻帧差法提取运动目标并计时.cpp
    2.7KB
  • 相邻帧差法提取运动目标.cpp
    2.5KB
  • 运行期均值法
  • 运行期均值提取运动目标.cpp
    2.2KB
  • IplImage+CvMat运行期均值法在视频中提取运动目标已添加注释.cpp
    6.3KB
  • 运行期均值法已添加注释.cpp
    6.3KB
  • 自适应阈值的三帧差分法
  • IplImage三帧差1.cpp
    4.6KB
  • Mat 三帧差2.cpp
    2.2KB
  • 自己改写的IplImage三帧差分法阈值需手动设定.cpp
    4.7KB
  • 混合高斯模型
  • 1 混合高斯模型提取运动区域.cpp
    1.8KB
内容介绍
//本文利用的是运行期均值的方法,学习率为0.003,以第一帧为背景帧,该方法只适合于背景相对简单的环境, //本文中对光流的计算是出于什么目的,完全没有作用 //人体相对不完整,框出的区域可能会偏小,一个人可能会框出多个区域,减小阈值会导致光噪声严重,该方法适合吗??? #include <stdio.h> #include "opencv/cv.h" #include "opencv2/highgui/highgui.hpp" #include "opencv2/legacy/legacy.hpp" //必须引此头文件,否则 cvCalcOpticalFlowHS找不到标示符 int main( int argc, char** argv ) { IplImage *eig = 0, *temp = 0; static float lamba = 20; int usePrevious = 1; CvTermCriteria criteria; //结构体含3个变量( int type;double epsilon; int max_iter;)迭代算法的终止准则 criteria.epsilon = 0.001f;/* 结果的精确性 */ criteria.max_iter = 3;/* 最大迭代次数 */ criteria.type = CV_TERMCRIT_EPS | CV_TERMCRIT_ITER; //equre=2|1=3?; //声明IplImage指针 IplImage* pFrame = NULL; IplImage* pFrImg = NULL; IplImage* pBkImg = NULL; CvMat* pFrameMat = NULL; CvMat* pFrMat = NULL; CvMat* pBkMat = NULL; CvCapture* pCapture = NULL; int nFrmNum = 0; //创建窗口 cvNamedWindow("video", 1); cvNamedWindow("background",1); cvNamedWindow("foreground",1); //cvNamedWindow("eig--x",1); // cvNamedWindow("temp--y",1); //设定窗口在电脑屏幕的位置,防止窗口相互重叠 cvMoveWindow("video", 30, 0); cvMoveWindow("background", 360, 0); cvMoveWindow("foreground", 690, 0); // cvMoveWindow("eig--x",360,300); // cvMoveWindow("temp--y",690,300); // if( argc != 2 ) //{ //fprintf(stderr, "Usage: bkgrd <video_file_name>\n"); // return -1; // } //打开视频文件 if( !(pCapture = cvCreateFileCapture("E:\\11.avi"))) { fprintf(stderr, "Can not open video file %s\n", "E:\\11.avi"); system("pause"); exit(-2); } //逐帧读取视频 while(pFrame = cvQueryFrame( pCapture )) { nFrmNum++; //如果是第一帧,需要申请内存,并初始化,不显示 if(nFrmNum == 1) { //创建头并分配数据。size 图像宽、高。IPL_DEPTH_8U - 无符号8位整型。每个元素(像素)通道数是1。 pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1); pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1); //创建矩阵。CvMat* cvCreateMat( int rows, int cols, int type ) //矩阵的元素是32位浮点型数据(CV_32FC1)。 pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1); eig = cvCreateImage( cvGetSize(pBkImg), 32, 1 ); temp = cvCreateImage( cvGetSize(pBkImg), 32, 1 ); //转化成单通道图像再处理 //cvCvtColor(...)颜色空间转换函数,参数CV_BGR2GRAY是RGB到gray,表示转换为灰度图 cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY); cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); //cvConvert函数用于图像和矩阵之间的相互转换 //IplImage里的数据只能用uchar的形式存放,当需要这些图像数据看作数据矩阵来运算时,0~255的精度显然满足不了要求; //然而CvMat里却可以存放任意通道数、任意格式的数据,这个机制方便了研究中的这种需求,转化为矩阵就可以进行更自由的计算。 cvConvert(pFrImg, pFrameMat); cvConvert(pFrImg, pFrMat); cvConvert(pBkImg, pBkMat); } else { cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); cvConvert(pFrImg, pFrameMat);//必须先创建好适当大小的内存cvCreateMat,然后才能转换 //先做高斯滤波,以平滑图像,如用于进行人体检测是否去掉高斯滤波需要做实验决定 cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0); //当前帧跟背景图相减 cvAbsDiff(pFrameMat, pBkMat, pFrMat); //把两幅图的差的绝对值输出到另一幅图上面来 //二值化前景图 //函数 cvThreshold 对单通道数组应用固定阈值操作,该函数的典型应用是对灰度图像进行阈值操作得到二值图像。 //阈值为60,,使用CV_THRESH_BINARY的最大值为255,阈值类型为CV_THRESH_BINARY cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY); //进行形态学滤波,去掉噪音 cvDilate(pFrImg, pFrImg, 0, 1); //膨胀 cvErode(pFrImg, pFrImg, 0, 1); //腐蚀 //cvErode()腐蚀后cvDilate()膨胀,叫作开操作,那些离散点或游丝线、毛刺就被过滤 // cvDilate()膨胀后cvErode()腐蚀,叫作闭操作,那些断裂处就被缝合。 //更新背景 cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);//pBkMat=pFrameMat*0.003+pBkMat*(1-0.003)http://blog.csdn.net/wanglp094/article/details/7646571 //将背景转化为图像格式,用以显示 cvConvert(pBkMat, pBkImg); //下面计算图像光流的函数有什么用???!去掉对结果没影响 cvCalcOpticalFlowHS(pBkImg,pFrImg,1,eig,temp,lamba,criteria); //光流计算函数,为输入图像的每一个象素计算光流 /*void cvCalcOpticalFlowHS( const CvArr* prev, const CvArr* curr, int use_previous, CvArr* velx, CvArr* vely, double lambda, CvTermCriteria criteria ); prev 第一幅图像, 8-比特, 单通道. curr 第二幅图像, 8-比特, 单通道. use_previous 使用以前的 (输入) 速度域 velx 光流的水平部分,与输入图像大小一样, 32-比特,浮点数, 单通道. vely 光流的垂直部分,与输入图像大小一样, 32-比特, 浮点数, 单通道. lambda Lagrangian 乘子 criteria 速度计算的终止条件*/ //把图像正过来 pBkImg->origin=1; pFrImg->origin=1; cvFlip(pBkImg,pBkImg,0); cvFlip(pFrImg,pFrImg,0); //显示图像 cvShowImage("video", pFrame); cvShowImage("background", pBkImg); cvShowImage("foreground", pFrImg); // cvFlip(eig,eig,0); // cvFlip(temp,temp,0); //cvShowImage("eig--x",eig); //cvShowImage("temp--y",temp); //如果有按键事件,则跳出循环 //此等待也为cvShowImage函数提供时间完成显示 //等待时间可以根据CPU速度调整 if( cvWaitKey(33) >= 0 )//按任意键退出 break; if(nFrmNum == 59) cvWaitKey(-1); } // end of if-else } // end of while-loop //销毁窗口 cvDestroyWindow("video"); cvDestroyWindow("background"); cvDestroyWindow("foreground"); //cvDestroyWindow("eig--x"); //cvDestroyWindow("temp--y"); //释放图像和矩阵 cvReleaseImage(&pFrImg); cvReleaseImage(&pBkImg); cvReleaseImage(&eig); cvReleaseImage(&temp); cvReleaseMat(&pFrameMat); cvReleaseMat(&pFrMat); cvReleaseMat(&pBkMat); return 0; }
评论
    相关推荐