Arquivos
cuneiform-sign-detection-code/lib/detection/run_gen_ssd_detection.py
T
2020-11-19 12:18:53 +01:00

185 linhas
7.8 KiB
Python

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm
import torch
import torch.nn.functional as F
import torchvision.transforms as transforms
from ..datasets.cunei_dataset_segments import CuneiformSegments, get_segment_meta
from ..alignment.LineFragment import plot_boxes
from ..utils.path_utils import make_folder
from ..utils.torchcv.box_coder_retina import RetinaBoxCoder
from ..utils.torchcv.box_coder_fpnssd import FPNSSDBoxCoder
from ..utils.torchcv.box import box_nms
from ..utils.torchcv.evaluations.voc_eval import voc_eval
from ..evaluations.sign_evaluation_prep import (prepare_ssd_outputs_for_eval, prepare_ssd_gt_for_eval,
get_pred_boxes_df, get_gt_boxes_df)
from ..evaluations.sign_evaluation import eval_detector, eval_detector_on_collection
from ..evaluations.sign_evaluator import SignEvalBasic, SignEvalFast
def gen_ssd_detections(didx_list, dataset, saa_version, relative_path,
model_version, fpnssd_net, with_64, create_bg_class, device,
test_min_score_thresh, test_nms_thresh, eval_ovthresh,
save_detections, show_detections, with_4_aspects=False, verbose_mode=True, return_eval=False):
list_pred_boxes_df, list_gt_boxes_df = [], []
list_seg_ap, list_seg_name_with_anno = [], []
# setup evaluators
use_new_eval = True
num_classes = 240
# eval_basic = SignEvalBasic(model_version, saa_version, eval_ovthresh)
eval_fast = SignEvalFast(model_version, saa_version, tp_thresh=eval_ovthresh, num_classes=num_classes)
# iterate over segments
for didx in tqdm(didx_list, desc=saa_version):
# print(didx)
seg_im, gt_boxes, gt_labels = dataset[didx]
# access meta
seg_rec = dataset.get_seg_rec(didx)
image_name, scale, seg_bbox, _, view_desc = get_segment_meta(seg_rec)
# for plots
input_im = np.asarray(seg_im)
# prepare box coder
# box_coder = RetinaBoxCoder()
box_coder = FPNSSDBoxCoder(input_size=seg_im.size, with_64=with_64, with_4_aspects=with_4_aspects, create_bg_class=create_bg_class)
# prepare input
inputs = transforms.Compose([transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[1.0])])(seg_im)
inputs = inputs.unsqueeze(0)
with torch.no_grad():
loc_preds, cls_preds = fpnssd_net(inputs.to(device))
box_preds, label_preds, score_preds = box_coder.decode(
loc_preds.cpu().data.squeeze(),
F.softmax(cls_preds.squeeze(), dim=1).cpu().data,
score_thresh=test_min_score_thresh, nms_thresh=test_nms_thresh)
if show_detections:
# plot prediction
plt.figure(figsize=(10, 10))
plot_boxes(box_preds, confidence=score_preds)
plt.imshow(input_im, cmap='gray')
plt.grid(True, color='w', linestyle=':')
plt.show()
# vis_detections(input_im, box_preds, scores=score_preds, labels=label_preds,
# thresh=0.01, max_vis=300, figs_sz=(15, 15)) #lbl2lbl[labels]
# plt.show()
# convert detections to all boxes format
all_boxes = prepare_ssd_outputs_for_eval(box_preds, label_preds, score_preds)
if save_detections:
res_name = "{}{}".format(image_name, view_desc)
res_path = "{}results/results_ssd/{}/{}".format(relative_path, model_version, saa_version)
# check folder
make_folder(res_path)
if True:
# Save detections
# outfile = "{}/{}.npy".format(res_path, res_name)
# np.save(outfile, scores)
# save all_boxes
outfile = "{}/{}_all_boxes.npy".format(res_path, res_name)
np.save(outfile, all_boxes)
if gt_boxes is not None:
if 0:
if verbose_mode:
# [METHOD A]: evaluate for a single segment (in tensor format)
print(voc_eval([box_preds.clone()], [label_preds.clone()], [score_preds.clone()],
[gt_boxes.clone()], [gt_labels.clone()], None,
iou_thresh=eval_ovthresh, use_07_metric=False)['map'])
# convert gt to numpy format
gt_boxes, gt_labels = prepare_ssd_gt_for_eval(gt_boxes, gt_labels)
if use_new_eval:
list_seg_name_with_anno.append(image_name + view_desc)
if verbose_mode:
print(image_name, view_desc)
# standard mAP eval
# eval_basic.eval_segment(all_boxes, gt_boxes, gt_labels, seg_rec.segm_idx, verbose=verbose_mode)
# fast evaluation
eval_fast.eval_segment(all_boxes, gt_boxes, gt_labels, seg_rec.segm_idx, verbose=verbose_mode)
else:
if verbose_mode:
# [METHOD B]: evaluate mAP and print stats for a single segment
# (these results can strongly differ from collection-wise evaluation)
acc, df_stats = eval_detector(gt_boxes, gt_labels, all_boxes, ovthresh=eval_ovthresh)
# collect results
list_seg_ap.append(df_stats['ap'].mean())
list_seg_name_with_anno.append(image_name + view_desc)
# prepare full collection evaluation
list_pred_boxes_df.append(get_pred_boxes_df(all_boxes, seg_rec.segm_idx))
list_gt_boxes_df.append(get_gt_boxes_df(gt_boxes, gt_labels, seg_rec.segm_idx))
# full collection eval
if use_new_eval:
eval_fast.prepare_eval_collection()
df_stats, global_ap = eval_fast.eval_collection(verbose=verbose_mode)
if return_eval:
return global_ap, df_stats, eval_fast
else:
if verbose_mode:
return eval_fast.list_seg_mean_ap, list_seg_name_with_anno
else:
return global_ap, df_stats
else:
acc = 0
df_stats = pd.DataFrame()
if len(list_gt_boxes_df) > 0:
# [METHOD C]: compute mAP across all instances of individual classes
# (these results can strongly differ from segment-wise evaluation)
gt_boxes_df = pd.concat(list_gt_boxes_df, ignore_index=True)
pred_boxes_df = pd.concat(list_pred_boxes_df, ignore_index=True)
acc, df_stats = eval_detector_on_collection(gt_boxes_df, pred_boxes_df, ovthresh=eval_ovthresh)
if verbose_mode:
return list_seg_ap, list_seg_name_with_anno
else:
return acc, df_stats
def get_detections(fpnssd_net, device, seg_im, with_64, with_4_aspects, create_bg_class,
test_nms_thresh, test_min_score_thresh):
# prepare box coder
# box_coder = RetinaBoxCoder()
box_coder = FPNSSDBoxCoder(input_size=seg_im.size, with_64=with_64, with_4_aspects=with_4_aspects,
create_bg_class=create_bg_class)
# prepare input
inputs = transforms.Compose([transforms.Lambda(lambda x: x.convert('L')),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[1.0])])(seg_im)
inputs = inputs.unsqueeze(0)
with torch.no_grad():
loc_preds, cls_preds = fpnssd_net(inputs.to(device))
box_preds, label_preds, score_preds = box_coder.decode(
loc_preds.cpu().data.squeeze(),
F.softmax(cls_preds.squeeze(), dim=1).cpu().data,
score_thresh=test_min_score_thresh, nms_thresh=test_nms_thresh)
# convert detections to all boxes format
all_boxes = prepare_ssd_outputs_for_eval(box_preds, label_preds, score_preds)
return all_boxes