получить ограничивающие рамки с максимальной уверенностью pandas opencv python - PullRequest
1 голос
/ 14 июля 2020

У меня есть алгоритм обнаружения символов, который может выводиться из сопоставления шаблонов / более быстрого rcnn или объединения результатов обоих из них, что дает мне координаты filename,xmin, ymin, xmax, ymax, class, confidence.

Проблема в том, что есть наличие нескольких ограничивающих рамок для одного и того же объекта. Как я могу эффективно отфильтровать эти поля и получить только поля с максимальной уверенностью в области удаления дубликатов.

образец Изображение:

sample image

The sample coordinate data frame:

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

Изображение:

initialinput

Expected output:

ожидаемый результат

Я пробовал фильтровать, используя достоверность в качестве порога, но это повлияет на отзыв решения. Как удалить эти дубликаты с помощью IoU?

1 Ответ

2 голосов
/ 22 июля 2020

Это решение, которое я придумал.

Создание уникального ключа для каждой ограничивающей рамки

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')

Пример внешнего соединения:

sample outer join

Function to find IoU of each row


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 < 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...