Python排序检测框数组时同步排序标签或保留原索引的方法
检测框排序时保持标签匹配的两种实现方案
你当前使用的「按y坐标做行聚类、同行按x坐标从左到右」的左上到右下排序逻辑无需调整,以下两种方案均可实现标签和检测框的对应关系不错乱:
方案1:绑定检测框与标签同步排序
核心逻辑是排序前将同位置的检测框、标签打包为元组,排序key仍然作用于检测框字段,排序完成后拆包即可得到顺序完全对应的两个数组。
可直接复用你现有代码,仅需修改排序段逻辑如下:
import numpy as np box_label = ["box1","box2","box3"] tmp_box = [] tmp_box.append([100,90,20,30]) #x,y,w,h tmp_box.append([90,80,25,30]) #x,y,w,h tmp_box.append([190,180,25,30]) #x,y,w,h tmp_box_np = np.array(tmp_box) max_height = np.max(tmp_box_np[::, 3]) nearest = max_height * 1.4 # 打包对应位置的检测框和标签 box_with_label = list(zip(tmp_box, box_label)) # 沿用原有排序规则,key取元组内的检测框字段 box_with_label.sort(key=lambda item: [int(nearest * round(float(item[0][1]) / nearest)), item[0][0]]) # 拆包得到排序后的检测框数组、标签数组 sorted_tmp_box, sorted_box_label = zip(*box_with_label) # 按需转回list类型 sorted_tmp_box = list(sorted_tmp_box) sorted_box_label = list(sorted_box_label)
方案2:排序时保留原始索引,通过索引映射标签
核心逻辑是不直接排序检测框数组,而是先构造「原始索引+检测框」的序列,排序后每个元素自带其在原数组中的下标,直接通过下标即可访问原box_label数组中对应的标签,无需修改原标签数组的顺序。
代码实现如下:
import numpy as np box_label = ["box1","box2","box3"] tmp_box = [] tmp_box.append([100,90,20,30]) #x,y,w,h tmp_box.append([90,80,25,30]) #x,y,w,h tmp_box.append([190,180,25,30]) #x,y,w,h tmp_box_np = np.array(tmp_box) max_height = np.max(tmp_box_np[::, 3]) nearest = max_height * 1.4 # 构造(原始索引, 检测框)的配对序列 index_with_box = list(enumerate(tmp_box)) # 沿用原有排序规则,key取元组内的检测框字段 index_with_box.sort(key=lambda item: [int(nearest * round(float(item[1][1]) / nearest)), item[1][0]]) # 提取排序后的检测框、对应原始索引 sorted_tmp_box = [item[1] for item in index_with_box] sorted_original_indices = [item[0] for item in index_with_box] # 访问标签示例:获取排序后第i个检测框对应的标签 # i = 0 # current_label = box_label[sorted_original_indices[i]]
方案选择参考
- 若后续逻辑需要直接使用排序后的标签列表,选方案1代码更简洁
- 若需要保留原始位置信息做额外逻辑处理、或不想改动原标签数组的存储顺序,选方案2灵活性更高
*注:两种方案完全复用你原有的排序key计算逻辑,不会改变原本检测框左上到右下的排序效果,无需调整行判定的阈值参数。
内容的提问来源于stack exchange,提问作者CodeDezk
相关产品推荐
相关产品推荐

