获得最大置信度的边界框 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]
为每个键获得最佳匹配
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的主要内容,如果未能解决你的问题,请参考以下文章
Tesseract 的 hOCR 输出是不是真的包含每个字符的边界框和置信度?