该功能使用的darknet框架,用yolov3进行训练检测,跟踪用的简单距离跟踪逻辑。

一、网址:https://github.com/AlexeyAB/darknet

二、参考训练参考我的另一篇博客:https://blog.csdn.net/zhulong1984/article/details/82344685

三、跟踪代码:

#pragma once#include "HeadDetect.h"
#include "opencv2/opencv.hpp"using namespace cv;
using namespace std;#define MAX_TRACK_COUNT         30//目标的最大个数
#define MAX_TRAJECTORY_COUNT    200//目标轨迹的最大个数
#define MAX_MISS_FRAME          30//最大丢失帧数
#define MAX_TRACK_DIST          20000//最大跟踪距离struct Tracker
{int nID;int nMissTimes;bool bMatchID;bool bTrack;bool bStatOK;bool bInitDirection;int nInitDirection;cv::KalmanFilter *kf;cv::Point predPoint;cv::Point curCentre;cv::Rect curRect;int nTrajCount;cv::Point centres[MAX_TRAJECTORY_COUNT];cv::Rect blobs[MAX_TRAJECTORY_COUNT];
};class HeadTrack
{
public:HeadTrack();~HeadTrack();int m_InCount;int m_OutCount;Tracker *m_pTrackers;//m_trackers[MAX_TRACK_COUNT];void trackInitial(int arrowStart, int arrowEnd, cv::Point lineStart, cv::Point lineEnd, cv::Mat detectRegion);void trackProcess(HDBox_Container *pHDBox_Container);void trackInOutStatistics();int pointInLineSide(cv::Point point, cv::Point lineStart, cv::Point lineEnd);private:int m_trackID;int m_nArrowStart;int m_nArrowEnd;cv::Point m_lineStart;cv::Point m_lineEnd;cv::Mat m_detectRegion;
};#include "headTrack.h"HeadTrack::HeadTrack()
{m_trackID = 0;m_InCount = 0;m_OutCount = 0;m_nArrowStart = 0;m_nArrowEnd = 0;m_pTrackers = new Tracker[MAX_TRACK_COUNT];memset(m_pTrackers, 0, sizeof(Tracker));
}HeadTrack::~HeadTrack()
{
}void HeadTrack::trackInitial(int arrowStart, int arrowEnd, cv::Point lineStart, cv::Point lineEnd, cv::Mat detectRegion)
{m_trackID = 0;m_InCount = 0;m_OutCount = 0;m_nArrowStart = arrowStart;m_nArrowEnd = arrowEnd;m_lineStart = lineStart;m_lineEnd = lineEnd;m_detectRegion = detectRegion.clone();
}void HeadTrack::trackProcess(HDBox_Container *pHDBox_Container)
{int i = 0, j = 0;//把太小的rect删除HDBox_Container boxContainer;boxContainer.headCount = 0;int width = m_detectRegion.cols;uchar *pDetectData = m_detectRegion.data;int step1 = m_detectRegion.step1();//cv::imshow("m_detectRegion", m_detectRegion);//cv::waitKey(10);for (i = 0;i< pHDBox_Container->headCount;i++){HDRect *pHDRect = &pHDBox_Container->candidates[i];int nx = (pHDRect->right + pHDRect->left) / 2;int ny = (pHDRect->top + pHDRect->bottom) / 2;int rectW = pHDRect->right - pHDRect->left;int rectH = pHDRect->bottom - pHDRect->top;if (rectW > 60 && rectH > 60 && (*(pDetectData + ny*width + nx) == 255)){boxContainer.candidates[boxContainer.headCount++] = pHDBox_Container->candidates[i];}}bool bMatch[HD_MAX_HEADS] = { false };for (i = 0;i< boxContainer.headCount;i++){bMatch[i] = false;}for (i = 0; i < MAX_TRACK_COUNT; i++){Tracker *pTracker = &m_pTrackers[i];if (pTracker->bTrack){bool bMinst = false;int nMatchID = -1;int maxDist = MAX_TRACK_DIST;for (j = 0; j < boxContainer.headCount; j++){if (!bMatch[j]){HDRect *pHDRect = &boxContainer.candidates[j];cv::Rect curRect;curRect.x = pHDRect->left;curRect.y = pHDRect->top;curRect.width = pHDRect->right - pHDRect->left;curRect.height = pHDRect->bottom - pHDRect->top;int nx = (pHDRect->left + pHDRect->right) / 2;int ny = (pHDRect->top + pHDRect->bottom) / 2;int dist = (pTracker->predPoint.x - nx)*(pTracker->predPoint.x - nx) + (pTracker->predPoint.y - ny)*(pTracker->predPoint.y - ny);if (dist < maxDist){maxDist = dist;pTracker->curRect = curRect;//后面更新用pTracker->curCentre.x = nx;pTracker->curCentre.y = ny;nMatchID = j;bMinst = true;}}}//找到了blobif (bMinst){bMatch[nMatchID] = true;HDRect *pHDRect = &boxContainer.candidates[nMatchID];cv::Rect curRect;curRect.x = pHDRect->left;curRect.y = pHDRect->top;curRect.width = pHDRect->right - pHDRect->left;curRect.height = pHDRect->bottom - pHDRect->top;int nx = (pHDRect->left + pHDRect->right) / 2;int ny = (pHDRect->top + pHDRect->bottom) / 2;pTracker->bMatchID = true;pTracker->nMissTimes = 0;pTracker->curCentre.x = nx;pTracker->curCentre.y = ny;pTracker->curRect = curRect;//更新预测值Mat measurement = Mat::zeros(2, 1, CV_32F);measurement.at<float>(0) = (float)nx;measurement.at<float>(1) = (float)ny;pTracker->kf->correct(measurement);Mat prediction = pTracker->kf->predict();pTracker->predPoint = Point(prediction.at<float>(0), prediction.at<float>(1)); //预测值(x',y')cv::Point centre = pTracker->centres[pTracker->nTrajCount - 1];if ((centre.x - nx)*(centre.x - nx) + (centre.y - ny)*(centre.y - ny) > 30){pTracker->centres[pTracker->nTrajCount].x = nx;pTracker->centres[pTracker->nTrajCount].y = ny;pTracker->blobs[pTracker->nTrajCount] = curRect;pTracker->nTrajCount++;if (pTracker->nTrajCount >= MAX_TRAJECTORY_COUNT - 1){pTracker->nTrajCount = MAX_TRAJECTORY_COUNT - 1;for (int k = 1; k < pTracker->nTrajCount; k++){pTracker->centres[k - 1] = pTracker->centres[k];pTracker->blobs[k - 1] = pTracker->blobs[k];}}}}   else//没找到blob{pTracker->nMissTimes++;//Mat prediction = pTracker->kf->predict();//pTracker->predPoint = Point(prediction.at<float>(0), prediction.at<float>(1)); //预测值(x',y')//更新预测值Mat measurement = Mat::zeros(2, 1, CV_32F);measurement.at<float>(0) = (float)pTracker->curCentre.x;measurement.at<float>(1) = (float)pTracker->curCentre.y;pTracker->kf->correct(measurement);Mat prediction = pTracker->kf->predict();pTracker->predPoint = Point(prediction.at<float>(0), prediction.at<float>(1)); //预测值(x',y')if (pTracker->nMissTimes > MAX_MISS_FRAME){pTracker->bTrack = false;delete pTracker->kf;}}}}//没有匹配上的,需要重新创建目标for (i = 0; i < boxContainer.headCount; i++){HDRect *pHDRect = &boxContainer.candidates[i];cv::Rect curRect;curRect.x = pHDRect->left;curRect.y = pHDRect->top;curRect.width = pHDRect->right - pHDRect->left;curRect.height = pHDRect->bottom - pHDRect->top;int nx = (pHDRect->left + pHDRect->right) / 2;int ny = (pHDRect->top + pHDRect->bottom) / 2;if (!bMatch[i]){for (j = 0; j < MAX_TRACK_COUNT; j++){Tracker *pTracker = &m_pTrackers[j];if (!pTracker->bTrack){pTracker->bTrack = true;pTracker->bMatchID = true;pTracker->bStatOK = false;pTracker->bInitDirection = false;pTracker->nID = ++m_trackID;pTracker->curCentre.x = nx;pTracker->curCentre.y = ny;pTracker->curRect = curRect;pTracker->nMissTimes = 0;pTracker->predPoint.x = nx;pTracker->predPoint.y = ny;pTracker->kf = new cv::KalmanFilter(4, 2, 0);pTracker->kf->transitionMatrix = (Mat_<float>(4, 4) << 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1);//转移矩阵Acv::setIdentity(pTracker->kf->measurementMatrix);                     //测量矩阵Hcv::setIdentity(pTracker->kf->processNoiseCov, Scalar::all(1e-5));    //系统噪声方差矩阵Qcv::setIdentity(pTracker->kf->measurementNoiseCov, Scalar::all(1e-1));//测量噪声方差矩阵Rcv::setIdentity(pTracker->kf->errorCovPost, Scalar::all(1));          //后验错误估计协方差矩阵PpTracker->kf->statePost = (Mat_<float>(4, 1) << nx, ny, 0, 0);Mat prediction = pTracker->kf->predict();pTracker->predPoint = Point(prediction.at<float>(0), prediction.at<float>(1)); //预测值(x',y')pTracker->centres[0].x = nx;pTracker->centres[0].y = ny;pTracker->blobs[0] = curRect;pTracker->nTrajCount = 1;break;}}}}
}int HeadTrack::pointInLineSide(cv::Point point, cv::Point lineStart, cv::Point lineEnd)
{int x0 = 0, x1 = 0;int y0 = 0, y1 = 0;int v0 = 0, v1 = 0;bool bFlag = false;bool bFlagX = false;bool bFlagY = false;x0 = lineStart.x;x1 = lineEnd.x;y0 = lineStart.y;y1 = lineEnd.y;先保证点在线段内if (x0 > x1){bFlagX = point.x > x1 && point.x < x0;}else{bFlagX = point.x <x1 && point.x >x0;}if (y0 > y1){bFlagY = point.y > y1 && point.y < y0;}else{bFlagY = point.y <y1 && point.y >y0;}bFlag = bFlagX || bFlagY;if (!bFlag){return 0;}v0 = (point.x - x0)*(y1 - y0) - (point.y - y0)*(x1 - x0);v1 = x1 - x0;if (x1 - x0 == 0){if (v0 < 0){return -1;}else{return 1;}}else{if (v0*v1 < 0){return -1;}else{return 1;}}return 0;
}void HeadTrack::trackInOutStatistics()
{int i = 0, j = 0;for (i = 0; i < MAX_TRACK_COUNT; i++){Tracker *pTracker = &m_pTrackers[i];if (pTracker->bTrack && pTracker->nTrajCount > 20 && !pTracker->bStatOK){if (!pTracker->bInitDirection){int count0 = 0;for (j = 0; j < 10; j++){int flag = pointInLineSide(pTracker->centres[j], m_lineStart, m_lineEnd);count0 += flag;}if (count0 > 0){pTracker->nInitDirection = 1;}else{pTracker->nInitDirection = -1;}}int count1 = 0;for (j = pTracker->nTrajCount - 10; j < pTracker->nTrajCount - 1; j++){int flag = pointInLineSide(pTracker->centres[j], m_lineStart, m_lineEnd);if (flag != 0 && pTracker->nInitDirection != flag){count1++;}}if (count1 > 6){if (pTracker->nInitDirection == m_nArrowStart){m_InCount++;}else{m_OutCount++;}pTracker->bStatOK = true;}}}
}

四、效果展示:

效果图1

效果图2 --QQ交流:187100248

算法demo,封装了一个前期的演示效果,验证算法可以在windows上运行,算法编译使用的是vs2015+cuda需要的环境,运行需要有GTX的显卡:

demo网盘地址:链接:https://pan.baidu.com/s/1IKaGZOqDEO-McBnkwhunzg  提取码:c9ga

部分原始数据,需要自己标注:链接:https://pan.baidu.com/s/1AOasuALCc7LX6cspyYUrcg 
提取码:rn13

深度学习 客流统计 人流计数相关推荐

  1. 《中国人工智能学会通讯》——2.27 利用深度学习改进统计机器翻译

    2.27 利用深度学习改进统计机器翻译 利用深度学习改进统计机器翻译的核心思想是以统计机器翻译为主体,使用深度学习改进其中的关键模块,如语言模型[1] .翻译模型 [2] .调序模型 [3] .词语对 ...

  2. 《深度学习,统计学习,数学基础》人工智能算法工程师手册:程序员写的AI书,50 章一网打尽...

    来源:专知 本文约3400字,建议阅读10+分钟. 免费开源人工智能手册,带你快速上手写代码! [ 导读 ]市面上很多人工智能相关的书籍.大部分的书,面向小白,内容深度不够:小部分教材书或者科研书,内 ...

  3. 《深度学习,统计学习,数学基础》人工智能算法工程师手册

    [ 导读 ]市面上很多人工智能相关的书籍.大部分的书,面向小白,内容深度不够:小部分教材书或者科研书,内容艰深,又过于复杂.那么有没有,面向算法工程师(程序员)人群的,面向有一定数学基础.算法基础,能 ...

  4. 【毕业设计】深度学习行人车辆流量计数系统 - 目标检测 python

    文章目录 0 前言 1. 目标检测概况 1.1 什么是目标检测? 1.2 发展阶段 2. 行人检测 2.1 行人检测简介 2.2 行人检测技术难点 2.3 行人检测实现效果 2.4 关键代码-训练过程 ...

  5. 关于机器学习、符号学习、统计学习、流形学习、深度学习关系的浅见:

    机器学习是人工智能领域中最能体现智能的一个分支.符号学习.统计学习.深度学习是机器学习的不同方向.符号学习主要以离散的方法处理遇到的问题,而统计学习主要以连续的方法处理问题:深度学习依赖于神经网络等: ...

  6. 机器学习和深度学习学习资料

    FROM:http://suanfazu.com/t/ji-qi-xue-xi-he-shen-du-xue-xi-xue-xi-zi-liao/126 比较全面的收集了机器学习的介绍文章,从感知机. ...

  7. [转]机器学习和深度学习资料汇总【01】

    本文转自:http://blog.csdn.net/sinat_34707539/article/details/52105681 <Brief History of Machine Learn ...

  8. 【转】自学成才秘籍!机器学习深度学习经典资料汇总

    小编都深深的震惊了,到底是谁那么好整理了那么多干货性的书籍.小编对此人表示崇高的敬意,小编不是文章的生产者,只是文章的搬运工. <Brief History of Machine Learnin ...

  9. 近200篇机器学习&amp;深度学习资料分享(含各种文档,视频,源码等)

    转自:http://www.tuicool.com/articles/jUz2Y3b 编者按:本文收集了百来篇关于机器学习和深度学习的资料,含各种文档,视频,源码等.而且原文也会不定期的更新,望看到文 ...

最新文章

  1. 图解eclipse+myeclipse完全绿色版制作过程
  2. Unix/Linux提权漏洞快速检测工具unix-privesc-check
  3. 怎样用“python”快速入门数据分析?
  4. java amqp_AMQP协议
  5. maven book
  6. python左移右移位运算_Python这些位运算的妙用,绝对让你大开眼界
  7. 基于.net的微服务架构下的开发测试环境运维实践
  8. python display函数_【python】pandas display选项
  9. 特征图注意力_ICLR2017 | AT_注意力引导的知识蒸馏
  10. KNN(五)--层次Kmean
  11. 6734. 【2020.06.18省选模拟】T2 航行
  12. Linux 下完整安装ffmpeg(包括各种解码器)
  13. 手撕Boost!Boost公式推导及实验验证
  14. 给你一个字符串,删除其中的不是英文字母的符号,也就是说除了英文字母之外的字符都应该删除,请你输出删除后的字符串。
  15. 【全网唯一】TC8一致性测试文章合集来袭(持续更新中)
  16. python中的Numpy包
  17. 【深度学习框架体系的学习】pytorch
  18. CV之IE之Inception:基于TF框架利用Inception模型+GD算法的某层网络图像生成不同尺寸和质量的Deep Dream幻觉梦境图片(特征可视化实现图像可解释性)—五个架构设计思维导图
  19. EV代码签名证书可以自助续签吗?
  20. BZOJ4585 [Apio2016]烟火表演

热门文章

  1. 异常: Canonical names should be kebab-case(“-” separated), lowercase......... blablabla
  2. Web前端面试指导(八):iframe有那些缺点
  3. Web前端面试指导:谈谈浏览器的兼容性
  4. 如何将CAD图纸图形同比例缩小或者放大
  5. 思科华为设备STP、RSTP配置命令对比
  6. 2021年煤气考试题库及煤气考试内容
  7. 处理Android中的点击冲突
  8. 个性化推荐技术的十大挑战
  9. 关于 某讯QQ群的群文件上传和下载出现错误-134 的解决方法
  10. 【新书推荐】【2019.05】财务诡计:如何识别财务报告中的会计诡计和舞弊(原书第4版)...