状态类算法复杂排序输出

对于目标检测任务中对某一类的检测结果进行输出的时候,一般都是无序的,很明显这样子很难满足的我们的需求,我们更喜欢他是这样子输出的:

👇 

我们可以看到——”按顺序输出结果“中的字段是完美的和上面图片中的识别结果一一对应的,这其实也很容易做到。

我们只需要把这些个矩形框一个个抽出来,放在一张白纸上面,如下图所示:

NOTE:下图是模拟的复杂样例,并非上图中的矩形框抽出来。

红色箭头代表的就是正确的排序方式,看到这里有一些朋友可能已经有了思路,我这边使用了数据结构算法中的图论算法,我们可以把上面四个箭头当作四层, 每一层从根节点也就是最左边的矩形框出发进行连边操作,每一次连边必须满足以下要求:

  • 连边的矩形框与上一个节点的Iou!=0
  • 连边的矩形框的质心必须处于上一个节点质心的右边
  • 连边的矩形框的质心必须与上一个节点的质心有着距离最近的关系。

根据这些约束条件,我们可以选取最左上的节点当作第一层的根节点,开始我们的连边操作:

当最有一个节点的最右边已经没有了节点的时候,至此我们结束了第一层搜索,删掉第一层连接的所有矩形框,进入第二层搜索。由于删掉了第一层所有的矩形框,第二层的第一个节点又变成了最左上角的节点,选取她开始第二轮的遍历连边操作。

以此类推,我们便完成了所有排序的工作:

放上一些彩蛋图: 

🍉参考实现代码如下:

from collections import deque
import math

def draw(points):
    import matplotlib.pyplot as plt

    # 中心点坐标
    # points = [(67.0, 72.0), (172.5, 70.0), (274.5, 79.5), (380.0, 79.0), (489.5, 149.5), (73.5, 241.0), 
    #           (185.0, 249.0), (386.5, 239.0), (604.5, 128.5), (719.5, 151.0), (209.5, 403.0), (374.0, 393.0), 
    #           (180.5, 562.0), (288.5, 568.5), (394.5, 573.5)]
    # 提取 x 和 y 坐标
    x_coords, y_coords = zip(*points)

    # 创建一个散点图
    plt.scatter(x_coords, y_coords, marker='o', color='blue')

    # 添加坐标标签
    for i, point in enumerate(points):
        plt.annotate(f"{i, point}", (x_coords[i], y_coords[i]), textcoords="offset points", xytext=(0,10), ha='center', fontsize=8)

    # 设置图的标题和坐标轴标签
    plt.title("centre plot")
    plt.xlabel("X")
    plt.ylabel("Y")

    # 设置坐标轴原点为左上角
    plt.gca().invert_yaxis()

    # 显示图
    plt.grid()
    plt.show()
    plt.savefig("switch_sort.jpg",dpi=300)


def convert_to_center(xmin, ymin, xmax, ymax):
    center_x = (xmin + xmax) / 2.0
    center_y = (ymin + ymax) / 2.0
    return (int(center_x),int(center_y))

def cal_dist(point1, point2):
    x1, y1 = point1
    x2, y2 = point2
    distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
    return distance

def cal_xIou(ret1, ret2):
    x1,y1 = convert_to_center(*ret1)
    x2,y2 = convert_to_center(*ret2)
    xmin1,ymin1,xmax1,ymax1 = ret1
    xmin2,ymin2,xmax2,ymax2 = ret2
    # print(ymin1, ymin2, ymax1, ymax2)
    if ymax1 < ymin2 or ymax2 < ymin1:
        return False
    else:
        return True

# def find_right_shortestPoint(centres_coordinates, now_point):
#     shortest_dist = float('inf')
#     for iter_point in centres_coordinates:
#         dist = cal_dist(now_point, iter_point)
#         if dist < shortest_dist and dist != 0:
#             if now_point[1] < iter_point[1]:
#                 return iter_point
#     return ValueError("找不到距离最近的框,是不是总共只有一个框!")

def find_shortestPoint(bboxes, centres_coordinates, backup_centres_coordinates, now_point, seen):
    shortest_dist = float('inf')
    target=(-1,-1)
    for iter_point in centres_coordinates:
        if iter_point in seen:
            continue
        # print(now_point, iter_point)
        if now_point[0] < iter_point[0]:
            dist = cal_dist(now_point, iter_point)
            # print(dist)
            if dist < shortest_dist and dist != 0:

                nowPoint_idx = backup_centres_coordinates.index(now_point)
                iterPoint_idx = backup_centres_coordinates.index(iter_point)
                nowBbox = bboxes[nowPoint_idx]
                iterBbox = bboxes[iterPoint_idx]

                # print(nowBbox, iterBbox)
                if not cal_xIou(nowBbox, iterBbox):
                    continue
                shortest_dist = dist
                target = iter_point          
    return target

def main_layers(bboxes):
    #[ [xmin,ymin,xmax,ymax]]
    backup_bboxes = bboxes.copy()
    centres_coordinates = []
    for bbox in bboxes:
        centre = convert_to_center(*bbox)
        centres_coordinates.append(centre)
    length_data = len(bboxes)
    backup_centres_coordinates = centres_coordinates.copy()
    # backup_centres_coordinates = centres_coordinates.copy()
    max_h, max_w = 0, 0
    for cc in centres_coordinates:
        max_h = max(max_h, cc[0])
        max_w = max(max_h, cc[1])

    # draw(centres_coordinates)   
    
    grap = [[0 for _ in range(int(max_w + 10))] for _ in range(int(max_h) + 10)]
    for cen in centres_coordinates:
        cen_x, cen_y = int(cen[0]), int(cen[1])
        grap[cen_x][cen_y] = 1
    
    result = {

    }
    queue = []
    seen = set()
    start_point = min(centres_coordinates, key=lambda point: (point[0], -point[1]))
    queue.append(start_point)
    seen.add(start_point)
    layer = 1
    iter_idx = 1
    print("Now Layer:{} start point:{}".format(layer, start_point))
 
    while iter_idx <= length_data:
        now_point = queue[-1]
        iter_point = find_shortestPoint(backup_bboxes, centres_coordinates, backup_centres_coordinates,now_point, seen)
        judge=True
        if iter_point[0]==-1:
            judge = False
        
        if judge:
            queue.append(iter_point)
            iter_idx += 1
            seen.add(iter_point)
        else:
            result[layer] = queue
            if iter_idx == length_data:
                break
            layer += 1
            for q in queue:
                # print(q)    
                # print(centres_coordinates)
                # backup_bboxes.remove(centres_coordinates.index(q))
                centres_coordinates.remove(q)
                
            queue = []
            seen = set()
            start_point = min(centres_coordinates, key=lambda point: (point[0], -point[1]))
            queue.append(start_point)
            seen.add(start_point)
            iter_idx += 1
            print("Now Layer:{} start point:{}".format(layer, start_point))

    sorted_dict = dict(sorted(result.items(),key=lambda item: item[1][0][1]))
    for key in sorted_dict:
        print(key, sorted_dict[key])
    return sorted_dict

🍉使用方法:

bboxes = [[box[0], box[1], box[0]+box[2], box[1]+box[3]] for box in used_res]
                    sorted_dict = main_layers(bboxes)
                    centres_coordinates = []
                    for bbox in bboxes:
                        centre = convert_to_center(*bbox)
                        centres_coordinates.append(centre)

                    sorted_used_res = []
                    for layer in sorted_dict:
                        for iter_column in sorted_dict[layer]:
                            iter_index = centres_coordinates.index(iter_column)
                            sorted_used_res.append(used_res[iter_index])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/211941.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis 安装部署

文章目录 1、前言2、安装部署2.1、单机模式2.1.1、通过 yum 安装&#xff08;不推荐&#xff0c;版本老旧&#xff09;2.1.1、通过源码编译安装&#xff08;推荐&#xff09; 2.2、主从模式2.3、哨兵模式2.4、集群模式2.5、其他命令2.6、其他操作系统 3、使用3.1、Java 代码 —…

吉他初学者学习网站搭建系列(4)——如何查询和弦图

文章目录 背景实现ChordDbvexchords 背景 作为吉他初学者&#xff0c;如何根据和弦名快速查到和弦图是一个必不可少的功能。以往也许你会去翻和弦的书籍查询&#xff0c;像查新华字典那样&#xff0c;但是有了互联网后我们不必那样&#xff0c;只需要在网页上输入和弦名&#…

react之ReactRouter的使用

react之ReactRouter的使用 一、环境搭建二、抽象路由模块三、路由导航3.1 声明式导航3.2 编程式导航 四、导航传参4.1 searchParams 传参4.2 params 传参 五 、嵌套路由配置六、默认二级路由七、404页面配置八、俩种路由模式 一、环境搭建 1.创建项目安装依赖 npx create-rea…

2024年美国大学生数学建模竞赛(MCM/ICM)论文写作方法指导

一、前言 谈笑有鸿儒&#xff0c;往来无白丁。鸟宿池边树&#xff0c;僧敲月下门。士为知己者死&#xff0c;女为悦己者容。吴楚东南坼&#xff0c;乾坤日夜浮。剪不断&#xff0c;理还乱&#xff0c;是离愁&#xff0c;别是一番滋味在心头。 重要提示&#xff1a;优秀论文的解…

Matlab 加权均值质心计算(WMN)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 思路很简单,即将之前的均值中心,引入相关的权重函数(通常与距离有关),以此为每个点进行赋权,最后即可得到一个加权均值中心: 二、实现代码 %% ********<

[二分查找]LeetCode2009 :使数组连续的最少操作数

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个整数数组 nums 。每一次操作中&#xff0c;你可以将 nums 中 任意 一个元素替换成 任意 整数。 如果 nums 满足以下条件&#xff0c;那么它是 连续的 …

ChatGPT 上线一周年

一年前&#xff0c;ChatGPT 正式上线&#xff0c;这无疑是个革命性的时刻&#xff0c;仅仅 6 周&#xff0c;ChatGPT 用户量达到 1 个亿。 这一年元宇宙作为概念垃圾彻底进入下水道&#xff0c;而 ChatGPT 和 AI 则席卷全球。 仅仅这一年&#xff0c;依托于 ChatGPT&#xff…

SmartSoftHelp8,数据库事务测试工具

SQL数据库事务测试工具 SQL数据库事务回滚测试工具 下载地址&#xff1a; https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组&#xff0c;分别求出两个数组的和&#xff0c;并 最小化 两个数组和之 差的绝对…

nodejs微信小程序+python+PHP贵州旅游系统的设计与实现-计算机毕业设计推荐MySQL

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

巧用MACD精准抄底和逃顶

一、认识MACD MACD又称平滑异同移动平均线&#xff0c;是由美国投资家杰拉尔德阿佩尔在 20 世纪 70 年代末提出的。 MACD 指标的设计基于MA均线原理&#xff0c;是对收盘价进行平滑处理&#xff08;求出加权平均值&#xff09;后的一种趋向类指标。它是股票交易中一种常见的技术…

IDEA2023安装教程(超详细)

文章目录 前言安装IntelliJ IDEA1. 下载IntelliJ IDEA2. 运行安装程序3. 选择安装路径4. 选择启动器设置5. 等待安装完成6. 启动IntelliJ IDEA7. 配置和设置8. 激活或选择许可证9. 开始使用 总结 前言 随着软件开发的不断发展&#xff0c;IntelliJ IDEA成为了许多开发人员首选…

pygame实现贪吃蛇小游戏

import pygame import random# 游戏初始化 pygame.init()# 游戏窗口设置 win_width, win_height 800, 600 window pygame.display.set_mode((win_width, win_height)) pygame.display.set_caption("Snake Game")# 颜色设置 WHITE (255, 255, 255) BLACK (0, 0, 0…

avue-tabs设置默认选中的tab

文章目录 一、问题二、解决三、最后 一、问题 最近在用avue这个UI框架来开发页面&#xff0c;有用到avue-tabs这个tab切换组件。结果竟然发现element-ui中el-tabs的v-model在avue-tabs中竟然是没有用的&#xff0c;无法设置默认选中哪个tab。avue这个基于element-ui开发的UI框…

【计算机网络笔记】802.11无线局域网

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

制作一个RISC-V的操作系统二-RISC-V ISA介绍

文章目录 ISA的基本介绍啥是ISA为什么要设计ISACISCvsRISCISA的宽度知名ISA介绍 RISC-V历史和特点RISC-V发展RISC-V ISA 命名规范模块化的ISA通用寄存器Hart特权级别Control and Status Register&#xff08;CSR&#xff09;内存管理与保护异常和中断 ISA的基本介绍 啥是ISA …

十大经典系统架构设计面试题

十大经典系统架构设计面试题_架构_程序员石磊_InfoQ写作社区翻译自&#xff1a;https://medium.com/geekculture/top-10-system-design-interview-questions-10f7b5ea123d在我作为微软和Facebhttps://xie.infoq.cn/article/4c0c9328a725a76922f6547ad 任何 SDI 问题的提示 通过…

Elasticsearch:什么是自然语言处理(NLP)?

自然语言处理定义 自然语言处理 (natural language processing - NLP) 是人工智能 (AI) 的一种形式&#xff0c;专注于计算机和人们使用人类语言进行交互的方式。 NLP 技术帮助计算机使用我们的自然交流模式&#xff08;语音和书面文本&#xff09;来分析、理解和响应我们。 自…

OpenCV-Python:计算机视觉介绍

目录 1.背景 2.计算机视觉发展历史 3.计算机视觉主要任务 4.计算机视觉应用场景 5.知识笔记 1.背景 OpenCV是计算机视觉的一个框架&#xff0c;想要学习OpenCV&#xff0c;需要对计算机视觉有一个大致的了解。计算机视觉是指通过计算机技术和算法来模拟人类视觉系统的能力…

Go语言实现深度学习的正向传播和反向传播

文章目录 开发前言开发理论图解理论数据类型数学函数数据节点统一抽象变量数据节点常量数据节点单目运算封装双目运算封装算子节点统一抽象基础算子加法算子减法算子乘法算子除法算子指数算子对数算子正切算子正弦算子余弦算子数据流图正向传播反向传播运行示例开发总结 开发前…