opencv车流量统计算法
- #include "cv.h"
- #include <cxcore.h>
- #include <highgui.h>
- #include <cvaux.h>//必须引此头文件
- #include "opencv2/imgproc/imgproc.hpp"
- typedef uchar byte;
- #define QUEUE_MAX_SIZE 100
- #define RANGE 5
- #define UPDATE_RATE (0.01)
- #define RATIO_QUEUE_LEN 1000
- typedef unsigned int uint32;
- #define MIN(x,y) (x>y?y:x)
- int g_QueueSize=;
- int threshold=;
- int g_CarWidth=;//车的宽和高
- int g_CarHeight=;
- int g_CarArea=;//检测的范围
- int g_Erosion_kernel_size=;
- int g_Dilation_kernel_size=;
- struct PIXEL_RECORD
- {
- byte PX_data;
- uint32 PX_count;
- };
- struct QUEUE
- {
- struct RECORD
- {
- double ratio;
- uint64 count;
- }record [RATIO_QUEUE_LEN];
- int curPos;
- double MostRatio;
- };
- struct RECORD
- {
- PIXEL_RECORD queue[QUEUE_MAX_SIZE];
- uint32 CurPos;//the postion of last element in queue;
- };
- void QUEUE_init(QUEUE* queue)
- {
- for (int i=;i<RATIO_QUEUE_LEN;i++)
- {
- queue->record[i].ratio=0.0;
- queue->record[i].count=;
- }
- queue->curPos=;
- queue->MostRatio=0.0;
- }
- double UpatePixelRatio(QUEUE& queue,double ratio)
- {
- int i=;
- int MinPos=;
- int MaxPos=;
- for (;i<RATIO_QUEUE_LEN;i++)
- {
- if(queue.record[i].ratio == ratio)
- {
- queue.record[i].count++;
- break;
- }
- }
- if (i==RATIO_QUEUE_LEN)
- {
- if(queue.curPos<RATIO_QUEUE_LEN)
- {
- queue.record[queue.curPos++].ratio=ratio;
- }
- if(queue.curPos== RATIO_QUEUE_LEN)
- {
- uint32 MinCount=0xFFFFFFFF;
- for(int j=;j<queue.curPos;j++)
- {
- if(queue.record[j].count<MinCount)
- {
- MinPos=j;
- MinCount=queue.record[j].count;
- }
- }
- queue.record[MinPos].ratio=ratio;
- }
- }
- uint32 MaxCount=;
- for (int j=;j<RATIO_QUEUE_LEN;j++)
- {
- if (queue.record[j].count>MaxCount)
- {
- MaxCount=queue.record[j].count;
- MaxPos=j;
- }
- }
- return queue.record[MaxPos].ratio;
- }
- uint32 GetMaxValueData(const PIXEL_RECORD* arr,int len)
- {
- uint32 tmp=;
- uint32 MaxPos=;
- for (int i=;i<len-;i++)
- {
- if(arr[i].PX_count>tmp)
- {
- tmp=arr[i].PX_count;
- MaxPos=i;
- }
- }
- return arr[MaxPos].PX_data;
- }
- uint32 GetMinValuePos(const PIXEL_RECORD* arr,int len)
- {
- byte tmp=;
- uint32 MinPos=g_QueueSize;
- for (int i=;i<len-;i++)
- {
- if(arr[i].PX_count<tmp)
- {
- tmp=arr[i].PX_count;
- MinPos=i;
- }
- }
- return MinPos;
- }
- byte UpdateQueue(RECORD* record,byte Vpixel,uint32 nFrm)
- {
- PIXEL_RECORD tmp;
- int i=;
- double UpdateRate;
- for (;i<g_QueueSize;i++)
- {
- if ((record->queue[i].PX_data)/RANGE == Vpixel/RANGE )
- {
- record->queue[i].PX_count++;
- record->queue[i].PX_data=(record->queue[i].PX_data)*(-UPDATE_RATE)+Vpixel*UPDATE_RATE;
- }
- }
- if (i==g_QueueSize)
- {
- if (record->CurPos < g_QueueSize)
- {
- record->queue[record->CurPos++].PX_data=Vpixel;
- }
- else
- {
- uint32 Pos=GetMinValuePos(record->queue,record->CurPos);
- record->queue[Pos].PX_data=Vpixel;
- }
- }
- return GetMaxValueData(record->queue,record->CurPos);
- }
- void RecordFrame(IplImage* pFrame,IplImage* pBKImg ,const int nFrm,RECORD* pRecordMap,QUEUE& PX_queue)
- {
- IplImage* pFrmGrayImg=NULL;
- pFrmGrayImg=cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
- if(pFrame->colorModel != CV_8U && pFrame->nChannels != )
- {
- cvCvtColor(pFrame,pFrmGrayImg,CV_BGR2GRAY);
- }
- else
- pFrmGrayImg=pFrame;
- uint32 ROW=pFrmGrayImg->width;
- uint32 COL=pFrmGrayImg->height;
- for (uint32 i=;i<ROW*COL;i++)
- {
- pBKImg->imageData[i]=UpdateQueue(pRecordMap+i,pFrmGrayImg->imageData[i], nFrm);
- }
- }
- void TouchTag(int* buf,int ROW,int COL,int& ctag,int x,int y)
- {
- int tag=ctag;
- bool mark=;
- for (int i=-;i<;i++)
- {
- for (int j=-;j<;j++)
- {
- if (buf[(x+i)*COL+(y+j)]>)
- {
- tag= MIN(buf[(x+i)*COL+(y+j)],tag);
- mark=;
- }
- }
- }
- if(mark==)
- {
- ctag++;
- tag=ctag;
- }
- buf[x*COL+y]=tag;
- }
- size_t DetectRect(CvMat* Img,int* buf)
- {
- uint32 ROW=Img->rows;
- uint32 COL=Img->cols;
- int cTag=;
- for (int i=;i<ROW -;i++)//! 图像中的横轴为X轴,即为列坐标
- {
- for (int j=;j<COL-;j++)
- {
- if(*(byte*)(CV_MAT_ELEM_PTR(*Img,i,j)) == )
- {
- TouchTag(buf,ROW,COL,cTag,i,j);
- }
- }
- }
- return cTag;
- }
- struct TAG_RECORD
- {
- uint32 MinX;
- uint32 MaxX;
- uint32 MinY;
- uint32 MaxY;
- uint32 count;
- };
- void GetRect(std::vector<TAG_RECORD>& TagArry,size_t cTag,int* buf,uint32 ROW,uint32 COL)
- {
- for (size_t i=;i<TagArry.size();i++)
- {
- TagArry[i].MaxX=;
- TagArry[i].MaxY=;
- TagArry[i].MinX=COL;
- TagArry[i].MinY=ROW;
- TagArry[i].count=;
- }
- int index=;
- for (int i=;i<ROW;i++)
- {
- for (int j=;j<COL;j++)
- {
- index=buf[i*COL+j];
- if (index> && index<TagArry.size())
- {
- TagArry[index].count++;
- if (i<TagArry[index].MinY)
- {
- TagArry[index].MinY=i;
- }
- if(i>TagArry[index].MaxY)
- {
- TagArry[index].MaxY=i;
- }
- if (j<TagArry[index].MinX)
- {
- TagArry[index].MinX=j;
- }
- if (j>TagArry[index].MaxX)
- {
- TagArry[index].MaxX=j;
- }
- }
- }
- }
- }
- void onTrackbarSlide(int)
- {
- }
- int main()
- {
- //声明IplImage指针
- IplImage* pFrame = NULL;
- IplImage* pFrImg = NULL;
- IplImage* pBkImg = NULL;
- CvMat* pDiff =NULL;
- CvMat* pFrameMat = NULL;
- CvMat* pFrMat = NULL;
- CvMat* pBkMat = NULL;
- RECORD* pRecordMap=NULL;
- int* TagMap=NULL;
- CvCapture* pCapture = NULL;
- CvRect FrRect;
- int nFrmNum = ;
- int ncount=;
- QUEUE PX_queue;
- size_t RecordSize;
- int ROW;
- int COL;
- //! 文字输出
- CvFont font;
- char str[]="flow:";
- double hscale = 0.6;
- double vscale = 0.6;
- int linewidth = ;
- double flow;
- char ncar[]="cars:";
- char nframe[]="frames:";
- char sframeRate[]="[FPS]:";
- //创建窗口
- cvNamedWindow("video", );
- cvNamedWindow("background",);
- cvNamedWindow("foreground",);
- //使窗口有序排列
- cvMoveWindow("video", , );
- cvMoveWindow("background", , );
- cvMoveWindow("foreground", , );
- char* filename="d:\\test.mp4";
- //打开视频文件
- if( !(pCapture = cvCaptureFromFile(filename)))
- {
- fprintf(stderr, "Can not open video file %s\n", filename);
- return -;
- }
- QUEUE_init(&PX_queue);
- double framesRate=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FPS);
- int frames=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_COUNT);
- cvCreateTrackbar("QueueSize","background", &g_QueueSize, QUEUE_MAX_SIZE,onTrackbarSlide);
- cvCreateTrackbar("CarWiedth","video", &g_CarWidth, ,onTrackbarSlide);
- cvCreateTrackbar("CarHeight","video", &g_CarHeight, ,onTrackbarSlide);
- cvCreateTrackbar("CarArea","video", &g_CarArea, ,onTrackbarSlide);
- cvCreateTrackbar("Threshold","foreground", &threshold, ,onTrackbarSlide);
- cvCreateTrackbar("dilate","foreground", &g_Dilation_kernel_size, ,onTrackbarSlide);
- cvCreateTrackbar("erode","foreground", &g_Erosion_kernel_size, ,onTrackbarSlide);
- //逐帧读取视频
- while(pFrame = cvQueryFrame( pCapture ))
- {
- nFrmNum++;
- //如果是第一帧,需要申请内存,并初始化
- if(nFrmNum == )
- {
- pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
- pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
- pDiff =cvCreateMat(pFrame->height, pFrame->width, CV_8U);
- pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- ROW=pDiff->rows;
- COL=pDiff->cols;
- //转化成单通道图像再处理
- cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
- RecordSize=pFrame->width * pFrame->height;
- pRecordMap=new RECORD[RecordSize];
- TagMap=new int[RecordSize];
- for (int i=;i<RecordSize;i++) //init
- {
- for (int j=;j<g_QueueSize;j++)
- {
- pRecordMap[i].queue[j].PX_count=;
- pRecordMap[i].queue[j].PX_data=;
- pRecordMap[i].CurPos=;
- }
- }
- cvConvert(pFrImg, pFrameMat);
- cvConvert(pBkImg, pBkMat);
- }
- else
- {
- cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
- cvSmooth(pFrImg, pFrImg, CV_GAUSSIAN, , , );
- RecordFrame(pFrImg,pBkImg,nFrmNum,pRecordMap,PX_queue);
- //高斯滤波先,以平滑图像
- cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, , , );
- //当前帧跟背景图相减
- cvAbsDiff(pFrImg, pBkImg, pDiff);
- //二值化前景图
- cvThreshold(pDiff, pDiff, threshold, , CV_THRESH_BINARY);
- //进行形态学滤波,去掉噪音
- IplConvKernel* element_erode=cvCreateStructuringElementEx(g_Erosion_kernel_size + , g_Erosion_kernel_size+,
- g_Erosion_kernel_size/, g_Erosion_kernel_size/, );
- IplConvKernel* element_dilate = cvCreateStructuringElementEx(g_Dilation_kernel_size + , g_Dilation_kernel_size+,
- g_Dilation_kernel_size/, g_Dilation_kernel_size/, );
- //! 腐蚀操作
- cvErode( pDiff, pDiff, element_erode );
- /// 膨胀操作
- cvDilate( pDiff, pDiff, element_dilate );
- // cvErode(pDiff, pDiff, 0, 1);
- // cvDilate(pDiff, pDiff, 0, 1);
- //
- for (int i=;i<RecordSize;i++)
- {
- TagMap[i]=;
- }
- size_t cTag=DetectRect(pDiff,TagMap);
- TAG_RECORD tmp;
- tmp.MinX=pDiff->cols;
- tmp.MinY=pDiff->rows;
- tmp.MaxX=;
- tmp.MaxY=;
- std::vector<TAG_RECORD> TagRecord(cTag+,tmp);
- GetRect(TagRecord,cTag,TagMap,pDiff->rows,pDiff->cols);
- ncount=;
- for (size_t i=;i<TagRecord.size();i++)
- {
- if (TagRecord[i].count<g_CarArea)
- {
- continue;
- }
- int MinX=TagRecord[i].MinX;
- int MinY=TagRecord[i].MinY;
- int MaxX=TagRecord[i].MaxX;
- int MaxY=TagRecord[i].MaxY;
- if (MaxX-MinX<g_CarWidth || MaxY-MinY<g_CarHeight)
- {
- continue;
- }
- ncount++;
- cvRectangle( pFrame, cvPoint(MinX,MinY), cvPoint(MaxX,MaxY), CV_RGB(,,), , , );
- }
- flow=framesRate*ncount/(double)nFrmNum;
- sprintf(nframe+,"%d",nFrmNum);
- sprintf(ncar+,"%d",ncount);
- sprintf(str+,"%f",flow);
- sprintf(sframeRate+,"%f",framesRate);
- cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,hscale,vscale,,linewidth);
- cvPutText(pFrame,sframeRate,cvPoint(,),&font,cvScalar(,,));
- cvPutText(pFrame,ncar,cvPoint(,),&font,cvScalar(,,));
- cvPutText(pFrame,nframe,cvPoint(,),&font,cvScalar(,,));
- cvPutText(pFrame,str,cvPoint(,),&font,cvScalar(,,));
- //显示图像
- cvShowImage("video", pFrame);
- cvShowImage("background", pBkImg);
- cvShowImage("foreground", pDiff);
- //如果有按键事件,则跳出循环
- //此等待也为cvShowImage函数提供时间完成显示
- //等待时间可以根据CPU速度调整
- if( cvWaitKey() >= )
- break;
- }
- }
- cvWaitKey();
- //销毁窗口
- cvDestroyWindow("video");
- cvDestroyWindow("background");
- cvDestroyWindow("foreground");
- //释放图像和矩阵
- cvReleaseImage(&pFrImg);
- cvReleaseImage(&pBkImg);
- cvReleaseMat(&pFrameMat);
- cvReleaseMat(&pFrMat);
- cvReleaseMat(&pBkMat);
- cvReleaseCapture(&pCapture);
- delete[] pRecordMap;
- delete[] TagMap;
- return ;
- }
opencv车流量统计算法的更多相关文章
- 基于OpenCV的KNN算法实现手写数字识别
基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...
- OpenCV实现KNN算法
原文 OpenCV实现KNN算法 K Nearest Neighbors 这个算法首先贮藏所有的训练样本,然后通过分析(包括选举,计算加权和等方式)一个新样本周围K个最近邻以给出该样本的相应值.这种方 ...
- java 在centos6.5+eclipse环境下调用opencv实现sift算法
java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core ...
- 基于FPGA的HDTV视频图像灰度直方图统计算法设计
随着HDTV的普及,以LCD-TV为主的高清数字电视逐渐进入蓬勃发展时期.与传统CRT电视不同的是,这些高清数字电视需要较复杂的视频处理电路来驱动,比如:模数转换(A/D Converter).去隔行 ...
- OPENCV下SIFT算法使用方法笔记
这几天继续在看Lowe大神的SIFT神作,看的眼花手脚抽筋.也是醉了!!!!实在看不下去,来点干货.我们知道opencv下自带SIFT特征检测以及MATCH匹配的库,这些库完全可以让我们进行傻瓜似的操 ...
- 用OpenCV实现Photoshop算法(三): 曲线调整
http://blog.csdn.net/c80486/article/details/52499919 系列文章: 用OpenCV实现Photoshop算法(一): 图像旋转 用OpenCV实现Ph ...
- OpenCV中Camshitf算法学习(补充)
结合OpenCV中Camshitf算法学习,做一些简单的补充,包括: 实现全自动跟随的一种方法 参考opencv中的相关demo,可以截取目标物体的图片,由此预先计算出其色彩投影图,用于实际的目标跟随 ...
- SEO 统计算法
1)简单粗暴型的,这里不用去管浏览器的user-agent,不管cookie等信息,每产生一次PV,就直接计数,优点:简单,缺点:可能不真实,也可能有刷量数据 2) 稍微细腻点的统计,会区分新老用户, ...
- OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)
原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...
随机推荐
- Git 重命名操作
截至目前,Tome 和Jerry 都使用手动命令来编译自己的项目.Jerry 决定为他们的项目创建 Makefile,并给予适当的名称来命名“string.c” 文件. [jerry@CentOS p ...
- [Angularjs] 第一步开始一个项目
[Angularjs] 第一步开始一个项目 一.什么是angularjs angularjs是2009年兴起的,目前由Google维护一个采用mvc模式的js框架,很多时候用来创建单页面应用.我也经常 ...
- MSP MCU I2C入门指南
这是一份介绍性指南,指导你如何用超低功耗MSP微控制器 (MCU) 开始一个与I2C通信有关的项目: 简介 I2C(或称为I2C,集成电路总线)是一种两线制通信形式,主要用来在短距离.电路板间的应用中 ...
- 零基础 Vue 开发环境搭建 打开运行Vue项目
[相关推荐]IntellIJ IDEA 配置 Vue 支持 打开Vue项目 所需文件 node.js环境(npm包管理器)(node-v8.11.3-x64.msi)(npmV5.6.0) cnpm ...
- 8 -- 深入使用Spring -- 6...2 Spring支持的事务策略
8.6.2 使用XML Schema配置事务策略 Spring 同时支持编程式事务策略和声明式事务策略,通常都推荐采用声明式事务策略. ⊙ 声明式事务能大大降低开发者的代码书写量,而且声明式事务几乎不 ...
- linux-Centos 7下bond与vlan技术的结合
服务器eno1与eno2作bonding,捆绑成bond0接口,服务器对端交换机端口,同属于301.302号vlan接口 vlan 301: 10.1.2.65/27 ...
- c++中map按key和value排序
``` #include<iostream> #include<algorithm> #include<vector> #include<map> #i ...
- 新装的MySQL没有密码怎么办
新装的mysql没有密码怎么办 [root@localhost log]# mysql -u root -p Enter password: Welcome to the MySQL monitor. ...
- iPhone XS 能否经受的起寒冬的考验
我的知乎文章链接: https://zhuanlan.zhihu.com/p/51782644 华北地区近日寒风凛冽,温度骤降,已经进入真正的冬天了,最低温度可以达到零下10度,我们手里的iPhone ...
- 单目三维稠密重建方案:Quadtree-accelerated Real-time Monocular Dense Mapping
论文:This is a monocular dense mapping system following the IEEE Robotics and Automation Letters (RA-L ...