首页 > 编程语言 >车辆检测计数算法

车辆检测计数算法

时间:2023-12-11 10:35:03浏览次数:33  
标签:old center temp rct 检测 计数 算法 new dis

车辆检测计数算法是一个经典的算法,可以使用目标跟踪+目标识别的方案来解决。

但是经过几天的调研后,我发现了一种简单的解决方案。

https://blog.csdn.net/taifyang/article/details/128264192

 

只需要前后两帧做一个最短路径匹配,然后利用直线与检测点是否相交,进行车辆计数。

这样的好处是显然易见的,足够简单并且依据也符合常理。

下面给出了一段我自己编写的计数函数:

void MarkNumber(vector<vector<Detection>> &new_det, vector<vector<Detection>> &old_det)
    {
        if (old_det.size() == 0)
        {
            old_det = new_det;
            return;
        }
        vector<vector<float>> dis_matrix;
        vector<Rect> new_rct;
        vector<Rect> old_rct;
        for (const auto& detection : new_det[0])
        {
            cv::Rect temp;
            temp.x = (double)detection.bbox.x;
            temp.y = (double)detection.bbox.y;// - ori_center.y+ detection.bbox.height/2.0
            temp.height = (double)detection.bbox.height;
            temp.width = (double)detection.bbox.width;
            new_rct.push_back(temp);
        }

        for (const auto& detection : old_det[0])
        {
            cv::Rect temp;
            temp.x = (double)detection.bbox.x;
            temp.y = (double)detection.bbox.y;// - ori_center.y+ detection.bbox.height/2.0
            temp.height = (double)detection.bbox.height;
            temp.width = (double)detection.bbox.width;
            old_rct.push_back(temp);
        }

        for (int i = 0; i < new_rct.size(); i++)
        {
            vector<float> dis_vec;
            for (int j = 0; j < old_rct.size(); j++)
            {
                Point new_center = Point(new_rct[i].x + new_rct[i].width / 2, new_rct[i].y + new_rct[i].height / 2);
                Point old_center = Point(old_rct[j].x + old_rct[j].width / 2, old_rct[j].y + old_rct[j].height / 2);

                float temp_dis = sqrt(pow(new_center.x - old_center.x, 2) + pow(new_center.y - old_center.y, 2));

                dis_vec.push_back(temp_dis);
            }
            dis_matrix.push_back(dis_vec);
        }


        for (int i = 0; i < new_rct.size(); i++)
        {
            int min_index= std::min_element(dis_matrix[i].begin(), dis_matrix[i].end()) - dis_matrix[i].begin();

            if (dis_matrix[i][min_index]< max_dis && dis_matrix[i][min_index] > min_dis)
            {
                Point new_center = Point(new_rct[i].x + new_rct[i].width / 2, new_rct[i].y + new_rct[i].height / 2);
                Point old_center = Point(old_rct[min_index].x + old_rct[min_index].width / 2, old_rct[min_index].y + old_rct[min_index].height / 2);
                float tx=new_center.x - old_center.x;
                float ty = new_center.y - old_center.y;

                if (vector_x * tx + vector_y * ty > 0)
                {
                    cv::Mat A = cv::Mat::zeros(2,2,CV_32F);
                    A.at<float>(0, 0) = old_center.y-new_center.y;
                    A.at<float>(0, 1) = new_center.x - old_center.x;
                    A.at<float>(1, 0) = line_pt[0].y - line_pt[1].y;
                    A.at<float>(1, 1) = line_pt[1].x - line_pt[1].x;

                    cv::Mat B = cv::Mat::zeros(2, 1, CV_32F);
                    B.at<float>(0, 0) = old_center.y * new_center.x- old_center.x * new_center.y;
                    B.at<float>(1, 0) = line_pt[0].y * line_pt[1].x - line_pt[0].x * line_pt[1].y;

                    cv::Mat theta = A.inv() * B;
                    float theta_x = theta.at<float>(0, 0);
                    float theta_y = theta.at<float>(1, 0);
                    if (theta_x >= min(line_pt[0].x, line_pt[1].x) && theta_y >= min(line_pt[0].y, line_pt[1].y) && theta_x <= max(line_pt[0].x, line_pt[1].x) && theta_y <= max(line_pt[0].y, line_pt[1].y))
                    {
                        count++;
                    }
                }
            }
        }


        auto tt = std::chrono::system_clock::to_time_t
        (std::chrono::system_clock::now());
        struct tm* ptm = new tm();
        localtime_s(ptm, &tt);
        if (ptm->tm_hour ==0 && ptm->tm_min == 0)
        {
            count = 0;
        }


    }

 

标签:old,center,temp,rct,检测,计数,算法,new,dis
From: https://www.cnblogs.com/xmds/p/17893807.html

相关文章

  • 基于AidLux的工业视觉少样本缺陷检测实战
    1.引言工业视觉缺陷检测系统是一种利用计算机视觉技术,通过分析生产过程中的图像和视频数据,来检测工业产品是否存在缺陷或质量问题的系统。有幸参加Aidlux的11月份的训练营<<工业视觉少样本缺陷检测实战>>,在这个过程中我收获到了很多之前没有接触到的算法和实践。本次课程利用Unet......
  • Unity3D 游戏开发中的随机算法详解
    在Unity3D游戏开发中,随机算法是非常重要的一部分。随机算法可以用于生成随机数、随机位置、随机事件等,为游戏增加了一定的变化性和可玩性。本文将详细介绍Unity3D中常用的随机算法,并给出相应的技术详解和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基......
  • 【算法】【线性表】两个排序数组的中位数
    1 题目两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log(m+n))。中位数的定义:这里的中位数等同于数学定义里的中位数。中位数是排序后数组的中间值。如果有数组中有n个数且n是奇数,则中位数为 A((n-1)/2)。如果有数组中有n个数且n......
  • 工业视觉少样本缺陷检测实战应用
    工业视觉少样本缺陷检测实战应用1.AidLux介绍AidLux能广泛应用在智能工业、AI教育、智慧人居、智慧城市、智慧物流、智慧交通、智慧零售和机器人等诸多场景中。集成国际主流AI框架和多种开发环境、后台服务程序、编译器及图形开发组件,无须配置开箱即用,极大地简化了开发步骤;自......
  • 闸刀开关状态识别AI算法与巡检机器人完美配合,安全无忧!
    随着工业自动化程度的不断提高,巡检机器人已经成为工业设备维护、安全监测的重要利器。然而,传统的巡检机器人在巡检过程中只能对固定的设备进行静态监测,对于一些动态状态的设备,比如闸刀开关状态的识别,传统的巡检方法显然已经无法满足实际需求。因此,如何利用人工智能技术来实现闸刀状......
  • dom检测
      form=document.createElement('form');form.id="angdh";document.body.appendChild(form);if(window["angdh"]!==form){console.log('被检测1')}if(!("angdh"inwindow)||window.hasOwnProperty('ang......
  • 文心一言 VS 讯飞星火 VS chatgpt (153)-- 算法导论12.2 9题
    九、用go语言,设T是一棵二叉搜索树,其关键字互不相同;设x是一个叶结点,y为其父结点。证明:y.key或者是T树中大于x.key的最小关键字,或者是T树中小于x.key的最大关键字。文心一言:要证明这个性质,我们可以采用二叉搜索树的性质:对于任何节点N,其左子树中的所有节点的值都小于N......
  • 文心一言 VS 讯飞星火 VS chatgpt (153)-- 算法导论12.2 9题
    九、用go语言,设T是一棵二叉搜索树,其关键字互不相同;设x是一个叶结点,y为其父结点。证明:y.key或者是T树中大于x.key的最小关键字,或者是T树中小于x.key的最大关键字。文心一言:要证明这个性质,我们可以采用二叉搜索树的性质:对于任何节点N,其左子树中的所有节点的值都小......
  • 算法之快速排序5非递归实现
    一:概述绝大多数的递归逻辑都可以利用栈的方式去代替。代码中一层一层的方法调用,本身就是使用一个方法调用栈。每次进入一个新的方法,就相当于入栈。每次有方法返回就相当于出栈。所以,可以把原本的递归实现转换成一个栈的实现,在栈中存储每一次方法调用的参数。二:具体代码实现/*非......
  • 扩展欧几里得算法
    扩欧代码(时间复杂度O(logn))求ax+by=gcd(a,b)的一组整数解 intgcd(inta,intb){ if(b==0)returna; returngcd(b,a%b);}intexgcd(inta,intb,int&x,int&y){ if(b==0) { x=1,y=0; returna; } intx1,y1,d; d=exgcd(b,a%b,x1,y1); x=y1,y=x1-a/b*y1; re......