一、处理逻辑

  • 背景建模得到前景 ----> 二值化标记 ---> 合并重叠框

    • 由于二值化标记的局限,导致出现了很多的重叠框;
    • 重叠框过多,在合并重叠框Merge这一步的时候举步维艰。时间消耗过长。
    • 计算包围框,不在Merge的范围内!计算包围框时间过长了。
  • 原因分析 + 证据证明!!!


1. 证据辅助过程

现象描述的准确文件:

① 找到超过3W点时,崩溃的数据。即找到当时耗时间过长的数据段,仔细分析问题。 fg格式文件准备。
② 时间间消耗证明过程。每帧是多少时间,多少点数,时间消耗。
③ fg到Meanshift到底得到了多少个标签?(非重复标签?)又得到了到底多少个框框?其中框框是个什么情况?重叠非重叠?需要处理多少个重叠的情况?
④ Merge这一步,面对这么多个重叠的框框,需要多少时间去处理?效率怎么样?
⑤ 这两个模块到底面临了多大的限制?局限性?天花板?
⑥ 如何解决这个局限性?

时间消耗过长的现象描述:

来了一个异常帧之后,由于前景点较多。在漂移半径较小的情况下,出现了很多这样的分割区域。

  • 有1300多个分割区域。(①CCL二值图标记的时间消耗;②二值图标记的标签个数问题

    • 时间消耗不是主要的,关键是标签个数是一大缺陷;导致了后续的问题
  • 后续的计算包围框的算法效率太低。
  • 29W个点,以及56W个点的move_points,要遍历
    • for 1:max_classID=1300
         for 1:move_points.size() 56W/29W

2. 参考opencv源码 connectedComponentWithStats函数

OpenCV—连通域分析connectedComponentsWithStats()_i_chaoren的博客-CSDN博客_cv::connectedcomponentswithstats

其中,自带了这部分后处理。除了标记,也直接给出了每个标记的区域信息,rect,area,centroid等信息。

2.1 opencv源码探析

文档位置:OpenCV: Structural Analysis and Shape Descriptors

opencv源码位置在:opencv->modules->imgproc->src->connectedcomponents.cpp

源码下载位置:https://github.com/opencv/opencv

  • connectedComponentsWithStats->connectedComponents_sub1->LabelingWu()

    • LabelingWu基本上按照CCL的代码逻辑在走;
    • 主要看获取了labels之后的操作
  • sop统计的数据类型,代码原理:

3. 修改之后的问题

时间:20:36:58时刻,2022-09 微信文件夹,16-3的数据。含有几个打shutter的帧,结果是:ID=1300之前,ComputeClosingRect计算包围框的时间消耗<1s,其中meanshif消耗2s

  • ① Meanshift模块,继续非常耗时。
  • ② 计算包围框模块,此时还是耗时7.34s

3.1 耗时7.4s时的情况

  • 上面是当前图像,打shutter

  • 下面是meanshift之后的标记结果。界面上的漂移半径很小。

  • MAXID= 2420。 ID到2000多的时候,还是很慢。

  • 此时前景像素点为68W点。

  • Meanshift模块时间消耗过大了。

3.2 单独测试合并重叠框的模块

测试代码如下:使用随机生成的方式,来进行合并

/*测试:合并重叠框算法效率&性能
*/
#include <opencv2/opencv.hpp>
#include <vector>bool isOverlap(cv::Point2i tl1, cv::Point2i br1, cv::Point2i curTl, cv::Point2i curBR);
bool isCenterClose(cv::Rect center, cv::Rect curCenter);
std::vector<int> getAllOverlaps(std::vector<cv::Rect>move_rects, cv::Rect curRect, int index);
void MergeUpdate(std::vector<cv::Rect> &move_rects);#define IMG_WIDTH 200
#define IMG_HEIGHT 200int shift_radius = 10;int main(int argc, char* argv[])
{cv::Mat img = cv::Mat::zeros(IMG_WIDTH, IMG_HEIGHT, CV_8UC1);// 1.随机生成多个重叠框int seed = 20;cv::RNG rng(seed);  int k = 0;while (k < 20){k++;std::vector<cv::Rect> move_rects;for (int i = 0; i < 10; ++i)                // 随机生成10个框{// 10% 概率生成大目标; 90% 概率生成小目标; 宽度; 左上角+w/hint left = rng.next() % IMG_WIDTH;int top = rng.next() % IMG_HEIGHT;int width = 0, height = 0;if (rng.next() % 10 == 0)             // 10% 大目标{width = rng.next() % IMG_WIDTH + 1;height = rng.next() % IMG_HEIGHT + 1;}else{width = rng.next() % (IMG_WIDTH / 3) + 1;height = rng.next() % (IMG_HEIGHT / 3) + 1;}cv::Rect rect(left, top, width, height);move_rects.push_back(rect);}cv::Mat imgBeforMerge = img.clone();for (int i = 0; i < move_rects.size(); ++i){cv::rectangle(imgBeforMerge, move_rects[i], 255, 1);       // 画出处理之前的bbox}// 2.合并重叠框MergeUpdate(move_rects);for (int i = 0; i < move_rects.size(); ++i){cv::rectangle(img, move_rects[i], 255, 1);       // 画出处理之前的bbox}}return 0;
}bool isOverlap(cv::Point2i tl1, cv::Point2i br1, cv::Point2i curTl, cv::Point2i curBR)
{//[tl1.x, tl1.y, br1.x, br1.y] [curTl.x, curTl.y, curBR.x, curBR.y]return !(br1.x < curTl.x || br1.y < curTl.y || tl1.x > curBR.x || tl1.y > curBR.y);
}bool isCenterClose(cv::Rect center, cv::Rect curCenter)
{int cenx = center.x + center.width / 2;int ceny = center.y + center.height / 2;int CurCenX = curCenter.x + curCenter.width / 2;int CurCenY = curCenter.y + curCenter.height / 2;float diff = (cenx - CurCenX) * (cenx - CurCenX)+ (ceny - CurCenY) * (ceny - CurCenY);return diff < shift_radius;
}std::vector<int> getAllOverlaps(std::vector<cv::Rect>move_rects, cv::Rect curRect, int index)
{std::vector<int> overlaps_ID;overlaps_ID.clear();// 从move_rects中找到所有与tl br的rect重叠的框,并返回索引for (int i = 0; i < move_rects.size(); i++){if (i != index){if (isOverlap(move_rects[i].tl(), move_rects[i].br(), curRect.tl(), curRect.br()))overlaps_ID.push_back(i);else if (isCenterClose(move_rects[i], curRect))overlaps_ID.push_back(i);}}return overlaps_ID;
}
/* 合并重叠框和近邻框 */
void MergeUpdate(std::vector<cv::Rect> &move_rects)
{bool finished = false;while (!finished)                               // 是否还有重叠框{finished = true;//std::cout << "size of rects:" << move_rects.size() << endl;int index = move_rects.size() - 1;while (index >= 0){// 加入边界cv::Rect curRect = move_rects[index];// 获取所有重叠框的IDstd::vector<int> overlaps = getAllOverlaps(move_rects, curRect, index);if (overlaps.size() > 0)              // 有重叠就合并{overlaps.push_back(index);std::vector<cv::Point2i> points;points.clear();float cenx = 0.0;float ceny = 0.0;int validNumSum = 0;for (int i = 0; i < overlaps.size(); i++){points.push_back(move_rects[overlaps[i]].tl());points.push_back(move_rects[overlaps[i]].br());}// 合并后的大框cv::Rect mergeRect = cv::boundingRect(points);// 删除合并前的所有小框:逆向排序,再删除,效率较高std::sort(overlaps.begin(), overlaps.end(), [](int &a, int &b) {return a > b; });// 获取迭代器的第一个值for (int i = 0; i < overlaps.size(); i++){std::vector<cv::Rect>::iterator   iter = move_rects.begin() + overlaps[i];move_rects.erase(iter);}move_rects.push_back(mergeRect);finished = false;break;}index -= 1;}  // end of inner while}  // end of outer while
}

参考YACCLAB Benchmark的代码

  • 主要学习点:① 学习如何测试时间开销;② 如何测试性能? correctness  《算法4》在这部分是如何做的呢?

补充

  • CV_32SC1 单通道;S--int 符号整,型;U--无符号整型。

    • 32位int整型的表示范围:21,4748,3647。21亿。
    • 全景像素点数:1280*35=4,4800。int

补充

  • 写测试代码,测试合并重叠框的程序段功能。
  • opencv的include问题
    • cv.hpp和opencv.hpp,cv.hpp是早期opencv版本中的定义名称;opencv.hpp是3.0版本后的表示方法
    • #include <opencv2/opencv.hpp>2
      • opencv.hpp里面包含了 opencv2里面的大部分头文件。
  • opencv include 包含目录:opencv/opencv/build/include opencv/opencv/build/include/opencv opencv/opencv/build/include/opencv2
  • opencv lib目录 库目录:    opencv/opencv/bulid/x64/vc14/lib
  • 链接器附加依赖项:           opencv_world340d.lib
  • 看懂这些配置,需要去看书籍《深入浅出计算机系统》等,里面的描述。
    • 实用、实践中,学为
    • 所用。

D:.
├─build
│  ├─bin
│  ├─etc
│  │  ├─haarcascades
│  │  └─lbpcascades
│  ├─include
│  │  ├─opencv
│  │  └─opencv2
│  │      ├─calib3d
│  │      ├─core
│  │      │  ├─hal
│  │      │  └─utils
│  │      ├─dnn
│  │      ├─features2d
│  │      ├─flann
│  │      ├─highgui
│  │      ├─imgcodecs
│  │      ├─imgproc
│  │      │  ├─detail
│  │      │  └─hal
│  │      ├─ml
│  │      ├─objdetect
│  │      ├─photo
│  │      ├─shape
│  │      ├─stitching
│  │      │  └─detail
│  │      ├─superres
│  │      ├─video
│  │      ├─videoio
│  │      └─videostab

下面是opencv文件夹的大概内容:

  • vs2015 最常用的: CTRL + M + O折叠代码 CTRL + M + L展开代码 亲测V2015中可用,其它版本应该也可以的
  • vscode 折叠代码:Ctrl+K+0;  展开代码:Ctrl+K+J

算法加速问题探讨

1. 加速的方式

  • ① 算法本身的复杂度:时间、空间开销问题。
  • ② Python->C++,C++和C比python快。但关键的地方还是在第一步的算法本身的复杂度上。5~20倍的这种加速还是无法满足使用要求。
  • ③ 算法并行;汇编加速;硬件加速;——我不涉及这个部分

是科研人就要快!加速你的算法!_小玺玺的博客-CSDN博客_智能优化算法执行速度特别慢 如何加速

2. 算法加速


数据结构—算法时间复杂度、空间复杂度和问题规模_南笙北萧~的博客-CSDN博客_问题规模对算法效率的影响

【3】算法的时间复杂度不仅仅依赖于问题的规模,还与输入实例的初始状态有关。

算法时间影响

  • ① 数据规模 O(n?) 与规模n有关系
  • ② 输入输出内容,与输入输出的内容有关系

基本是两个变量;不同规模下,不同内容,导致的时间开销问题;

  • ① 规模过大,导致的冗余计算?——是否可以化多为少来进行?
  • ② 输入内容差异,导致的时间问题?

测试MeanshiftMerge时间开销

  • 影响算法运行的因素:① 算法的实现『时间复杂度』;② 数据规模;③ 输入数据的内容

1. 如何计算算法的时间复杂度?

  • ① 理论分析:通过看源代码,看循环次数,结合经验;判断该代码的时间复杂度的量级;O(N^2)? NlogN? N? logN?
  • ② 测试用例测试:2倍输入规模,看时间,画出双对数图log-log图,看比率。根据幂定理:log(T(2N)/(T(N)) = b
    • NlogN算法的b=2;
    • N^2算法,b=2

  • 使用的测试资料为:50%前景,倍增尺寸看结果。

传统目标检测后处理问题相关推荐

  1. 【机器学习】传统目标检测算法总结

    目标检测是什么 object detection,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别.所以,object detection要解决的问题就是物体在哪里以及是什么的整个流程问题. ...

  2. 目标检测:传统目标检测方法

    文章目录 引言 什么是传统目标检测? 区域选择 特征提取 分类器 传统目标检测方法不足 引言 提到Computer Vision,可能我们会最先想到CV的基本任务Image Classificatio ...

  3. 目标检测 Chapter1 传统目标检测方法

    文章目录 目标检测问题定义 介绍 目标检测和图像分类.图像分割的区别 目标检测问题方法 传统目标检测 深度学习目标检测 传统 Vs 深度学习 传统目标检测综述 Viola-Jones HOG+SVM ...

  4. 2D: 传统目标检测算法综述

    一. 目标检测的发展历程 1. 2001年,V-J检测器诞生,主要用于人脸的检测: 2. 2006年,HOG + SVM的方法出现,主要用于行人的检测: 3. 2008年,rgb大神(记住这个人,后面 ...

  5. 目标检测后处理:从nms到softer nms

    文章目录 1 NMS 1.1 动机 1.2 步骤 2 Soft-NMS 2.1 动机 2.2 算法思想 2.3 步骤 3 Softer-NMS 3.1 动机 3.1.1 现有方法的问题 3.1.2 本 ...

  6. 【机器学习】传统目标检测算法之HOG

    转载+理解:hog:https://www.cnblogs.com/wyuzl/p/6792216.html hog:https://blog.csdn.net/masibuaa/article/de ...

  7. 目标检测(三)传统目标检测与识别的特征提取——基于HOG特征的目标检测原理

    目录 简介 提取HOG特征的步骤 1.预处理获取要计算其特征的输入图像 2.计算图像的梯度 3.计算8×8细胞梯度直方图 4.直方图归一化 5.计算HOG特征向量 Opencv利用HOG特征实现行人检 ...

  8. 【机器学习】传统目标检测算法之DPM

    前面介绍了一下HOG,HOG有一个缺点:很难处理遮挡问题,人体姿势动作幅度过大或物体方向改变也不易检测. 继2005年HOG提出之后,DPM模型在借鉴了HOG之后也被提了出来同时还取得了不错的成绩. ...

  9. 【机器学习】传统目标检测算法之级联分类器Cascade

    先附上参考文章吧. 文章其实是"P. Viola, M. Jones. Rapid Object Detection using a Boosted Cascade of Simple Fe ...

最新文章

  1. linux 内核位置无关,Linux内核启动阶段虚实地址映射
  2. MySQL系列:innodb源代码分析之线程并发同步机制
  3. can bus 中spn是什么_CP AUTOSAR功能栈简介NM网络管理(Can)
  4. spark里的hbase的ImmutableBytesWritable的打印问题scala
  5. 【转】ABP源码分析十六:DTO的设计
  6. 父亲节——女儿的礼物
  7. [置顶]c# 设计模式(2)结构型
  8. 编译原理 语法分析程序
  9. 百度AI开放平台文字之身份证识别的实现
  10. Android 调用免费短信验证码sdk开发
  11. js高级--jsonp跨域
  12. Cookie、Session 简述
  13. 在百度地图上展示dwg/dxf
  14. 思考分析常用思维模型
  15. javaee图书管理系统mysql,图书管理系统设计与实现—看这篇就够了
  16. foobar2000-new
  17. java-net-php-python-jspm早教中心系统查重PPT计算机毕业设计程序
  18. [日推荐]『质安查』买到放心的产品就靠它了
  19. Auto-Icon:一款自动代码生成工具 | 开发​工程师必备
  20. 多个vue项目生产环境下NGINX配置文件

热门文章

  1. MATLAB数字图像处理复习概览
  2. 总结word2vec
  3. 反黑风暴·记一次遭遇 SSDP DDoS 和 EternalBlue(永恒之蓝)攻击经历
  4. 2021辽宁高考成绩查询具体时间,2021年辽宁高考成绩什么时候出具体时间几点 具体准确时间...
  5. Linux系统中的文件系统格式区别及详解
  6. java代码实现声纹识别_govpr--golang实现的gmm-ubm算法的说话人识别(声纹识别)引擎...
  7. ​单张图像三维人脸重建必备入门face3d—3DMM
  8. oracle clustered索引,数据库表--index clustered table
  9. html中map标签的用法,HTML中的map和area标签
  10. restrict关键字用法