1. #include "cv.h"
  2. #include <cxcore.h>
  3. #include <highgui.h>
  4. #include <cvaux.h>//必须引此头文件
  5. #include "opencv2/imgproc/imgproc.hpp"
  6. typedef uchar byte;
  7. #define QUEUE_MAX_SIZE 100
  8. #define RANGE 5
  9. #define UPDATE_RATE (0.01)
  10. #define RATIO_QUEUE_LEN 1000
  11. typedef unsigned int uint32;
  12. #define MIN(x,y) (x>y?y:x)
  13.  
  14. int g_QueueSize=;
  15. int threshold=;
  16. int g_CarWidth=;//车的宽和高
  17. int g_CarHeight=;
  18. int g_CarArea=;//检测的范围
  19. int g_Erosion_kernel_size=;
  20. int g_Dilation_kernel_size=;
  21. struct PIXEL_RECORD
  22. {
  23. byte PX_data;
  24. uint32 PX_count;
  25. };
  26.  
  27. struct QUEUE
  28. {
  29. struct RECORD
  30. {
  31. double ratio;
  32. uint64 count;
  33. }record [RATIO_QUEUE_LEN];
  34.  
  35. int curPos;
  36. double MostRatio;
  37.  
  38. };
  39. struct RECORD
  40. {
  41. PIXEL_RECORD queue[QUEUE_MAX_SIZE];
  42. uint32 CurPos;//the postion of last element in queue;
  43.  
  44. };
  45.  
  46. void QUEUE_init(QUEUE* queue)
  47. {
  48. for (int i=;i<RATIO_QUEUE_LEN;i++)
  49. {
  50. queue->record[i].ratio=0.0;
  51. queue->record[i].count=;
  52.  
  53. }
  54. queue->curPos=;
  55. queue->MostRatio=0.0;
  56. }
  57. double UpatePixelRatio(QUEUE& queue,double ratio)
  58. {
  59.  
  60. int i=;
  61. int MinPos=;
  62. int MaxPos=;
  63. for (;i<RATIO_QUEUE_LEN;i++)
  64. {
  65. if(queue.record[i].ratio == ratio)
  66. {
  67. queue.record[i].count++;
  68. break;
  69. }
  70.  
  71. }
  72. if (i==RATIO_QUEUE_LEN)
  73. {
  74. if(queue.curPos<RATIO_QUEUE_LEN)
  75. {
  76. queue.record[queue.curPos++].ratio=ratio;
  77. }
  78. if(queue.curPos== RATIO_QUEUE_LEN)
  79. {
  80. uint32 MinCount=0xFFFFFFFF;
  81. for(int j=;j<queue.curPos;j++)
  82. {
  83. if(queue.record[j].count<MinCount)
  84. {
  85. MinPos=j;
  86. MinCount=queue.record[j].count;
  87. }
  88. }
  89. queue.record[MinPos].ratio=ratio;
  90. }
  91. }
  92. uint32 MaxCount=;
  93. for (int j=;j<RATIO_QUEUE_LEN;j++)
  94. {
  95. if (queue.record[j].count>MaxCount)
  96. {
  97. MaxCount=queue.record[j].count;
  98. MaxPos=j;
  99. }
  100. }
  101. return queue.record[MaxPos].ratio;
  102. }
  103. uint32 GetMaxValueData(const PIXEL_RECORD* arr,int len)
  104. {
  105. uint32 tmp=;
  106. uint32 MaxPos=;
  107. for (int i=;i<len-;i++)
  108. {
  109. if(arr[i].PX_count>tmp)
  110. {
  111. tmp=arr[i].PX_count;
  112. MaxPos=i;
  113. }
  114. }
  115. return arr[MaxPos].PX_data;
  116. }
  117.  
  118. uint32 GetMinValuePos(const PIXEL_RECORD* arr,int len)
  119. {
  120. byte tmp=;
  121. uint32 MinPos=g_QueueSize;
  122. for (int i=;i<len-;i++)
  123. {
  124. if(arr[i].PX_count<tmp)
  125. {
  126. tmp=arr[i].PX_count;
  127. MinPos=i;
  128. }
  129. }
  130. return MinPos;
  131. }
  132.  
  133. byte UpdateQueue(RECORD* record,byte Vpixel,uint32 nFrm)
  134. {
  135. PIXEL_RECORD tmp;
  136. int i=;
  137. double UpdateRate;
  138. for (;i<g_QueueSize;i++)
  139. {
  140.  
  141. if ((record->queue[i].PX_data)/RANGE == Vpixel/RANGE )
  142. {
  143. record->queue[i].PX_count++;
  144. record->queue[i].PX_data=(record->queue[i].PX_data)*(-UPDATE_RATE)+Vpixel*UPDATE_RATE;
  145.  
  146. }
  147. }
  148. if (i==g_QueueSize)
  149. {
  150. if (record->CurPos < g_QueueSize)
  151. {
  152. record->queue[record->CurPos++].PX_data=Vpixel;
  153. }
  154. else
  155. {
  156. uint32 Pos=GetMinValuePos(record->queue,record->CurPos);
  157. record->queue[Pos].PX_data=Vpixel;
  158. }
  159.  
  160. }
  161. return GetMaxValueData(record->queue,record->CurPos);
  162. }
  163.  
  164. void RecordFrame(IplImage* pFrame,IplImage* pBKImg ,const int nFrm,RECORD* pRecordMap,QUEUE& PX_queue)
  165. {
  166. IplImage* pFrmGrayImg=NULL;
  167. pFrmGrayImg=cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
  168. if(pFrame->colorModel != CV_8U && pFrame->nChannels != )
  169. {
  170. cvCvtColor(pFrame,pFrmGrayImg,CV_BGR2GRAY);
  171. }
  172. else
  173. pFrmGrayImg=pFrame;
  174.  
  175. uint32 ROW=pFrmGrayImg->width;
  176. uint32 COL=pFrmGrayImg->height;
  177.  
  178. for (uint32 i=;i<ROW*COL;i++)
  179. {
  180. pBKImg->imageData[i]=UpdateQueue(pRecordMap+i,pFrmGrayImg->imageData[i], nFrm);
  181.  
  182. }
  183.  
  184. }
  185.  
  186. void TouchTag(int* buf,int ROW,int COL,int& ctag,int x,int y)
  187. {
  188. int tag=ctag;
  189. bool mark=;
  190. for (int i=-;i<;i++)
  191. {
  192.  
  193. for (int j=-;j<;j++)
  194. {
  195.  
  196. if (buf[(x+i)*COL+(y+j)]>)
  197. {
  198. tag= MIN(buf[(x+i)*COL+(y+j)],tag);
  199. mark=;
  200. }
  201. }
  202. }
  203. if(mark==)
  204. {
  205. ctag++;
  206. tag=ctag;
  207. }
  208. buf[x*COL+y]=tag;
  209. }
  210.  
  211. size_t DetectRect(CvMat* Img,int* buf)
  212. {
  213. uint32 ROW=Img->rows;
  214. uint32 COL=Img->cols;
  215. int cTag=;
  216. for (int i=;i<ROW -;i++)//! 图像中的横轴为X轴,即为列坐标
  217. {
  218. for (int j=;j<COL-;j++)
  219. {
  220. if(*(byte*)(CV_MAT_ELEM_PTR(*Img,i,j)) == )
  221. {
  222. TouchTag(buf,ROW,COL,cTag,i,j);
  223. }
  224. }
  225. }
  226.  
  227. return cTag;
  228. }
  229.  
  230. struct TAG_RECORD
  231. {
  232. uint32 MinX;
  233. uint32 MaxX;
  234. uint32 MinY;
  235. uint32 MaxY;
  236. uint32 count;
  237. };
  238. void GetRect(std::vector<TAG_RECORD>& TagArry,size_t cTag,int* buf,uint32 ROW,uint32 COL)
  239. {
  240. for (size_t i=;i<TagArry.size();i++)
  241. {
  242. TagArry[i].MaxX=;
  243. TagArry[i].MaxY=;
  244. TagArry[i].MinX=COL;
  245. TagArry[i].MinY=ROW;
  246. TagArry[i].count=;
  247. }
  248. int index=;
  249. for (int i=;i<ROW;i++)
  250. {
  251. for (int j=;j<COL;j++)
  252. {
  253. index=buf[i*COL+j];
  254. if (index> && index<TagArry.size())
  255. {
  256. TagArry[index].count++;
  257. if (i<TagArry[index].MinY)
  258. {
  259. TagArry[index].MinY=i;
  260. }
  261. if(i>TagArry[index].MaxY)
  262. {
  263. TagArry[index].MaxY=i;
  264. }
  265. if (j<TagArry[index].MinX)
  266. {
  267. TagArry[index].MinX=j;
  268. }
  269. if (j>TagArry[index].MaxX)
  270. {
  271. TagArry[index].MaxX=j;
  272. }
  273. }
  274.  
  275. }
  276. }
  277.  
  278. }
  279.  
  280. void onTrackbarSlide(int)
  281. {
  282.  
  283. }
  284. int main()
  285. {
  286.  
  287. //声明IplImage指针
  288. IplImage* pFrame = NULL;
  289. IplImage* pFrImg = NULL;
  290. IplImage* pBkImg = NULL;
  291. CvMat* pDiff =NULL;
  292. CvMat* pFrameMat = NULL;
  293. CvMat* pFrMat = NULL;
  294. CvMat* pBkMat = NULL;
  295. RECORD* pRecordMap=NULL;
  296. int* TagMap=NULL;
  297. CvCapture* pCapture = NULL;
  298. CvRect FrRect;
  299. int nFrmNum = ;
  300. int ncount=;
  301. QUEUE PX_queue;
  302. size_t RecordSize;
  303. int ROW;
  304. int COL;
  305. //! 文字输出
  306. CvFont font;
  307. char str[]="flow:";
  308. double hscale = 0.6;
  309. double vscale = 0.6;
  310. int linewidth = ;
  311. double flow;
  312. char ncar[]="cars:";
  313. char nframe[]="frames:";
  314. char sframeRate[]="[FPS]:";
  315. //创建窗口
  316. cvNamedWindow("video", );
  317. cvNamedWindow("background",);
  318. cvNamedWindow("foreground",);
  319. //使窗口有序排列
  320. cvMoveWindow("video", , );
  321. cvMoveWindow("background", , );
  322. cvMoveWindow("foreground", , );
  323.  
  324. char* filename="d:\\test.mp4";
  325. //打开视频文件
  326.  
  327. if( !(pCapture = cvCaptureFromFile(filename)))
  328. {
  329. fprintf(stderr, "Can not open video file %s\n", filename);
  330. return -;
  331. }
  332.  
  333. QUEUE_init(&PX_queue);
  334.  
  335. double framesRate=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FPS);
  336. int frames=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_COUNT);
  337.  
  338. cvCreateTrackbar("QueueSize","background", &g_QueueSize, QUEUE_MAX_SIZE,onTrackbarSlide);
  339. cvCreateTrackbar("CarWiedth","video", &g_CarWidth, ,onTrackbarSlide);
  340. cvCreateTrackbar("CarHeight","video", &g_CarHeight, ,onTrackbarSlide);
  341. cvCreateTrackbar("CarArea","video", &g_CarArea, ,onTrackbarSlide);
  342. cvCreateTrackbar("Threshold","foreground", &threshold, ,onTrackbarSlide);
  343. cvCreateTrackbar("dilate","foreground", &g_Dilation_kernel_size, ,onTrackbarSlide);
  344. cvCreateTrackbar("erode","foreground", &g_Erosion_kernel_size, ,onTrackbarSlide);
  345. //逐帧读取视频
  346. while(pFrame = cvQueryFrame( pCapture ))
  347. {
  348. nFrmNum++;
  349.  
  350. //如果是第一帧,需要申请内存,并初始化
  351. if(nFrmNum == )
  352. {
  353.  
  354. pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
  355. pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,);
  356. pDiff =cvCreateMat(pFrame->height, pFrame->width, CV_8U);
  357. pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  358. pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  359. pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  360. ROW=pDiff->rows;
  361. COL=pDiff->cols;
  362. //转化成单通道图像再处理
  363. cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  364. RecordSize=pFrame->width * pFrame->height;
  365. pRecordMap=new RECORD[RecordSize];
  366. TagMap=new int[RecordSize];
  367.  
  368. for (int i=;i<RecordSize;i++) //init
  369. {
  370. for (int j=;j<g_QueueSize;j++)
  371. {
  372.  
  373. pRecordMap[i].queue[j].PX_count=;
  374. pRecordMap[i].queue[j].PX_data=;
  375. pRecordMap[i].CurPos=;
  376. }
  377. }
  378.  
  379. cvConvert(pFrImg, pFrameMat);
  380. cvConvert(pBkImg, pBkMat);
  381.  
  382. }
  383. else
  384. {
  385.  
  386. cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  387. cvSmooth(pFrImg, pFrImg, CV_GAUSSIAN, , , );
  388.  
  389. RecordFrame(pFrImg,pBkImg,nFrmNum,pRecordMap,PX_queue);
  390.  
  391. //高斯滤波先,以平滑图像
  392. cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, , , );
  393.  
  394. //当前帧跟背景图相减
  395. cvAbsDiff(pFrImg, pBkImg, pDiff);
  396.  
  397. //二值化前景图
  398. cvThreshold(pDiff, pDiff, threshold, , CV_THRESH_BINARY);
  399. //进行形态学滤波,去掉噪音
  400.  
  401. IplConvKernel* element_erode=cvCreateStructuringElementEx(g_Erosion_kernel_size + , g_Erosion_kernel_size+,
  402. g_Erosion_kernel_size/, g_Erosion_kernel_size/, );
  403.  
  404. IplConvKernel* element_dilate = cvCreateStructuringElementEx(g_Dilation_kernel_size + , g_Dilation_kernel_size+,
  405. g_Dilation_kernel_size/, g_Dilation_kernel_size/, );
  406.  
  407. //! 腐蚀操作
  408. cvErode( pDiff, pDiff, element_erode );
  409.  
  410. /// 膨胀操作
  411. cvDilate( pDiff, pDiff, element_dilate );
  412.  
  413. // cvErode(pDiff, pDiff, 0, 1);
  414. // cvDilate(pDiff, pDiff, 0, 1);
  415. //
  416.  
  417. for (int i=;i<RecordSize;i++)
  418. {
  419. TagMap[i]=;
  420. }
  421.  
  422. size_t cTag=DetectRect(pDiff,TagMap);
  423. TAG_RECORD tmp;
  424.  
  425. tmp.MinX=pDiff->cols;
  426. tmp.MinY=pDiff->rows;
  427. tmp.MaxX=;
  428. tmp.MaxY=;
  429. std::vector<TAG_RECORD> TagRecord(cTag+,tmp);
  430.  
  431. GetRect(TagRecord,cTag,TagMap,pDiff->rows,pDiff->cols);
  432. ncount=;
  433. for (size_t i=;i<TagRecord.size();i++)
  434. {
  435.  
  436. if (TagRecord[i].count<g_CarArea)
  437. {
  438. continue;
  439. }
  440.  
  441. int MinX=TagRecord[i].MinX;
  442. int MinY=TagRecord[i].MinY;
  443. int MaxX=TagRecord[i].MaxX;
  444. int MaxY=TagRecord[i].MaxY;
  445.  
  446. if (MaxX-MinX<g_CarWidth || MaxY-MinY<g_CarHeight)
  447. {
  448. continue;
  449.  
  450. }
  451. ncount++;
  452. cvRectangle( pFrame, cvPoint(MinX,MinY), cvPoint(MaxX,MaxY), CV_RGB(,,), , , );
  453.  
  454. }
  455.  
  456. flow=framesRate*ncount/(double)nFrmNum;
  457.  
  458. sprintf(nframe+,"%d",nFrmNum);
  459. sprintf(ncar+,"%d",ncount);
  460.  
  461. sprintf(str+,"%f",flow);
  462. sprintf(sframeRate+,"%f",framesRate);
  463.  
  464. cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,hscale,vscale,,linewidth);
  465. cvPutText(pFrame,sframeRate,cvPoint(,),&font,cvScalar(,,));
  466. cvPutText(pFrame,ncar,cvPoint(,),&font,cvScalar(,,));
  467. cvPutText(pFrame,nframe,cvPoint(,),&font,cvScalar(,,));
  468.  
  469. cvPutText(pFrame,str,cvPoint(,),&font,cvScalar(,,));
  470. //显示图像
  471. cvShowImage("video", pFrame);
  472. cvShowImage("background", pBkImg);
  473. cvShowImage("foreground", pDiff);
  474.  
  475. //如果有按键事件,则跳出循环
  476. //此等待也为cvShowImage函数提供时间完成显示
  477. //等待时间可以根据CPU速度调整
  478. if( cvWaitKey() >= )
  479. break;
  480.  
  481. }
  482.  
  483. }
  484.  
  485. cvWaitKey();
  486.  
  487. //销毁窗口
  488. cvDestroyWindow("video");
  489. cvDestroyWindow("background");
  490. cvDestroyWindow("foreground");
  491.  
  492. //释放图像和矩阵
  493. cvReleaseImage(&pFrImg);
  494. cvReleaseImage(&pBkImg);
  495.  
  496. cvReleaseMat(&pFrameMat);
  497. cvReleaseMat(&pFrMat);
  498. cvReleaseMat(&pBkMat);
  499.  
  500. cvReleaseCapture(&pCapture);
  501. delete[] pRecordMap;
  502. delete[] TagMap;
  503. return ;
  504. }

opencv车流量统计算法的更多相关文章

  1. 基于OpenCV的KNN算法实现手写数字识别

    基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...

  2. OpenCV实现KNN算法

    原文 OpenCV实现KNN算法 K Nearest Neighbors 这个算法首先贮藏所有的训练样本,然后通过分析(包括选举,计算加权和等方式)一个新样本周围K个最近邻以给出该样本的相应值.这种方 ...

  3. java 在centos6.5+eclipse环境下调用opencv实现sift算法

    java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core ...

  4. 基于FPGA的HDTV视频图像灰度直方图统计算法设计

    随着HDTV的普及,以LCD-TV为主的高清数字电视逐渐进入蓬勃发展时期.与传统CRT电视不同的是,这些高清数字电视需要较复杂的视频处理电路来驱动,比如:模数转换(A/D Converter).去隔行 ...

  5. OPENCV下SIFT算法使用方法笔记

    这几天继续在看Lowe大神的SIFT神作,看的眼花手脚抽筋.也是醉了!!!!实在看不下去,来点干货.我们知道opencv下自带SIFT特征检测以及MATCH匹配的库,这些库完全可以让我们进行傻瓜似的操 ...

  6. 用OpenCV实现Photoshop算法(三): 曲线调整

    http://blog.csdn.net/c80486/article/details/52499919 系列文章: 用OpenCV实现Photoshop算法(一): 图像旋转 用OpenCV实现Ph ...

  7. OpenCV中Camshitf算法学习(补充)

    结合OpenCV中Camshitf算法学习,做一些简单的补充,包括: 实现全自动跟随的一种方法 参考opencv中的相关demo,可以截取目标物体的图片,由此预先计算出其色彩投影图,用于实际的目标跟随 ...

  8. SEO 统计算法

    1)简单粗暴型的,这里不用去管浏览器的user-agent,不管cookie等信息,每产生一次PV,就直接计数,优点:简单,缺点:可能不真实,也可能有刷量数据 2) 稍微细腻点的统计,会区分新老用户, ...

  9. OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)

    原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...

随机推荐

  1. Git 重命名操作

    截至目前,Tome 和Jerry 都使用手动命令来编译自己的项目.Jerry 决定为他们的项目创建 Makefile,并给予适当的名称来命名“string.c” 文件. [jerry@CentOS p ...

  2. [Angularjs] 第一步开始一个项目

    [Angularjs] 第一步开始一个项目 一.什么是angularjs angularjs是2009年兴起的,目前由Google维护一个采用mvc模式的js框架,很多时候用来创建单页面应用.我也经常 ...

  3. MSP MCU I2C入门指南

    这是一份介绍性指南,指导你如何用超低功耗MSP微控制器 (MCU) 开始一个与I2C通信有关的项目: 简介 I2C(或称为I2C,集成电路总线)是一种两线制通信形式,主要用来在短距离.电路板间的应用中 ...

  4. 零基础 Vue 开发环境搭建 打开运行Vue项目

    [相关推荐]IntellIJ IDEA 配置 Vue 支持 打开Vue项目 所需文件 node.js环境(npm包管理器)(node-v8.11.3-x64.msi)(npmV5.6.0) cnpm ...

  5. 8 -- 深入使用Spring -- 6...2 Spring支持的事务策略

    8.6.2 使用XML Schema配置事务策略 Spring 同时支持编程式事务策略和声明式事务策略,通常都推荐采用声明式事务策略. ⊙ 声明式事务能大大降低开发者的代码书写量,而且声明式事务几乎不 ...

  6. linux-Centos 7下bond与vlan技术的结合

    服务器eno1与eno2作bonding,捆绑成bond0接口,服务器对端交换机端口,同属于301.302号vlan接口 vlan 301: 10.1.2.65/27                  ...

  7. c++中map按key和value排序

    ``` #include<iostream> #include<algorithm> #include<vector> #include<map> #i ...

  8. 新装的MySQL没有密码怎么办

    新装的mysql没有密码怎么办 [root@localhost log]# mysql -u root -p Enter password: Welcome to the MySQL monitor. ...

  9. iPhone XS 能否经受的起寒冬的考验

    我的知乎文章链接: https://zhuanlan.zhihu.com/p/51782644 华北地区近日寒风凛冽,温度骤降,已经进入真正的冬天了,最低温度可以达到零下10度,我们手里的iPhone ...

  10. 单目三维稠密重建方案:Quadtree-accelerated Real-time Monocular Dense Mapping

    论文:This is a monocular dense mapping system following the IEEE Robotics and Automation Letters (RA-L ...