示例#1
0
def test_ctdet_decode():
    np.random.seed(32)
    hm = np.random.randn(2, 64, 64, 80)
    reg = np.random.randn(2, 64, 64, 2) * 10.0
    wh = np.random.randn(2, 64, 64, 2) * 20.0

    keras_hm = K.constant(hm)
    keras_reg = K.constant(reg)
    keras_wh = K.constant(wh)

    keras_detections = K.eval(
        _ctdet_decode(keras_hm, keras_reg, keras_wh, output_stride=1))

    gold_fn = 'path_for_colab/tests/data/ctdet_decode_gold.p'
    if not os.path.exists(gold_fn):
        import torch as th
        import sys
        sys.path.append(os.path.expanduser('~/Pytorch/CenterNet/src'))
        from lib.models.decode import ctdet_decode  # noqa
        py_hm = th.from_numpy(hm.transpose(0, 3, 1, 2)).float()
        py_hm.sigmoid_()
        py_reg = th.from_numpy(reg.transpose(0, 3, 1, 2)).float()
        py_wh = th.from_numpy(wh.transpose(0, 3, 1, 2)).float()
        py_detections = ctdet_decode(py_hm, py_reg, py_wh).detach().numpy()
        with open(gold_fn, 'wb') as f:
            pickle.dump(py_detections, f)
    else:
        with open(gold_fn, 'rb') as f:
            py_detections = pickle.load(f)
    assert np.allclose(keras_detections, py_detections)
    def save_result1(self, outputs, batch,
                     results):  # 这里的outputs包含model输出的所有特征图(3个特征图)
        # 对每一个output特征图都计算dets_out,然后将3个dets_out整合起来,根据score来排序,然后用NMS或者其他方法来过滤!!!

        dets_list = []
        dets_score_list = []
        for idx in range(len(outputs)):
            output = outputs[idx]
            reg = output['reg'] if self.opt.reg_offset else None
            dets = ctdet_decode(output['hm'],
                                output['wh'],
                                reg=reg,
                                cat_spec_wh=self.opt.cat_spec_wh,
                                K=self.opt.K)
            dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])
            # print(type(dets), dets.shape)
            dets_list.append(dets)

        dets_300 = np.concatenate(
            (dets_list[0], dets_list[1], dets_list[2]),
            axis=1)  # 将3个dets:array[1,100,6]连接起来成为dets_300:array[1,300,6]
        dets_300_sort = dets_300.copy()
        array_for_sort = dets_300.reshape(
            -1, dets.shape[2])[:, :5]  # 将dets_300的最后一列改变成score,方便下面排序
        sort_idx = np.lexsort(
            -array_for_sort.T)  # sort_idx是dets_300按照score从大到小排序的索引
        # print(array_for_sort.shape, sort_idx)
        for key, item in enumerate(sort_idx):
            dets_300_sort[0][key] = dets_300[0][
                item]  # 将排序后的numpy数组保存到 dets_300_sort
        # print(dets_300_sort.shape, dets_300_sort[0][0][4],dets_300_sort[0][101][4])
        # dets_300_sort = dets_300_sort[:,:100,:] # 检测结果只取前100??
        dets = dets_300_sort  # 这个命名只是为了不改下面的两个语句中的变量名

        dets_outs = ctdet_post_process(dets.copy(),
                                       batch['meta']['c'].cpu().numpy(),
                                       batch['meta']['s'].cpu().numpy(),
                                       output['hm'].shape[2],
                                       output['hm'].shape[3],
                                       output['hm'].shape[1])
        for j in range(1, self.opt.num_classes +
                       1):  # 给数组reshape一下,要不然不符合NMS需要输入2维数组的输入要求
            dets_outs[0][j] = np.array(dets_outs[0][j],
                                       dtype=np.float32).reshape(-1, 5)
        # print(type(dets_outs),len(dets_outs[0]))
        results_nms = {}
        for j in range(1, self.opt.num_classes + 1):
            results_nms[j] = np.concatenate(
                [dets_out[j] for dets_out in dets_outs],
                axis=0).astype(np.float32)
            # print(j, results_nms[j])
            soft_nms(results_nms[j], Nt=0.5, method=2)
        # print(111, type(dets_outs[0]), dets_outs[0].keys())
        # print(222, type(results_nms), results_nms.keys())   # results_nms是dets_outs[0]经过NMS之后得到的结果
        # results[batch['meta']['img_id'].cpu().numpy()[0]] = dets_outs[0]
        results[batch['meta']['img_id'].cpu().numpy()[0]] = results_nms
示例#3
0
 def save_result(self, output, batch, results):
     reg = output['reg'] if self.opt.reg_offset else None
     dets = ctdet_decode(output['hm'],
                         output['wh'],
                         reg=reg,
                         cat_spec_wh=self.opt.cat_spec_wh,
                         K=self.opt.K)
     dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])
     dets_out = ctdet_post_process(dets.copy(),
                                   batch['meta']['c'].cpu().numpy(),
                                   batch['meta']['s'].cpu().numpy(),
                                   output['hm'].shape[2],
                                   output['hm'].shape[3],
                                   output['hm'].shape[1])
     results[batch['meta']['img_id'].cpu().numpy()[0]] = dets_out[0]
    def process(self, images, return_time=False):
        with torch.no_grad():
            output = self.model(images)[-1]
            hm = output['hm'].sigmoid_()
            wh = output['wh']
            # reg = output['reg']
            torch.cuda.synchronize()
            forward_time = time.time()
            # dets = ctdet_decode(hm, wh, reg=reg)
            dets = ctdet_decode(hm, wh)

        if return_time:
            return output, dets, forward_time
        else:
            return output, dets
    def debug(self, batch, output, iter_id):
        opt = self.opt
        reg = output['reg'] if opt.reg_offset else None
        dets = ctdet_decode(output['hm'],
                            output['wh'],
                            reg=reg,
                            cat_spec_wh=opt.cat_spec_wh,
                            K=opt.K)
        dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])
        dets[:, :, :4] *= opt.down_ratio
        dets_gt = batch['meta']['gt_det'].numpy().reshape(1, -1, dets.shape[2])
        dets_gt[:, :, :4] *= opt.down_ratio
        for i in range(1):
            debugger = Debugger(dataset=opt.dataset,
                                ipynb=(opt.debug == 3),
                                theme=opt.debugger_theme)
            img = batch['input'][i].detach().cpu().numpy().transpose(1, 2, 0)
            img = np.clip(((img * opt.std + opt.mean) * 255.), 0,
                          255).astype(np.uint8)
            pred = debugger.gen_colormap(
                output['hm'][i].detach().cpu().numpy())
            gt = debugger.gen_colormap(batch['hm'][i].detach().cpu().numpy())
            debugger.add_blend_img(img, pred, 'pred_hm')
            debugger.add_blend_img(img, gt, 'gt_hm')
            debugger.add_img(img, img_id='out_pred')
            for k in range(len(dets[i])):
                if dets[i, k, 4] > opt.center_thresh:
                    #        add_coco_bbox(bbox, cat, conf=1, show_txt=True, img_id='default'):
                    debugger.add_coco_bbox(dets[i, k, :4],
                                           dets[i, k, -1],
                                           dets[i, k, 4],
                                           img_id='out_pred')

            debugger.add_img(img, img_id='out_gt')
            for k in range(len(dets_gt[i])):
                if dets_gt[i, k, 4] > opt.center_thresh:
                    #        add_coco_bbox(bbox, cat, conf=1, show_txt=True, img_id='default'):
                    debugger.add_coco_bbox(dets_gt[i, k, :4],
                                           dets_gt[i, k, -1],
                                           dets_gt[i, k, 4],
                                           img_id='out_gt')

            if opt.debug == 4:
                debugger.save_all_imgs(opt.debug_dir,
                                       prefix='{}'.format(iter_id))
            else:
                debugger.show_all_imgs(pause=True)
示例#6
0
    def process(self, images, return_time=False):
        with torch.no_grad():
            output = self.model(images)[-1]
            hm = output['hm'].sigmoid_()
            wh = output['wh']
            reg = output['reg'] if self.opt.reg_offset else None
            if self.opt.flip_test:
                hm = (hm[0:1] + flip_tensor(hm[1:2])) / 2
                wh = (wh[0:1] + flip_tensor(wh[1:2])) / 2
                reg = reg[0:1] if reg is not None else None
            torch.cuda.synchronize()
            forward_time = time.time()
            dets = ctdet_decode(hm, wh, reg=reg, K=self.opt.K)

        if return_time:
            return output, dets, forward_time
        else:
            return output, dets
 def save_result(self, output, batch,
                 results):  # 能不能尽量不改这里面的小函数,只改变针对函数的输入?????
     # print(output['hm'].size(), output['wh'].size(), output['reg'].size())
     #     [1, 20, 128, 128]      [1, 2, 128, 128]     [1, 2, 128, 128]
     reg = output[
         'reg'] if self.opt.reg_offset else None  # self.opt.reg_offset = True
     dets = ctdet_decode(output['hm'],
                         output['wh'],
                         reg=reg,
                         cat_spec_wh=self.opt.cat_spec_wh,
                         K=self.opt.K)
     # print(dets.size()) #[1, 100, 6] ,其中的6代表了 [tlx, tly, brx, bry, scores, clses], 按照score的高低排序
     dets = dets.detach().cpu().numpy().reshape(
         1, -1, dets.shape[2])  # detach()用来切断梯度的传播
     # print(dets.shape)  #(1, 100, 6)
     dets_out = ctdet_post_process(dets.copy(),
                                   batch['meta']['c'].cpu().numpy(),
                                   batch['meta']['s'].cpu().numpy(),
                                   output['hm'].shape[2],
                                   output['hm'].shape[3],
                                   output['hm'].shape[1])
     # print(len(dets_out), dets_out) # len(dets_out) = 1  ; dets_out = [{1: [...], 2: [], 3: [[130.917, 491.190, 285.635, 504.33, 0.797]], 4: [...],...}, 20: [...]]
     results[batch['meta']['img_id'].cpu().numpy()[0]] = dets_out[0]
示例#8
0
    def val(self, epoch, data_loader):
        model_with_loss = self.model_with_loss
        if len(self.opt.gpus) > 1:
            model_with_loss = self.model_with_loss.module
        model_with_loss.eval()
        torch.cuda.empty_cache()
        opt = self.opt
        results = {}
        data_time, batch_time = AverageMeter(), AverageMeter()
        avg_loss_stats = {l: AverageMeter() for l in self.loss_stats}
        num_iters = len(data_loader) if opt.num_iters < 0 else opt.num_iters
        bar = Bar('{}/{}'.format(opt.task, opt.exp_id), max=num_iters)
        end = time.time()
        for iter_id, batch in enumerate(data_loader):
            if iter_id >= num_iters:
                break
            data_time.update(time.time() - end)

            for k in batch:
                if k != 'meta':
                    batch[k] = batch[k].to(device=opt.device,
                                           non_blocking=True)
            output, loss, loss_stats = model_with_loss(batch)

            results.setdefault('img_id', []).extend(batch['meta']['img_id'])
            boxes = ctdet_decode(output['hm'],
                                 output['wh'],
                                 output['reg'],
                                 K=self.opt.K)
            meta = batch['meta']
            c = meta['c'].numpy()
            s = meta['s'].numpy()
            _, _, out_h, out_w = output['hm'].shape
            dets = ctdet_post_process(boxes.cpu().numpy(), [c], [s], out_h,
                                      out_w, opt.num_classes)
            # breakpoint()
            results.setdefault('detections', []).extend(dets)
            loss = loss.mean()
            batch_time.update(time.time() - end)
            end = time.time()

            Bar.suffix = '{phase}: [{0}][{1}/{2}]|Tot: {total:} |ETA: {eta:} '.format(
                epoch,
                iter_id,
                num_iters,
                phase='val',
                total=bar.elapsed_td,
                eta=bar.eta_td)
            for l in avg_loss_stats:
                # breakpoint()
                loss_t = loss_stats[l] or torch.zeros(1)
                avg_loss_stats[l].update(loss_t.mean().item(),
                                         batch['input'].size(0))
                Bar.suffix += '|{} {:.4f} '.format(l, avg_loss_stats[l].avg)
                self.val_writer.add_scalar(l, avg_loss_stats[l].avg,
                                           self.global_steps, 1)

            if not opt.hide_data_time:
                Bar.suffix = Bar.suffix + '|Data {dt.val:.3f}s({dt.avg:.3f}s) ' \
                                          '|Net {bt.avg:.3f}s'.format(dt=data_time, bt=batch_time)
            if opt.print_iter > 0:
                if iter_id % opt.print_iter == 0:
                    print('{}/{}| {}'.format(opt.task, opt.exp_id, Bar.suffix))
            else:
                bar.next()

            if opt.debug > 0:
                self.debug(batch, output, iter_id)

            if opt.test:
                self.save_result(output, batch, results)
            del output, loss, loss_stats
            # break
        ret = {k: v.avg for k, v in avg_loss_stats.items()}

        for l in avg_loss_stats:
            self.val_writer.add_scalar(l, avg_loss_stats[l].avg,
                                       self.global_steps)
        bar.next()
        bar.finish()
        ret['time'] = bar.elapsed_td.total_seconds() / 60.
        return ret, results