diff --git a/docs/MonoLoco++.md b/docs/MonoLoco++.md index 9ed2c8f..41ac517 100644 --- a/docs/MonoLoco++.md +++ b/docs/MonoLoco++.md @@ -18,9 +18,40 @@ Our vision-based system (i) is privacy-safe, (ii) works with any fixed or moving This readme is in Beta version and refers to the `update` branch. It is currently under development. +## Predictions +For a quick setup download a pifpaf and a MonoLoco++ models from here and save them into `data/models`. + +### 3D Localization +The predict script receives an image (or an entire folder using glob expressions), +calls PifPaf for 2d human pose detection over the image +and runs Monoloco++ for 3d location of the detected poses. +The command `--net` defines if saving pifpaf outputs, MonoLoco++ outputs or MonStereo ones. +You can check all commands for Pifpaf at [openpifpaf](https://github.com/vita-epfl/openpifpaf). + + +Output options include json files and/or visualization of the predictions on the image in *frontal mode*, +*birds-eye-view mode* or *combined mode* and can be specified with `--output_types` + +Below an example image and comparison with ground-truth. +Ground-truth KITTI files for comparing results can be downloaded from here and should be saved into `data/arrays` +Ground-truth files can also be generated, more info in the preprocessing section +``` +python -m monstereo.run predict --net monoloco_pp --glob docs/002282.png --output_types multi +--model data/models/monoloco_pp-201203-1424.pkl -o --long-edge 2500 --n_dropout 50 +``` + +To show all the instances estimated by MonoLoco add the argument `show_all` to the above command. + +### Social Distancing +WIP + +### Orientation and Bounding Box dimensions +MonoLoco++ estimates orientation and box dimensions as well. Results are saved in a json file when using the command +`--output_types json`. At the moment, the only visualization including orientation is the social distancing one. + ## Preprocessing -# Kitti +### Kitti Annotations from a pose detector needs to be stored in a folder. For example by using [openpifpaf](https://github.com/vita-epfl/openpifpaf): ``` @@ -134,6 +165,3 @@ python -m monstereo.run eval --model --dir_ann ``` - -### Predictions -Currently under development. For the moment, please refer to the master branch \ No newline at end of file diff --git a/monstereo/network/net.py b/monstereo/network/net.py index bea48f2..67b7ac9 100644 --- a/monstereo/network/net.py +++ b/monstereo/network/net.py @@ -163,7 +163,7 @@ class Loco: print("found {} matches with ground-truth".format(len(matches))) # Keep track of instances non-matched - idxs_matches = (el[0] for el in matches) + idxs_matches = [el[0] for el in matches] not_matches = [idx for idx, _ in enumerate(boxes) if idx not in idxs_matches] else: diff --git a/monstereo/predict.py b/monstereo/predict.py index 9984f58..eee17ca 100644 --- a/monstereo/predict.py +++ b/monstereo/predict.py @@ -26,32 +26,29 @@ LOG = logging.getLogger(__name__) def factory_from_args(args): - # Merge the model_pifpaf argument - if not args.checkpoint: - args.checkpoint = 'shufflenetv2k30' # Default model - # glob + # Data if args.glob: args.images += glob.glob(args.glob) if not args.images: raise Exception("no image files given") - # add args.device + # Model + if not args.checkpoint: + args.checkpoint = 'data/models/shufflenetv2k30-201104-224654-cocokp-d75ed641.pkl' # Default model + + # Decices args.device = torch.device('cpu') args.disable_cuda = False args.pin_memory = False if torch.cuda.is_available(): args.device = torch.device('cuda') args.pin_memory = True - - # Add num_workers args.loader_workers = 8 # Add visualization defaults args.figure_width = 10 args.dpi_factor = 1.0 - # TODO - args.long_edge = None if args.net == 'monstereo': args.batch_size = 2 else: @@ -59,7 +56,7 @@ def factory_from_args(args): # Make default pifpaf argument args.force_complete_pose = True - args.instance_threshold = 0.15 + print("Force complete pose is active") # Configure decoder.configure(args) diff --git a/monstereo/run.py b/monstereo/run.py index 7215b5c..d2ab60e 100644 --- a/monstereo/run.py +++ b/monstereo/run.py @@ -37,13 +37,14 @@ def cli(): 'json bird front or multi for MonStereo') predict_parser.add_argument('--no_save', help='to show images', action='store_true') predict_parser.add_argument('--dpi', help='image resolution', type=int, default=100) + predict_parser.add_argument('--long-edge', default=None, type=int, + help='rescale the long side of the image (aspect ratio maintained)') # Pifpaf parsers decoder.cli(predict_parser) network.cli(predict_parser) show.cli(predict_parser) visualizer.cli(predict_parser) - predict_parser.add_argument('--scale', default=1.0, type=float, help='change the scale of the image to preprocess') # Monoloco predict_parser.add_argument('--net', help='Choose network: monoloco, monoloco_p, monoloco_pp, monstereo') diff --git a/monstereo/utils/iou.py b/monstereo/utils/iou.py index 24ad252..cc5d813 100644 --- a/monstereo/utils/iou.py +++ b/monstereo/utils/iou.py @@ -57,7 +57,7 @@ def get_iou_matches(boxes, boxes_gt, iou_min=0.3): ious.append(iou) idx_gt_max = int(np.argmax(ious)) if (ious[idx_gt_max] >= iou_min) and (idx_gt_max not in used): - matches.append((idx, idx_gt_max)) + matches.append((int(idx), idx_gt_max)) used.append(idx_gt_max) return matches @@ -93,6 +93,6 @@ def reorder_matches(matches, boxes, mode='left_rigth'): # Order the boxes based on the left-right position in the image and ordered_boxes = np.argsort([box[0] for box in boxes]) # indices of boxes ordered from left to right - matches_left = [idx for (idx, _) in matches] + matches_left = [int(idx) for (idx, _) in matches] return [matches[matches_left.index(idx_boxes)] for idx_boxes in ordered_boxes if idx_boxes in matches_left]