예제 #1
0
def predict_imgs(model, img_folder, bbox_folder, output_file, normalize,
                 detection_thresh):
    detections = {}
    for file in os.listdir(bbox_folder):
        dets = load(os.path.join(bbox_folder, file))
        assert dets.shape[1] == 5
        img_name = file[:-4]  # remove extension
        detections[img_name] = dets

    valid_dataset = hrnet_dataset.ImgFolderDataset(cfg, img_folder, detections,
                                                   normalize, detection_thresh)
    valid_loader = torch.utils.data.DataLoader(
        valid_dataset,
        batch_size=cfg.TEST.BATCH_SIZE_PER_GPU * len(cfg.GPUS),
        shuffle=False,
        pin_memory=True)

    start = time.time()
    preds, boxes, image_names, orig_boxes = predict(cfg, valid_loader,
                                                    valid_dataset, model)
    end = time.time()
    print("Time in prediction: " + str(end - start))

    ensuredir(os.path.dirname(output_file))
    valid_dataset.rescore_and_save_result(output_file, preds, boxes,
                                          image_names, orig_boxes)
예제 #2
0
def main(args):
    assert args.output.endswith('.pkl'), "Output file must be a pkl file"

    # Clear up temp folder if it exists
    if os.path.exists(args.tmp_folder) and not args.tpn_only:
        shutil.rmtree(args.tmp_folder)

    frame_dir = os.path.join(args.tmp_folder, 'frames')
    bbox_dir = os.path.join(args.tmp_folder, 'bboxes')
    keypoint_file = os.path.join(args.tmp_folder, 'keypoints.json')

    if not args.tpn_only:
        # split to frames:
        ensuredir(os.path.join(args.tmp_folder, 'frames'))
        out = os.system("ffmpeg -i %s -qscale:v 2 %s/frames/img_%%06d.jpg" %
                        (args.vid_path, args.tmp_folder))
        if out != 0:
            print("could not split to frames, error code: " + str(out))
            sys.exit(1)

        # Mask-RCNN
        maskrcnn_bboxes.predict_imgs(frame_dir, bbox_dir)

        # hrnet
        hrnet_predict.predict(
            '../hrnet/experiments/coco/hrnet/w32_256x192_adam_lr1e-3.yaml',
            frame_dir, bbox_dir, keypoint_file)

    # Run TPN
    print("Running TPN...")
    poses = run_tpn(args.model, frame_dir, keypoint_file, args.pose_refine,
                    args.focal_length, args.cx, args.cy)
    save(args.output, poses)
예제 #3
0
def generate_vid_frames(cam, vid_id):
    print(cam, vid_id)
    metas = sequence_metas[cam][vid_id]
    steps = [
        2 if mpii_3dhp.get_train_fps(meta[0], meta[1]) == 50 else 1
        for meta in metas
    ]
    out_folder = os.path.join(muco_temp.MUCO_TEMP_PATH,
                              'frames/cam_%d/vid_%d' % (cam, vid_id))
    ensuredir(out_folder)

    gt_poses = load(
        os.path.join(muco_temp.MUCO_TEMP_PATH,
                     'frames/cam_%d/gt.pkl' % cam))[vid_id]['annot3']
    hip_ind = MuPoTSJoints().index_of('hip')

    for i in range(NUM_FRAMES):
        # generate frame
        depths = gt_poses[i, :, hip_ind, 2]
        ordered_poses = np.argsort(
            depths)[::-1]  # poses ordered by depth in decreasing order

        bg_ind = ordered_poses[0]
        img = mpii_3dhp.get_image(metas[bg_ind][0],
                                  metas[bg_ind][1],
                                  cam,
                                  metas[bg_ind][2] + i * steps[bg_ind],
                                  rgb=False)
        img = img.astype('float32')
        # add new pose onto image
        for pose_ind in ordered_poses[1:]:
            sub, seq, start = metas[pose_ind]
            pose_img = mpii_3dhp.get_image(sub,
                                           seq,
                                           cam,
                                           start + i * steps[pose_ind],
                                           rgb=False)

            # mask is 0 at greenscreen bg, 1 at foreground (body, chair)
            mask = mpii_3dhp.get_mask(sub, seq, cam,
                                      start + i * steps[pose_ind],
                                      'FGmasks')[:, :, 2] / 255.
            mask = cv2.GaussianBlur(mask, (0, 0), 2)[:, :, np.newaxis]
            # chair_mask is 0 at chair, 1 everywhere else
            chair_mask = mpii_3dhp.get_mask(sub, seq, cam,
                                            start + i * steps[pose_ind],
                                            'ChairMasks')[:, :, [2]] / 255

            img = chair_mask * img + (1 - chair_mask) * pose_img
            img = mask * pose_img + (1 - mask) * img

        img = img.astype('uint8')
        cv2.imwrite(os.path.join(out_folder, 'img_%04d.jpg' % i), img,
                    [cv2.IMWRITE_JPEG_QUALITY, 80])
예제 #4
0
def run_experiment(test_dict_2d, test_dict_3d, train_dict_2d, train_dict_3d,
                   train_dict_3d_absolute, test_dict_actionwise, cam_dict,
                   normalisation_params, out_path, p):
    """
    Runs the experiment specified by the params object `p`. It saves additional data in a
    timestamped folder under LOG_PATH, like network structure, trained model, training loss/errors, etc.
    """
    model = siamese_network(p)

    print "Parameters:"
    print p

    ensuredir(out_path)
    save(os.path.join(out_path, 'params.txt'), str(p))
    save(os.path.join(out_path, 'normalisation.pkl'), normalisation_params)

    train_generator = PosNegBatchGenerator(
        train_dict_2d,
        train_dict_3d,
        p,
        shuffle=True,
        cams=cam_dict,
        train_dict_3d_absolute=train_dict_3d_absolute)
    valid_generator = SplitBatchGenerator(test_dict_2d, test_dict_3d, p)

    callbacks = []

    if p.weight_decay:
        callbacks.append(LearningRateScheduler(exp_decay(p), verbose=1))

    callbacks.append(
        LogAllMillimeterError(normalisation_params['std_3d'],
                              test_dict_actionwise,
                              siamese=len(model.inputs) >= 2,
                              csv=os.path.join(out_path, 'metrics.log')))

    print "Output folder is", out_path
    result = model.fit_generator(train_generator,
                                 steps_per_epoch=p.TRAIN_SIZE / p.batch_size,
                                 epochs=p.num_epochs,
                                 callbacks=callbacks,
                                 validation_data=valid_generator,
                                 validation_steps=p.VALID_SIZE / p.batch_size,
                                 verbose=2)

    model.save(os.path.join(out_path, 'model.h5'))

    return result
예제 #5
0
def predict_imgs(model, img_folder, bbox_folder, output_file, normalize,
                 detection_thresh):
    detections = {}

    for file in sorted(os.listdir(bbox_folder)):
        dets = load(os.path.join(bbox_folder, file))
        assert dets.shape[1] == 5
        img_name = file[:-4]  # remove extension
        detections[img_name] = dets

    valid_dataset = hrnet_dataset.ImgFolderDataset(cfg, img_folder, detections,
                                                   normalize, detection_thresh)

    start = time.time()
    preds, boxes, image_names, orig_boxes = predict_dataset(
        cfg, valid_dataset, model)
    end = time.time()
    print("Time in prediction: " + str(end - start))

    ensuredir(os.path.dirname(output_file))
    valid_dataset.rescore_and_save_result(output_file, preds, boxes,
                                          image_names, orig_boxes)
예제 #6
0
def run_experiment(output_path, _config, exp: Experiment):
    exp.log_parameters(flatten_params(_config))
    save(os.path.join(output_path, "config.json"), _config)
    ensuredir(output_path)

    if _config["train_data"] == "mpii_train":
        print("Training data is mpii-train")
        train_data = Mpi3dTrainDataset(
            _config["pose2d_type"],
            _config["pose3d_scaling"],
            _config["cap_25fps"],
            _config["stride"],
        )

    elif _config["train_data"] == "mpii+muco":
        print("Training data is mpii-train and muco_temp concatenated")
        mpi_data = Mpi3dTrainDataset(
            _config["pose2d_type"],
            _config["pose3d_scaling"],
            _config["cap_25fps"],
            _config["stride"],
        )

        muco_data = PersonStackedMucoTempDataset(_config["pose2d_type"],
                                                 _config["pose3d_scaling"])
        train_data = ConcatPoseDataset(mpi_data, muco_data)

    elif _config["train_data"].startswith("muco_temp"):
        train_data = PersonStackedMucoTempDataset(_config["pose2d_type"],
                                                  _config["pose3d_scaling"])

    test_data = Mpi3dTestDataset(_config["pose2d_type"],
                                 _config["pose3d_scaling"],
                                 eval_frames_only=True)

    if _config["simple_aug"]:
        train_data.augment(False)

    assert _config["orient_norm"] == "gauss"
    normalizer_orient = MeanNormalizeOrient(train_data)
    # Load the preprocessing steps
    train_data.transform = None
    transforms_train = [
        decode_trfrm(_config["preprocess_2d"], globals())(train_data,
                                                          cache=False),
        decode_trfrm(_config["preprocess_3d"], globals())(train_data,
                                                          cache=False),
        normalizer_orient,
    ]

    normalizer2d = transforms_train[0].normalizer
    normalizer3d = transforms_train[1].normalizer

    transforms_test = [
        decode_trfrm(_config["preprocess_2d"], globals())(test_data,
                                                          normalizer2d),
        decode_trfrm(_config["preprocess_3d"], globals())(test_data,
                                                          normalizer3d),
        normalizer_orient,
    ]

    transforms_train.append(RemoveIndex())
    transforms_test.append(RemoveIndex())

    train_data.transform = SaveableCompose(transforms_train)
    test_data.transform = SaveableCompose(transforms_test)

    # save normalisation params
    save(output_path + "/preprocess_params.pkl",
         train_data.transform.state_dict())

    len_train = len(train_data)
    len_test = len(test_data)
    print("Length of training data:", len_train)
    print("Length of test data:", len_test)
    exp.log_parameter("train data length", len_train)
    exp.log_parameter("test data length", len_test)

    bos = train_data[[0]]["orientation"].shape
    out_shape = (bos[1] * bos[2] if _config["model"]["loss"] == "orient" else
                 MuPoTSJoints.NUM_JOINTS * 3)
    model = TemporalModelOptimized1f(
        train_data[[0]]["pose2d"].shape[-1],
        out_shape,
        _config["model"]["filter_widths"],
        dropout=_config["model"]["dropout"],
        channels=_config["model"]["channels"],
        layernorm=_config["model"]["layernorm"],
    )
    test_model = TemporalModel(
        train_data[[0]]["pose2d"].shape[-1],
        out_shape,
        _config["model"]["filter_widths"],
        dropout=_config["model"]["dropout"],
        channels=_config["model"]["channels"],
        layernorm=_config["model"]["layernorm"],
    )

    model.cuda()
    test_model.cuda()

    save(output_path + "/model_summary.txt", str(model))

    pad = (model.receptive_field() - 1) // 2
    train_loader = ChunkedGenerator(
        train_data,
        _config["batch_size"],
        pad,
        _config["train_time_flip"],
        shuffle=_config["shuffle"],
        ordered_batch=_config["ordered_batch"],
    )
    tester = ModelCopyTemporalEvaluator(test_model,
                                        test_data,
                                        _config["model"]["loss"],
                                        _config["test_time_flip"],
                                        post_process3d=get_postprocessor(
                                            _config, test_data, normalizer3d),
                                        prefix="test",
                                        orient_norm=_config["orient_norm"],
                                        normalizer_orient=normalizer_orient)

    torch_train(
        exp,
        train_loader,
        model,
        lambda m, b: calc_loss(m, b, _config, None, None, None,
                               normalizer_orient),
        # lambda m, b: calc_loss(
        #     m,
        #     b,
        #     _config,
        #     torch.tensor(normalizer2d.mean[2::3]).cuda(),
        #     torch.tensor(normalizer2d.std[2::3]).cuda(),
        #     torch.tensor(normalizer3d.std).cuda(),
        # ),
        _config,
        callbacks=[tester],
    )

    model_path = os.path.join(output_path, "model_params.pkl")
    torch.save(model.state_dict(), model_path)
    exp.log_model("model", model_path)

    save(
        output_path + "/test_results.pkl",
        {
            "index": test_data.index,
            "pred": preds_from_logger(test_data, tester),
            "pose3d": test_data.poses3d,
        },
    )
def run_experiment(output_path, _config, exp: Experiment):
    config, m = eval.load_model(_config["weights"])
    # config.update(_config)
    config["model"].update(_config["model"])
    _config["model"] = config["model"]

    # tmp = _config["model"]["loss"]
    # _config["model"]["loss"] = "v * mse + e_smooth_small"
    exp.log_parameters(train.flatten_params(_config))
    # _config["model"]["loss"] = tmp
    save(os.path.join(output_path, "config.json"), _config)
    ensuredir(output_path)

    if _config["train_data"] == "mpii_train":
        print("Training data is mpii-train")
        train_data = Mpi3dTrainDataset(
            _config["pose2d_type"],
            _config["pose3d_scaling"],
            _config["cap_25fps"],
            _config["stride"],
        )

    elif _config["train_data"] == "mpii+muco":
        print("Training data is mpii-train and muco_temp concatenated")
        mpi_data = Mpi3dTrainDataset(
            _config["pose2d_type"],
            _config["pose3d_scaling"],
            _config["cap_25fps"],
            _config["stride"],
        )

        muco_data = PersonStackedMucoTempDataset(_config["pose2d_type"],
                                                 _config["pose3d_scaling"])
        train_data = ConcatPoseDataset(mpi_data, muco_data)

    elif _config["train_data"].startswith("muco_temp"):
        train_data = PersonStackedMucoTempDataset(_config["pose2d_type"],
                                                  _config["pose3d_scaling"])

    test_data = Mpi3dTestDataset(_config["pose2d_type"],
                                 _config["pose3d_scaling"],
                                 eval_frames_only=True)

    if _config["simple_aug"]:
        train_data.augment(False)

    # Load the preprocessing steps
    params_path = os.path.join(LOG_PATH, _config["weights"],
                               "preprocess_params.pkl")
    transform = SaveableCompose.from_file(params_path, test_data, globals())

    train_data.transform = None
    transforms_train = [
        decode_trfrm(_config["preprocess_2d"], globals())(train_data,
                                                          cache=False),
        decode_trfrm(_config["preprocess_3d"], globals())(train_data,
                                                          cache=False),
    ]

    normalizer2d = transforms_train[0].normalizer
    normalizer3d = transforms_train[1].normalizer

    transforms_test = [
        decode_trfrm(_config["preprocess_2d"], globals())(test_data,
                                                          normalizer2d),
        decode_trfrm(_config["preprocess_3d"], globals())(test_data,
                                                          normalizer3d),
    ]

    transforms_train.append(RemoveIndex())
    transforms_test.append(RemoveIndex())

    train_data.transform = SaveableCompose(transforms_train)
    test_data.transform = SaveableCompose(transforms_test)
    # train_data.transform = SaveableCompose.from_file(params_path, train_data, globals())
    # test_data.transform = SaveableCompose.from_file(params_path, test_data, globals())

    # save normalisation params
    save(output_path + "/preprocess_params.pkl",
         train_data.transform.state_dict())

    len_train = len(train_data)
    len_test = len(test_data)
    print("Length of training data:", len_train)
    print("Length of test data:", len_test)
    exp.log_parameter("train data length", len_train)
    exp.log_parameter("test data length", len_test)

    model = TemporalModelOptimized1f(
        train_data[[0]]["pose2d"].shape[-1],
        MuPoTSJoints.NUM_JOINTS,
        config["model"]["filter_widths"],
        dropout=config["model"]["dropout"],
        channels=config["model"]["channels"],
        layernorm=config["model"]["layernorm"],
    )
    model.load_state_dict(m.state_dict())
    test_model = TemporalModel(
        train_data[[0]]["pose2d"].shape[-1],
        MuPoTSJoints.NUM_JOINTS,
        config["model"]["filter_widths"],
        dropout=config["model"]["dropout"],
        channels=config["model"]["channels"],
        layernorm=config["model"]["layernorm"],
    )

    model.cuda()
    test_model.cuda()

    save(output_path + "/model_summary.txt", str(model))

    # normalizer2d = train_data.transform.transforms[0].normalizer
    # normalizer3d = train_data.transform.transforms[1].normalizer

    pad = (model.receptive_field() - 1) // 2
    train_loader = ChunkedGenerator(
        train_data,
        _config["batch_size"],
        pad,
        _config["train_time_flip"],
        shuffle=_config["shuffle"],
        ordered_batch=_config["ordered_batch"],
    )
    tester = ModelCopyTemporalEvaluator(
        test_model,
        test_data,
        config["model"]["loss"],
        _config["test_time_flip"],
        post_process3d=get_postprocessor(_config, test_data, normalizer3d),
        prefix="test",
    )

    torch_train(
        exp,
        train_loader,
        model,
        lambda m, b: train.calc_loss(
            m,
            b,
            _config,
            torch.tensor(normalizer2d.mean[2::3]).cuda(),
            torch.tensor(normalizer2d.std[2::3]).cuda(),
            torch.tensor(normalizer3d.std).cuda(),
        ),
        _config,
        callbacks=[tester],
    )

    model_path = os.path.join(output_path, "model_params.pkl")
    torch.save(model.state_dict(), model_path)
    exp.log_model("model", model_path)
예제 #8
0
    def rescore_and_save_result(self, output_file, preds, all_boxes, img_path,
                                orig_boxes):
        assert output_file.endswith('.json') or output_file.endswith(
            '.npy'), "Only json and numpy output is supported"

        ensuredir(os.path.dirname(output_file))

        # person x (keypoints)
        _kpts = []
        for idx, kpt in enumerate(preds):
            _kpts.append({
                'keypoints': kpt,
                'center': all_boxes[idx][0:2],
                'scale': all_boxes[idx][2:4],
                'area': all_boxes[idx][4],
                'score': all_boxes[idx][5],
                'image': img_path[idx],
                'origbox': orig_boxes[idx]
            })

        # image x person x (keypoints)
        kpts = defaultdict(list)
        for kpt in _kpts:
            kpts[kpt['image']].append(kpt)

        # rescoring and oks nms
        num_joints = self.num_joints
        in_vis_thre = self.in_vis_thre
        oks_thre = self.oks_thre
        oks_nmsed_kpts = []
        nmsed_kpts_by_frame = defaultdict(list)
        for img in kpts.keys():
            img_kpts = kpts[img]
            for n_p in img_kpts:
                box_score = n_p['score']
                kpt_score = 0
                valid_num = 0
                for n_jt in range(0, num_joints):
                    t_s = n_p['keypoints'][n_jt][2]
                    if t_s > in_vis_thre:
                        kpt_score = kpt_score + t_s
                        valid_num = valid_num + 1
                if valid_num != 0:
                    kpt_score = kpt_score / valid_num
                # rescoring
                n_p['score'] = kpt_score * box_score

            if self.soft_nms:
                keep = soft_oks_nms(
                    [img_kpts[i] for i in range(len(img_kpts))], oks_thre)
            else:
                keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))],
                               oks_thre)

            if len(keep) == 0:
                selected_kpts = img_kpts
            else:
                selected_kpts = [img_kpts[_keep] for _keep in keep]

            oks_nmsed_kpts.append(selected_kpts)
            nmsed_kpts_by_frame[img] = selected_kpts

        self._write_keypoint_results(nmsed_kpts_by_frame, output_file)
예제 #9
0
def run_experiment(output_path, _config):
    save(os.path.join(output_path, 'config.json'), _config)
    ensuredir(output_path)

    if _config['train_data'] == 'mpii_train':
        print("Training data is mpii-train")
        train_data = Mpi3dTrainDataset(_config['pose2d_type'],
                                       _config['pose3d_scaling'],
                                       _config['cap_25fps'], _config['stride'])

    elif _config['train_data'] == 'mpii+muco':
        print("Training data is mpii-train and muco_temp concatenated")
        mpi_data = Mpi3dTrainDataset(_config['pose2d_type'],
                                     _config['pose3d_scaling'],
                                     _config['cap_25fps'], _config['stride'])

        muco_data = PersonStackedMucoTempDataset(_config['pose2d_type'],
                                                 _config['pose3d_scaling'])
        train_data = ConcatPoseDataset(mpi_data, muco_data)

    elif _config['train_data'].startswith('muco_temp'):
        train_data = PersonStackedMucoTempDataset(_config['pose2d_type'],
                                                  _config['pose3d_scaling'])

    test_data = Mpi3dTestDataset(_config['pose2d_type'],
                                 _config['pose3d_scaling'],
                                 eval_frames_only=True)

    if _config['simple_aug']:
        train_data.augment(False)

    # Load the preprocessing steps
    train_data.transform = None
    transforms_train = [
        decode_trfrm(_config['preprocess_2d'], globals())(train_data,
                                                          cache=False),
        decode_trfrm(_config['preprocess_3d'], globals())(train_data,
                                                          cache=False)
    ]

    normalizer2d = transforms_train[0].normalizer
    normalizer3d = transforms_train[1].normalizer

    transforms_test = [
        decode_trfrm(_config['preprocess_2d'], globals())(test_data,
                                                          normalizer2d),
        decode_trfrm(_config['preprocess_3d'], globals())(test_data,
                                                          normalizer3d)
    ]

    transforms_train.append(RemoveIndex())
    transforms_test.append(RemoveIndex())

    train_data.transform = SaveableCompose(transforms_train)
    test_data.transform = SaveableCompose(transforms_test)

    # save normalisation params
    save(output_path + '/preprocess_params.pkl',
         train_data.transform.state_dict())

    print("Length of training data:", len(train_data))
    print("Length of test data:", len(test_data))

    model = TemporalModelOptimized1f(train_data[[0]]['pose2d'].shape[-1],
                                     MuPoTSJoints.NUM_JOINTS,
                                     _config['model']['filter_widths'],
                                     dropout=_config['model']['dropout'],
                                     channels=_config['model']['channels'],
                                     layernorm=_config['model']['layernorm'])
    test_model = TemporalModel(train_data[[0]]['pose2d'].shape[-1],
                               MuPoTSJoints.NUM_JOINTS,
                               _config['model']['filter_widths'],
                               dropout=_config['model']['dropout'],
                               channels=_config['model']['channels'],
                               layernorm=_config['model']['layernorm'])

    model.cuda()
    test_model.cuda()

    save(output_path + '/model_summary.txt', str(model))

    pad = (model.receptive_field() - 1) // 2
    train_loader = ChunkedGenerator(train_data,
                                    _config['batch_size'],
                                    pad,
                                    _config['train_time_flip'],
                                    shuffle=True)
    tester = ModelCopyTemporalEvaluator(test_model,
                                        test_data,
                                        _config['model']['loss'],
                                        _config['test_time_flip'],
                                        post_process3d=get_postprocessor(
                                            _config, test_data, normalizer3d),
                                        prefix='test')

    torch_train(train_loader,
                model,
                lambda m, b: calc_loss(m, b, _config),
                _config,
                callbacks=[tester])

    torch.save(model.state_dict(), os.path.join(output_path,
                                                'model_params.pkl'))
    save(
        output_path + '/test_results.pkl', {
            'index': test_data.index,
            'pred': preds_from_logger(test_data, tester),
            'pose3d': test_data.poses3d
        })