获得最大置信度的边界框 pandas opencv python

Posted

技术标签:

【中文标题】获得最大置信度的边界框 pandas opencv python【英文标题】:get bounding boxes with maximum confidence pandas opencv python 【发布时间】:2020-11-03 15:12:16 【问题描述】:

我有一个符号检测算法,可以从模板匹配/更快的 rcnn 输出,也可以将两者的结果结合起来,得到坐标filename,xmin, ymin, xmax, ymax, class, confidence

问题是同一对象出现多个边界框。 我如何有效地过滤这些框并仅获得对删除重复区域具有最大置信度的框。

示例图片:

样本坐标数据框:

df=pd.DataFrame('filename':['dummyfile.jpg']*5, class=['cube']*5, xmin':[88,87,65,492,470],'ymin':[87,111,110,187,184],'xmax':[197,198,174,603,578],
              'ymax':[198,220,221,295,295],'confidence':[0.99,0.88,0.95,0.89,0.83])
  class  confidence       filename  xmax  xmin  ymax  ymin
0  cube        0.99  dummyfile.jpg   197    88   198    87
1  cube        0.88  dummyfile.jpg   198    87   220   111
2  cube        0.95  dummyfile.jpg   174    65   221   110
3  cube        0.89  dummyfile.jpg   603   492   295   187
4  cube        0.83  dummyfile.jpg   578   470   295   184

图像表示:

预期输出:

我尝试使用置信度作为阈值进行过滤,但它会影响解决方案的召回率。 如何利用 IoU 删除这些重复项?

【问题讨论】:

这里有一些类似的实现,你可以参考:***.com/questions/58995949/…pyimagesearch.com/2016/11/07/… 【参考方案1】:

这是我想出的解决方案。

为每个边界框创建唯一键

df['key']=df['xmin'].astype(str)+'_'+df['ymin'].astype(str)+'_'+df['xmax'].astype(str)+'_'+df['ymax'].astype(str)

根据文件名对所有行进行外连接。 (用于计算 IoU)

###copy df
df_1=df.copy()

###Renaming df columns with _1 suffix
df_cols=df.columns.tolist()
df_cols.remove('filename')
new_cols=[col+'_1' for col in df_cols]
new_col_dict=dict(zip(df_cols,new_cols))
df_1.rename(columns=new_col_dict,inplace=True)

### Outer joining both dataframes
newdf=pd.merge(df,df_1,'outer',on='filename')

外连接示例:

查找每行IoU的功能


def IOU(df):
    '''funtion to calulcate IOU within rows of dataframe'''
    # determining the minimum and maximum -coordinates of the intersection rectangle
    xmin_inter = max(df.xmin, df.xmin_1)
    ymin_inter = max(df.ymin, df.ymin_1)
    xmax_inter = min(df.xmax, df.xmax_1)
    ymax_inter = min(df.ymax, df.ymax_1)

    # calculate area of intersection rectangle
    inter_area = max(0, xmax_inter - xmin_inter + 1) * max(0, ymax_inter - ymin_inter + 1)

    # calculate area of actual and predicted boxes
    actual_area = (df.xmax - df.xmin + 1) * (df.ymax - df.ymin + 1)
    pred_area = (df.xmax_1 - df.xmin_1 + 1) * (df.ymax_1 - df.ymin_1+ 1)

    # computing intersection over union
    iou = inter_area / float(actual_area + pred_area - inter_area)

    # return the intersection over union value
    return iou

计算每一行的IoU并用ioU过滤行
newdf['iou']= newdf.apply(IOU, axis = 1)
### filtering all iou<0.4
newdf=newdf[newdf['iou']>=0.4]

为每个键获得最佳匹配

一旦我们有了 IoU 匹配数据框,解析每个唯一的键边界框, 获得每个唯一键的最大置信度值,iou>0.4

best_df=pd.DataFrame()
for i, v in df.iterrows():
    key=v['key']
    iou_match=newdf[newdf['key']==key]
    iou_match.sort_values('confidence_1',ascending=False,inplace=True)
    iou_match=iou_match.reset_index()
    best_match=iou_match.loc[0,['filename','class_1','xmin_1','ymin_1','xmax_1','ymax_1','confidence_1']]
    best_df=best_df.append(best_match,ignore_index=True)

best_df 现在看起来像:

  class_1  confidence_1       filename  xmax_1  xmin_1  ymax_1  ymin_1
0  cube          0.99  dummyfile.jpg   197.0    88.0   198.0    87.0
1  cube          0.99  dummyfile.jpg   197.0    88.0   198.0    87.0
2  cube          0.99  dummyfile.jpg   197.0    88.0   198.0    87.0
3  cube          0.89  dummyfile.jpg   603.0   492.0   295.0   187.0
4  cube          0.89  dummyfile.jpg   603.0   492.0   295.0   187.0

删除重复项以获得唯一的最佳匹配

best_df.drop_duplicates(inplace=True)

最终结果:

  class_1  confidence_1       filename  xmax_1  xmin_1  ymax_1  ymin_1
0  cube          0.99  dummyfile.jpg   197.0    88.0   198.0    87.0
3  cube          0.89  dummyfile.jpg   603.0   492.0   295.0   187.0

【讨论】:

【参考方案2】:

而不是迭代和 drop_duplicates,应该更容易进行过滤,然后进行 groupby 和 max 聚合以选择具有最高置信度的键(同时确保其排列行被过滤掉)。

best_df = df.apply(lambda g: g['confidence']>g['confidence_1']).groupby('key').filter(agg('confidence_1':'max')

【讨论】:

以上是关于获得最大置信度的边界框 pandas opencv python的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 的边界框

Tesseract 的 hOCR 输出是不是真的包含每个字符的边界框和置信度?

带有opencv的手写数字边界框

opencv-python:为啥检测到不正确的边界框(几个边界框)?

OpenMMLab 目标检测

youcans 的 OpenCV 例程200篇199.轮廓的外接边界框