Example #1
0
def select_gaps(argv):
    pjoin = os.path.join
    parser = argparse.ArgumentParser("Select gaps")
    parser = parser_video(parser)
    parser.add_argument('--select-gaps', action='store_true')
    parser.add_argument("-s",
                        "--d-scenelets",
                        dest='s',
                        type=argparse_check_exists,
                        help="Folder containing original PiGraphs scenelets")
    args = parser.parse_args(argv)
    d = os.path.join(args.video, args.d)
    assert os.path.exists(d), "does not exist: %s" % d

    if os.path.isdir(args.video):
        if args.video.endswith(os.sep):
            args.video = args.video[:-1]
    name_query = args.video.split(os.sep)[-1]
    assert len(name_query), args.video.split(os.sep)
    p_query = pjoin(args.video, "skel_%s_unannot.json" % name_query) \
        if os.path.isdir(args.video) else args.video
    assert p_query.endswith('.json'), "Need a skeleton file"

    # load initial video path (local poses)
    query = Scenelet.load(p_query, no_obj=True)
    frame_ids = query.skeleton.get_frames()
    centroids = Skeleton.get_resampled_centroids(start=frame_ids[0],
                                                 end=frame_ids[-1],
                                                 old_frame_ids=frame_ids,
                                                 poses=query.skeleton.poses)

    depths_times_charnesses = []
    skeleton = Skeleton()
    depths = []
    for p in sorted(os.listdir(d)):
        ch = float(p.split('charness')[1][1:])
        d_time = pjoin(d, p)
        p_skel = next(
            f for f in os.listdir(d_time) if os.path.isfile(pjoin(d_time, f))
            and f.startswith('skel') and f.endswith('json') and '_00' in f)
        sclt = Scenelet.load(pjoin(d_time, p_skel))
        mn, mx = sclt.skeleton.get_frames_min_max()
        frame_id = mn + (mx - mn) // 2
        if query.skeleton.has_pose(frame_id):
            pos_3d = query.skeleton.get_centroid_3d(frame_id)
        else:
            lin_id = frame_id - frame_ids[0]
            pos_3d = centroids[lin_id, :]
        depth = np.linalg.norm(pos_3d)
        depths.append(depth)
        depths_times_charnesses.append(
            DepthTimeCharness(depth=depth, frame_id=frame_id, charness=ch))
    hist, bin_edges = np.histogram(depths, bins=5)
    lg.debug("hist: %s" % hist)
    lg.debug("edges: %s" % bin_edges)
Example #2
0
 def __init__(self, skeleton=None):
     self.skeleton = skeleton if skeleton is not None else Skeleton()
     self.objects = {}
     self.aux_info = {}
     self.transforms = {}
     self.name_scene = None
     self.name_scenelet = None
     self.charness = np.float32(1.)
     """Per-scenelet charness (a single float32)."""
     self.match_score = np.float32(0.)
     """Also called feature distance, smaller is better."""
     # self.confidence = None
     # """Array to show how sure we are about the different
     # entries in the skeleton."""
     self.density = None
     """How densely sampled in space this part of the scene is 
     (how many poses there are usually around the middle frame).
     """
     self.charness_poses = None
     """A dictionary that stores a characteristicness for each pose.
Example #3
0
def extract_skeleton(scene,
                     frame_ids=None,
                     frame_multiplier=1.,
                     time_multiplier=1.):
    joints = {
        ob.name.split('.')[1]: ob
        for ob in bpy.data.objects
        if ob.name.startswith('Output') and ob.name.endswith('Sphere')
    }
    print("joints: %s" % joints)
    assert len(joints) == Joint.get_num_joints(), \
        "No: %s != %s" % (len(joints), Joint.get_num_joints())
    if not frame_ids:
        frame_ids = range(scene.frame_start, scene.frame_end + 1)

    skeleton = Skeleton()
    for frame_id in frame_ids:
        o_frame_id = int(round(frame_id * frame_multiplier))
        if skeleton.has_pose(o_frame_id):
            print("skipping %s, because already set" % frame_id)
            continue
        print("frame_id: %s, o_frame_id: %s" % (frame_id, o_frame_id))
        scene.frame_set(frame_id)
        bpy.context.scene.update()
        pose = np.zeros(shape=(Skeleton.DIM, len(joints)))
        for joint, ob in joints.items():
            pos = ob.matrix_world.col[3]
            joint_id = Joint.from_string(joint)
            pose[:, joint_id] = from_blender(pos)
        assert not skeleton.has_pose(o_frame_id), "Already has %s" % frame_id
        skeleton.set_pose(frame_id=o_frame_id,
                          pose=pose,
                          time=o_frame_id * time_multiplier)

    # scenelet = Scenelet(skeleton=skeleton)
    # scenelet.save(path=path_out, save_obj=False)

    return skeleton
Example #4
0
def extract_annotated_scenelet(
        scene,
        prefix_obj='obb',
        frame_ids=None,
        frame_multiplier=1.,
        time_multiplier=1.,
        f_ob_is_joint=lambda ob: ob.name.startswith(
            'Output') and ob.name.endswith('Sphere'),
        f_joint_name_from_ob=lambda ob: ob.name.split('.')[1]):
    """
    
    Args:
        scene (bpy.types.Scene):
            The current scene (e.g. bpy.context.scene).
        prefix_obj (str):
            Start of object names that we want to include in the scenelet
            as oriented bounding boxes.
        frame_ids (List[int]):
            A subset of frame IDs to export.
        frame_multiplier (float):
            Scaling for frame IDs. The result will be rounded and truncated.
            output.frame_id := int(round(frame_id * frame_multiplier))
        time_multipler (float):
            Scaling for times associated with frame_ids.
            output.time := int(round(frame_id * frame_multiplier)) 
            * time_multiplier.
        f_ob_is_joint (Callable[[bpy.types.Object], bool]]):
            Decides if a Blender object is a joint.
        f_joint_name_from_ob (Callable[[bpy.types.Object], str]):
            Gets the joint name from the Blender object name.
    """
    # joints = {
    #     ob.name.split('.')[1]: ob
    #     for ob in bpy.data.objects
    #     if ob.name.startswith('Output') and ob.name.endswith('Sphere')}
    joints = {
        f_joint_name_from_ob(ob): ob
        for ob in bpy.data.objects if f_ob_is_joint(ob)
    }
    print("joints: %s" % joints)
    skeleton = Skeleton()
    if len(joints):
        assert len(joints) == 16, "No: %s" % len(joints)
        if not frame_ids:
            frame_ids = range(scene.frame_start, scene.frame_end + 1)
        for frame_id in frame_ids:
            o_frame_id = int(round(frame_id * frame_multiplier))
            if skeleton.has_pose(o_frame_id):
                print("skipping %s" % frame_id)
                continue
            print("frame_id: %s" % frame_id)
            scene.frame_set(frame_id)
            bpy.context.scene.update()
            # bpy.ops.anim.change_frame(frame_id)
            pose = np.zeros(shape=(3, len(joints)))
            for joint, ob in joints.items():
                pos = ob.matrix_world.col[3]
                print("pos[%s]: %s" % (ob.name, pos))
                joint_id = Joint.from_string(joint)
                print("joint %s is %s" % (joint, Joint(joint_id)))
                pose[:, joint_id] = from_blender(pos)
            print("o_frame: %s from %s" % (o_frame_id, frame_id))
            assert not skeleton.has_pose(o_frame_id), \
                "Already has %s" % frame_id
            skeleton.set_pose(frame_id=o_frame_id,
                              pose=pose,
                              time=o_frame_id * time_multiplier)
    objs_bl = {}
    for obj in bpy.data.objects:
        if obj.name.startswith(prefix_obj) and not obj.hide:
            obj_id = int(obj.name.split('_')[1])
            try:
                objs_bl[obj_id].append(obj)
            except KeyError:
                objs_bl[obj_id] = [obj]

    print("objs: %s" % objs_bl)
    scenelet = Scenelet(skeleton=skeleton)
    print("scenelet: %s" % scenelet)
    for obj_id, parts_bl in objs_bl.items():
        name_category = None
        scene_obj = None
        for part_id, part_bl in enumerate(parts_bl):
            transl, rot, scale = part_bl.matrix_world.decompose()
            rot = rot.to_matrix()
            if any(comp < 0. for comp in scale):
                scale *= -1.
                rot *= -1.
            assert not any(comp < 0. for comp in scale), "No: %s" % scale

            matrix_world = part_bl.matrix_world.copy()

            # need to save full scale, not only half axes
            for c in range(3):
                for r in range(3):
                    matrix_world[r][c] *= 2.
            name_parts = part_bl.name.split('_')
            if name_category is None:
                name_category = name_parts[2]
                scene_obj = SceneObj(label=name_category)
            else:
                assert name_category == name_parts[2], \
                    "No: %s %s" % (name_category, name_parts[2])
            name_part = name_parts[3]
            print("part: %s" % name_part)
            part = SceneObjPart(name_part)
            part.obb = Obb(centroid=np.array(
                from_blender([transl[0], transl[1], transl[2]])),
                           axes=np.array([[rot[0][0], rot[0][1], rot[0][2]],
                                          [-rot[2][0], -rot[2][1], -rot[2][2]],
                                          [rot[1][0], rot[1][1], rot[1][2]]]),
                           scales=np.array(
                               [scale[0] * 2., scale[1] * 2., scale[2] * 2.]))
            # if 'table' in name_category:
            #     print(part.obb.axes)
            #     raise RuntimeError("stop")
            print("obb: %s" % part.obb.to_json(0))
            scene_obj.add_part(part_id, part)
        scenelet.add_object(obj_id, scene_obj, clone=False)
    return scenelet
Example #5
0
    def load(cls, path, no_obj=False):
        """

        Returns:
            s (stealth.logic.scenelet.Scenelet):
                Scenelet read from disk.
        """
        with open(path, 'r') as fin:
            data = json.load(fin)
        s = Scenelet()

        # 3d
        if '3d' in data:
            s.skeleton = Skeleton.from_json(data)
        else:
            sys.stderr.write("No skeleton in scenelet: %s" % path)

        # scenelets
        if 'scenelets' in data:
            if 'obbs' in data['scenelets'] and not no_obj:
                for obb_path in data['scenelets']['obbs']:
                    obb_folder, obj_name = os.path.split(obb_path)
                    obj_id, scene_obj_name, part_name = obj_name.split('_')
                    obj_id = int(obj_id)
                    part_name = part_name.split('.')[0]
                    obb_json_path = os.path.join(
                        os.path.split(path)[0], obb_folder,
                        os.path.splitext(obj_name)[0] + ".json")
                    if os.path.exists(obb_json_path):
                        part = SceneObjPart(part_name)
                        part.obb, data_obb = Obb.load(obb_json_path,
                                                      return_data=True)
                        part_id = data_obb['part_id'] \
                            if 'part_id' in data_obb \
                            else -1
                        part.path = os.path.join(
                            os.path.split(path)[0], obb_path)
                        if s.has_object(obj_id):
                            s.get_object(obj_id).add_part(part_id=part_id,
                                                          label_or_part=part)
                        else:
                            scene_obj = SceneObj(scene_obj_name)
                            scene_obj.add_part(part_id=part_id,
                                               label_or_part=part)
                            s.add_object(obj_id, scene_obj, clone=False)
                    else:
                        obb_obj_path = os.path.join(
                            os.path.split(path)[0], obb_path)
                        s.add_object(obj_id,
                                     SceneObject(label=scene_obj_name,
                                                 name=part_name,
                                                 mesh=MeshOBJ(obb_obj_path,
                                                              verbose=False)),
                                     clone=False)
                    if 'transforms' in data['scenelets']:
                        try:
                            s.objects[obj_id].transform = \
                                np.asarray(
                                    data['scenelets']['transforms'][obj_name],
                                    dtype='f4')
                        except KeyError:
                            pass

            # TODO: read 'clouds' to parts

        for k, v in data.items():
            if k in Scenelet.__KEYS_SKELETON:
                continue
            s.add_aux_info(k, v)
        try:
            s.name_scene = data['name_scene']
        except KeyError:
            s.name_scene = os.path.basename(os.path.split(path)[-2])
            if '__' in s.name_scene:
                s.name_scene = s.name_scene.partition('__')[0]
            if s.name_scene.startswith('skel_'):
                s.name_scene = s.name_scene[5:]

        try:
            s.name_scenelet = data['name_scenelet']
        except KeyError:
            s.name_scenelet = os.path.splitext(os.path.basename(path))[0]
            if s.name_scenelet.startswith('skel_'):
                s.name_scenelet = s.name_scenelet[5:]

        if 'charness' in data:
            s.charness = data['charness']
        if 'match_score' in data:
            s.match_score = data['match_score']
        # if 'confidence' in data:
        #     s.confidence = data['confidence']

        # density
        try:
            s.density = data['density']
        except KeyError:
            pass

        # charness_poses
        try:
            j_dict = data['charness_poses']
            s.charness_poses = {
                frame_id: np.float32(value)
                for frame_id, value in zip(j_dict['frame_ids'],
                                           j_dict['values'])
            }
        except KeyError:
            pass

        return s
Example #6
0
def main(argv):
    parser = argparse.ArgumentParser(
        "Filter initial path based on distance to full fit")
    parser.add_argument('skel', help="Skeleton file to filter", type=str)
    parser.add_argument('--threshold',
                        help='Distance threshold. Default: 0.4',
                        type=float,
                        default=0.4)
    args = parser.parse_args(argv)
    lower_body = [
        Joint.LKNE, Joint.RKNE, Joint.LANK, Joint.RANK, Joint.LHIP, Joint.RHIP
    ]

    print(args.skel)
    p_root = os.path.dirname(args.skel)
    p_fit = os.path.join(p_root, 'opt1')
    assert os.path.isdir(p_fit), p_fit
    query = Scenelet.load(args.skel)
    out = Skeleton()

    data = []

    x = []
    y = []
    y2 = []
    for d_ in sorted(os.listdir(p_fit)):
        d = os.path.join(p_fit, d_)
        pattern = os.path.join(d, 'skel_*.json')
        for f in sorted(glob.iglob(pattern)):
            print(f)
            assert '00' in f, f
            sclt = Scenelet.load(f)
            frames = sclt.skeleton.get_frames()
            mid_frame = frames[len(frames) // 2]
            time = sclt.skeleton.get_time(mid_frame)
            q_frame_id = query.skeleton.find_time(time)
            q_time = query.skeleton.get_time(q_frame_id)
            print(time, q_time, f)
            q_pose = query.skeleton.get_pose(q_frame_id)
            pose = sclt.skeleton.get_pose(mid_frame)
            pose[[0, 2]] -= (pose[:, Joint.PELV:Joint.PELV + 1] -
                             q_pose[:, Joint.PELV:Joint.PELV + 1])[[0, 2]]
            diff = np.mean(
                np.linalg.norm(q_pose[:, lower_body] - pose[:, lower_body],
                               axis=0))
            print(q_frame_id, time, diff)
            y.append(diff)
            x.append(q_frame_id)
            data.append((q_frame_id, diff, time))

            if query.skeleton.has_pose(q_frame_id - 1):
                tmp_pose = copy.deepcopy(q_pose)
                tmp_pose -= tmp_pose[:, Joint.PELV:Joint.PELV +
                                     1] - query.skeleton.get_pose(
                                         q_frame_id -
                                         1)[:, Joint.PELV:Joint.PELV + 1]
                y2.append(
                    np.mean(
                        np.linalg.norm(pose[:, lower_body] -
                                       tmp_pose[:, lower_body],
                                       axis=0)))
            else:
                y2.append(0.)

            out.set_pose(frame_id=q_frame_id, time=q_time, pose=pose)
            break

    data = smooth(data)
    plt.plot(x, y, 'x--', label='Distance to best Kinect fit\'s center frame')
    plt.plot(x, y2, 'o--', label='Distance to prev pose')
    plt.plot([d[0] for d in data], [d[1] for d in data],
             'o--',
             label='Smoothed')
    plt.xlabel('Time (s)')
    plt.ylabel('Sum local squared distance')
    plt.legend()
    plt.savefig(os.path.join(p_root, 'tmp.pdf'))
    Scenelet(skeleton=out).save(os.path.join(p_root, 'skel_tmp.json'))

    above = []
    prev_frame_id = None
    for frame_id, dist, time in data:
        # assert prev_frame_id is None or frame_id != prev_frame_id, \
        #     'No: {}'.format(frame_id)
        if dist > args.threshold:
            above.append(
                Span2(start=frame_id, end=frame_id, value=dist, time=time))
        prev_frame_id = frame_id

    spans = [copy.deepcopy(above[0])]
    it = iter(above)
    next(it)
    prev_frame_id = above[0].start
    for span2 in it:
        frame_id = span2.start
        if prev_frame_id + 1 < frame_id:
            # span = spans[-1]
            # spans[-1] = span[0], prev_frame_id, span[2]
            spans[-1].end = prev_frame_id
            spans.append(
                Span2(start=frame_id,
                      end=frame_id,
                      time=None,
                      value=span2.value))
        else:
            print(prev_frame_id, frame_id)
        prev_frame_id = frame_id
    spans[-1].end = prev_frame_id
    print("Need replacement: {}".format(above))
    print("Need replacement2: {}".format(spans))
Example #7
0
def main(argv):
    conf = Conf.get()
    parser = argparse.ArgumentParser("Denis pose converter")
    parser.add_argument('camera_name',
                        help="Camera name ('G15', 'S6')",
                        type=str)
    parser.add_argument(
        '-d',
        dest='dir',
        required=True,
        help="Path to the <scene folder>/denis containing skeletons.json")
    parser.add_argument(
        '-filter',
        dest='with_filtering',
        action="store_true",
        help="Should we do post-filtering (1-euro) on the pelvis positions")
    parser.add_argument('-huber',
                        required=False,
                        help="Should we do huber loss?",
                        action='store_true')
    parser.add_argument('-smooth',
                        type=float,
                        default=0.005,
                        help="Should we have a smoothness term (l2/huber)?")
    parser.add_argument(
        '--winsorize-limit',
        type=float,
        default=conf.optimize_path.winsorize_limit,
        help='Threshold for filtering too large jumps of the 2D centroid')
    parser.add_argument('--no-resample',
                        action='store_true',
                        help="add resampled frames")
    parser.add_argument('--n-actors',
                        type=int,
                        default=1,
                        help="How many skeletons to track.")
    parser.add_argument('-n-actors',
                        type=int,
                        default=1,
                        help="Max number of people in scene.")
    # parser.add_argument(
    #     '-r', type=float,
    #     help='Video rate. Default: 1, if avconv -r 5. '
    #          'Original video sampling rate (no subsampling) should be '
    #          '24/5=4.8. avconv -r 10 leads to 24/10=2.4.',
    #     required=True)
    parser.add_argument('--person_height',
                        type=float,
                        help='Assumed height of human(s) in video.',
                        default=Conf.get().optimize_path.person_height)
    parser.add_argument(
        '--forwards-window-size',
        type=int,
        help='How many poses in time to look before AND after to '
        'average forward direction. 0 means no averaging. Default: 0.',
        default=0)
    parser.add_argument('--no-img',
                        action='store_true',
                        help='Read and write images (vis reproj error)')
    parser.add_argument('--postfix',
                        type=str,
                        help="output file postfix.",
                        default='unannot')
    args = parser.parse_args(argv)
    show = False
    args.resample = not args.no_resample
    # assert not args.resample, "resample should be off"
    assert os.path.exists(args.dir), "Source does not exist: %s" % args.dir
    p_scene = os.path.normpath(os.path.join(args.dir, os.pardir))  # type: str
    p_video_params = os.path.join(p_scene, 'video_params.json')
    assert os.path.exists(p_video_params), "Need video_params.json for rate"
    if 'r' not in args or args.r is None:
        args.r = json.load(open(p_video_params, 'r'))['rate-avconv']

    # manual parameters (depth initialization, number of actors)
    p_scene_params = os.path.join(args.dir, os.pardir, 'scene_params.json')
    if not os.path.exists(p_scene_params):
        scene_params = {
            'depth_init': 10.,
            'actors': args.n_actors,
            'ground_rot': [0., 0., 0.]
        }
        json.dump(scene_params, open(p_scene_params, 'w'))
        raise RuntimeError("Inited scene_params.json, please check: %s" %
                           p_scene_params)
    else:
        scene_params = json.load(open(p_scene_params, 'r'))
        lg.warning("Will work with %d actors and init depth to %g" %
                   (scene_params['actors'], scene_params['depth_init']))
        assert '--n-actors' not in argv \
               or args.n_actors == scene_params['actors'], \
            "Actor count mismatch, remove %d from args, because " \
            "scene_params.json says %d?" \
            % (args.n_actors, scene_params['actors'])
        args.n_actors = scene_params['actors']
        ground_rot = scene_params['ground_rot'] or [0., 0., 0.]

    # load images
    path_images = os.path.abspath(os.path.join(args.dir, os.pardir, 'origjpg'))
    images = {}
    shape_orig = None
    if not args.no_img:
        images, shape_orig = load_images(path_images)

    path_skeleton = \
        max((f for f in os.listdir(os.path.join(args.dir))
             if f.startswith('skeletons') and f.endswith('json')),
            key=lambda s: int(os.path.splitext(s)[0].split('_')[1]))
    print("path_skeleton: %s" % path_skeleton)
    data = json.load(open(os.path.join(args.dir, path_skeleton), 'r'))
    # data, pose_constraints, first_run = \
    #     cleanup(data, p_dir=os.path.join(args.dir, os.pardir))
    # poses_2d = []
    # plt.figure()
    # show_images(images, data)
    if False:
        # pose_ids = identify_actors_multi(data, n_actors=1)
        p_segm_pickle = os.path.join(args.dir, os.pardir,
                                     "label_skeletons.pickle")
        problem = None
        if False and os.path.exists(p_segm_pickle):
            lg.warning("Loading skeleton segmentation from pickle %s" %
                       p_segm_pickle)
            pose_ids, problem = pickle_load(open(p_segm_pickle, 'rb'))
        if not problem or problem._n_actors != args.n_actors:
            pose_ids, problem, data = more_actors_gurobi(
                data,
                n_actors=args.n_actors,
                constraints=pose_constraints,
                first_run=first_run)
            if True or show:
                show_multi(images,
                           data,
                           pose_ids,
                           problem,
                           p_dir=os.path.join(args.dir, os.pardir),
                           first_run=first_run,
                           n_actors=args.n_actors)
            pickle.dump((pose_ids, problem), open(p_segm_pickle, 'wb'), -1)
    else:
        pose_ids = greedy_actors(data, n_actors=args.n_actors)
        data = DataPosesWrapper(data=data)

    visible_f = {a: {} for a in range(args.n_actors)}
    visible_f_max = 0.
    if show:
        plt.ion()
        fig = None
        axe = None
        scatters = dict()

    # how many images we have
    min_frame_id = min(f for f in pose_ids)
    frames_mod = max(f for f in pose_ids) - min_frame_id + 1
    skel_ours = Skeleton(frames_mod=frames_mod,
                         n_actors=args.n_actors,
                         min_frame_id=min_frame_id)
    skel_ours_2d = Skeleton(frames_mod=frames_mod,
                            n_actors=args.n_actors,
                            min_frame_id=min_frame_id)

    # assert len(images) == 0 or max(f for f in images) + 1 == frames_mod, \
    #     "Assumed image count is %d, but max_frame_id is %d" \
    #     % (len(images), frames_mod-1)
    if isinstance(data, DataPosesWrapper):
        frames = data.get_frames()
    else:
        frames = []
        for frame_str in sorted(data.get_frames()):
            try:
                frame_id = int(frame_str.split('_')[1])
            except ValueError:
                print("skipping key %s" % frame_id)
                continue
            frames.append(frame_id)
    my_visibilities = [[], []]
    for frame_id in frames:
        frame_str = DataPosesWrapper._to_frame_str(frame_id)
        pose_in = data.get_poses_3d(frame_id=frame_id)
        # np.asarray(data[frame_str][u'centered_3d'])
        # pose_in_2d = np.asarray(data[frame_str][u'pose_2d'])
        pose_in_2d = data.get_poses_2d(frame_id=frame_id)
        # visible = np.asarray(data[frame_str][u'visible'])

        if False and len(pose_in.shape) > 2:
            pose_id = pose_ids[frame_id]
            if not args.no_img:
                im = cv2.cvtColor(images[frame_id], cv2.COLOR_RGB2BGR)
                for i in range(pose_in.shape[0]):
                    c = (1., 0., 0., 1.)
                    if i == pose_id:
                        c = (0., 1., 0., 1.)
                    color = tuple(int(c_ * 255) for c_ in c[:3])
                    for p2d in pose_in_2d[i, :, :]:
                        # color = (c[0] * 255, c[1] * 255., c[2] * 255.)
                        cv2.circle(im, (p2d[1], p2d[0]),
                                   radius=3,
                                   color=color,
                                   thickness=-1)
                    center = np.mean(pose_in_2d[i, :, :],
                                     axis=0).round().astype('i4').tolist()
                    cv2.putText(im, "%d" % i, (center[1], center[0]), 1, 1,
                                color)
                if show:
                    cv2.imshow("im", im)
                    cv2.waitKey(100)
            # if sid not in scatters:
            #     scatters[sid] = axe.scatter(pose_in_2d[i, :, 1], pose_in_2d[i, :, 0], c=c)
            # else:
            #     scatters[sid].set_offsets(pose_in_2d[i, :, [1, 0]])
            #     scatters[sid].set_array(np.tile(np.array(c), pose_in_2d.shape[1]))
            # scatter.set_color(c)
            # plt.draw()
            # plt.pause(1.)
            pose_in = pose_in[pose_id, :, :]
            pose_in_2d = pose_in_2d[pose_id, :, :]
            visible = visible[pose_id]
        # else:
        # pose_id = 0
        # pose_id = pose_ids[frame_id]

        for actor_id in range(args.n_actors):
            # if actor_id in (2, 3, 4, 5, 8, 9)
            # expanded frame_id
            frame_id2 = Skeleton.unmod_frame_id(frame_id=frame_id,
                                                actor_id=actor_id,
                                                frames_mod=frames_mod)
            assert (actor_id != 0) ^ (frame_id2 == frame_id), "no"
            frame_id_mod = skel_ours.mod_frame_id(frame_id=frame_id2)

            assert frame_id_mod == frame_id, \
                "No: %d %d %d" % (frame_id, frame_id2, frame_id_mod)
            actor_id2 = skel_ours.get_actor_id(frame_id2)
            assert actor_id2 == actor_id, "no: %s %s" % (actor_id, actor_id2)

            # which pose explains this actor in this frame
            pose_id = pose_ids[frame_id][actor_id]
            # check, if actor found
            if pose_id < 0:
                continue

            # 3D pose
            pose = pose_in[pose_id, :, JointDenis.revmap].T
            # added by Aron on 4/4/2018 (Denis' pelvis is too high up)
            pose[:, Joint.PELV] = (pose[:, Joint.LHIP] + pose[:, Joint.RHIP]) \
                                  / 2.
            skel_ours.set_pose(frame_id2, pose)

            # 2D pose
            pose_2d = pose_in_2d[pose_id, :, :]
            arr = np.array(JointDenis.pose_2d_to_ours(pose_2d),
                           dtype=np.float32).T
            skel_ours_2d.set_pose(frame_id2, arr)

            #
            # visibility (binary) and confidence (float)
            #

            # np.asarray(data[frame_str][u'visible'][pose_id])
            vis_i = data.get_visibilities(frame_id)[pose_id]

            # vis_f = np.asarray(data[frame_str][u'visible_float'][pose_id])
            vis_f = data.get_confidences(frame_id)[pose_id]
            for jid, visible in enumerate(vis_i):  # for each joint
                # binary visibility
                jid_ours = JointDenis.to_ours_2d(jid)
                skel_ours_2d.set_visible(frame_id2, jid_ours, visible)

                # confidence (fractional visibility)
                if np.isnan(vis_f[jid]):
                    continue

                try:
                    visible_f[actor_id][frame_id2][jid_ours] = vis_f[jid]
                except KeyError:
                    visible_f[actor_id][frame_id2] = {jid_ours: vis_f[jid]}
                visible_f_max = max(visible_f_max, vis_f[jid])
                conf_ = get_conf_thresholded(vis_f[jid],
                                             thresh_log_conf=None,
                                             dtype_np=np.float32)
                skel_ours_2d.set_confidence(frame_id=frame_id2,
                                            joint=jid_ours,
                                            confidence=conf_)
                my_visibilities[0].append(vis_f[jid])
                my_visibilities[1].append(conf_)
            skel_ours_2d._confidence_normalized = True

    plt.figure()
    plt.plot(my_visibilities[0], my_visibilities[1], 'o')
    plt.savefig('confidences.pdf')

    assert skel_ours.n_actors == args.n_actors, "no"
    assert skel_ours_2d.n_actors == args.n_actors, "no"
    # align to room
    min_z = np.min(skel_ours.poses[:, 2, :])
    print("min_max: %s, %s" % (min_z, np.max(skel_ours.poses[:, 2, :])))
    skel_ours.poses[:, 2, :] += min_z
    skel_ours.poses /= 1000.
    # The output is scaled to 2m by Denis.
    # We change this to 1.8 * a scale in order to correct for
    # the skeletons being a bit too high still.
    skel_ours.poses *= \
        args.person_height * conf.optimize_path.height_correction / 2.
    skel_ours.poses[:, 2, :] *= -1.
    skel_ours.poses = skel_ours.poses[:, [0, 2, 1], :]

    # refine
    name_video = args.dir.split(os.sep)[-2]
    out_path = os.path.join(args.dir, os.pardir,
                            "skel_%s_%s.json" % (name_video, args.postfix))
    out_path_orig = os.path.join(args.dir, os.pardir,
                                 "skel_%s_lfd_orig.json" % name_video)
    sclt_orig = Scenelet(skeleton=copy.deepcopy(skel_ours))
    sclt_orig.save(out_path_orig)

    skel_ours_2d_all = copy.deepcopy(skel_ours_2d)
    assert len(skel_ours_2d_all.get_frames()), skel_ours_2d_all.get_frames()

    #
    # Optimize
    #

    # frames_ignore = [(282, 372), (516, 1000)]

    skel_ours, skel_ours_2d, intrinsics, \
    frame_ids_filled_in = prepare(
      args.camera_name,
      winsorize_limit=args.winsorize_limit,
      shape_orig=shape_orig,
      path_scene=p_scene,
      skel_ours_2d=skel_ours_2d,
      skel_ours=skel_ours,
      resample=args.resample,
    path_skel=path_skeleton)
    frames_ignore = []
    tr_ground = np.eye(4, dtype=np.float32)
    skel_opt, out_images, K = \
        optimize_path(
          skel_ours, skel_ours_2d, images, intrinsics=intrinsics,
          path_skel=out_path, shape_orig=shape_orig,
          use_huber=args.huber, weight_smooth=args.smooth,
          frames_ignore=frames_ignore, resample=args.resample,
          depth_init=scene_params['depth_init'],
          ground_rot=ground_rot)

    for frame_id in skel_opt.get_frames():
        skel_opt.set_time(frame_id=frame_id, time=float(frame_id) / args.r)

    skel_opt_raw = copy.deepcopy(skel_opt)
    skel_opt_resampled = Skeleton.resample(skel_opt)

    # Filter pelvis
    if args.with_filtering:
        out_filter_path = os.path.join(args.dir, os.pardir, "vis_filtering")
        skel_opt = filter_(skel_opt_resampled,
                           out_filter_path=out_filter_path,
                           skel_orig=skel_opt,
                           weight_smooth=args.smooth,
                           forwards_window_size=args.forwards_window_size)
    else:
        skel_opt.estimate_forwards(k=args.forwards_window_size)
        skel_opt_resampled.estimate_forwards(k=args.forwards_window_size)

    # if len(images):
    #     skel_opt.fill_with_closest(images.keys()[0], images.keys()[-1])

    min_y, max_y = skel_opt.get_min_y(tr_ground)
    print("min_y: %s, max_y: %s" % (min_y, max_y))

    #
    # save
    #
    frame_ids_old = set(skel_opt.get_frames())
    if args.resample:
        skel_opt = skel_opt_resampled
        frame_ids_filled_in.update(
            set(skel_opt.get_frames()).difference(frame_ids_old))
        lg.warning("Saving resampled scenelet!")
    scenelet = Scenelet(skel_opt)
    del skel_opt
    # skel_dict = skel_opt.to_json()
    tr_ground[1, 3] = min_y
    scenelet.aux_info['ground'] = tr_ground.tolist()
    assert isinstance(ground_rot, list) and len(ground_rot) == 3
    scenelet.add_aux_info('ground_rot', ground_rot)
    scenelet.add_aux_info(
        'path_opt_params', {
            'rate': args.r,
            'w-smooth': args.smooth,
            'winsorize-limit': args.winsorize_limit,
            'camera': args.camera_name,
            'huber': args.huber,
            'height_correction': conf.optimize_path.height_correction,
            'focal_correction': conf.optimize_path.focal_correction
        })
    scenelet.add_aux_info('frame_ids_filled_in', list(frame_ids_filled_in))

    # To MATLAB
    # _skeleton.get_min_y(_tr_ground)
    # with skel_opt as skeleton:
    # skeleton = skel_opt
    # skeleton_name = os.path.split(args.dir)[0]
    # skeleton_name = skeleton_name[skeleton_name.rfind('/')+1:]
    # mdict = skeleton.to_mdict(skeleton_name)
    # mdict['room_transform'] = tr_ground
    # mdict['room_transform'][1, 3] *= -1.
    # print(mdict)
    # print("scene_name?: %s" % os.path.split(args.dir)[0])
    # skeleton.save_matlab(
    #     os.path.join(os.path.dirname(args.dir), "skeleton_opt.mat"),
    #     mdict=mdict)

    assert scenelet.skeleton.has_forwards(), "No forwards??"
    scenelet.save(out_path)
    if show:
        # save path plot
        out_path_path = os.path.join(args.dir, os.pardir,
                                     "%s_path.jpg" % name_video)
        path_fig = plot_path(scenelet.skeleton)
        legend = ["smooth %g" % args.smooth]

    # hack debug
    # path_skel2 = os.path.join(args.dir, os.pardir, 'skel_lobby7_nosmooth.json')
    # if os.path.exists(path_skel2):
    #     skel2 = Skeleton.load(path_skel2)
    #     path_fig = plot_path(skel2, path_fig)
    #     legend.append('no smooth')
    if show:
        plt.legend(legend)
        path_fig.savefig(out_path_path)

    # backup args
    path_args = os.path.join(args.dir, os.pardir, 'args_denis.txt')
    with open(path_args, 'a') as f_args:
        f_args.write("%s %s\n" %
                     (os.path.basename(sys.executable), " ".join(argv)))

    # save 2D detections to file
    if args.postfix == 'unannot':
        path_skel_ours_2d = os.path.join(
            args.dir, os.pardir, "skel_%s_2d_%02d.json" % (name_video, 0))
        sclt_2d = Scenelet(skel_ours_2d_all)
        print('Saving {} to {}'.format(len(skel_ours_2d_all.get_frames()),
                                       path_skel_ours_2d))
        sclt_2d.skeleton.aux_info = {}
        sclt_2d.save(path_skel_ours_2d)
    else:
        print(args.postfix)

    logging.info("Saving images...")
    if len(images) and len(out_images):
        path_out_images = os.path.join(args.dir, os.pardir, 'color')
        try:
            os.makedirs(path_out_images)
        except OSError:
            pass
        visible_f_max_log = np.log(visible_f_max)
        frames = list(out_images.keys())
        for frame_id in range(frames[0], frames[-1] + 1):
            im = out_images[frame_id] if frame_id in out_images \
                else cv2.cvtColor(images[frame_id], cv2.COLOR_BGR2RGB)
            for actor_id in range(args.n_actors):
                if frame_id in visible_f[actor_id]:
                    frame_id2 = skel_ours_2d_all.unmod_frame_id(
                        frame_id=frame_id,
                        actor_id=actor_id,
                        frames_mod=skel_ours_2d_all.frames_mod)
                    for joint, is_vis in visible_f[actor_id][frame_id].items():
                        p2d = skel_ours_2d_all.get_joint_3d(joint,
                                                            frame_id=frame_id2)
                        # radius = np.log(is_vis) / visible_f_max_log
                        # lg.debug("r0: %g" % radius)
                        # radius = np.exp(np.log(is_vis) / visible_f_max_log)
                        # lg.debug("radius is %g" % radius)
                        vis_bool = True
                        if skel_ours_2d_all.has_visible(frame_id=frame_id2,
                                                        joint_id=joint):
                            vis_bool &= skel_ours_2d_all.is_visible(
                                frame_id2, joint)
                        radius = abs(np.log(is_vis / 0.1 + 1e-6))
                        if not np.isnan(radius):
                            p2d = (int(round(p2d[0])), int(round(p2d[1])))
                            cv2.circle(im,
                                       center=p2d,
                                       radius=int(round(radius)),
                                       color=(1., 1., 1., 0.5),
                                       thickness=1)
                            conf = get_conf_thresholded(conf=is_vis,
                                                        thresh_log_conf=None,
                                                        dtype_np=np.float32)
                            if conf > 0.5:
                                cv2.putText(img=im,
                                            text=Joint(joint).get_name(),
                                            org=p2d,
                                            fontFace=1,
                                            fontScale=1,
                                            color=(10., 150., 10., 100.))
                    # lg.debug("set visibility to %g, radius %g" % (is_vis, radius))
            # if frame_id in out_images:
            scale = (shape_orig[1] / float(im.shape[1]),
                     shape_orig[0] / float(im.shape[0]))
            cv2.imwrite(
                os.path.join(path_out_images, "color_%05d.jpg" % frame_id),
                cv2.resize(im, (0, 0),
                           fx=scale[0],
                           fy=scale[1],
                           interpolation=cv2.INTER_CUBIC))
            # else:
            #     fname = "color_%05d.jpg" % frame_id
            #     shutil.copyfile(
            #         os.path.join(path_images, fname),
            #         os.path.join(path_out_images, fname))
        lg.info("Wrote images to %s/" % path_out_images)
Example #8
0
def evaluate(named_solution,
             sclt_gt,
             sclt_gt_2d,
             frame_ids,
             path_scene,
             stats,
             actions=None,
             scale=100.):
    """
    
    :param named_solution:
    :param sclt_gt:
    :param sclt_gt_2d:
    :param frame_ids:
    :param path_scene:
    :param stats:
    :param actions:
    :param scale: scale from meter to cm
    :return:
    """
    p_intrinsics = os.path.join(path_scene, 'intrinsics.json')
    intrinsics = np.array(json.load(open(p_intrinsics, 'r')), dtype=np.float32)
    print('Loading {}'.format(named_solution.path))
    sclt_sol = Scenelet.load(named_solution.path)
    sclt_sol.skeleton._visibility.clear()
    sclt_sol.skeleton._confidence.clear()
    sclt_sol.skeleton._forwards.clear()
    sclt_sol.skeleton = Skeleton.resample(sclt_sol.skeleton)
    err_3d = Comparison(title='World',
                        path_scene=path_scene,
                        name_method=named_solution.name_method,
                        stats=stats)
    err_3d_local = Comparison(title='Local',
                              path_scene=path_scene,
                              name_method=named_solution.name_method,
                              stats=stats)
    err_2d = Comparison(title='2D',
                        path_scene=path_scene,
                        name_method=named_solution.name_method,
                        stats=stats)

    occlusion = sclt_gt.aux_info['occluded']
    missing = {'method': [], 'gt': []}
    for frame_id in frame_ids:
        try:
            entry = sclt_sol.skeleton.get_pose(frame_id=frame_id)
        except KeyError:
            missing['method'].append(frame_id)
            continue
        if actions is not None and frame_id in actions \
          and actions[frame_id] == 'walking':
            print('Skipping non-interactive frame {} {}'.format(
                frame_id, actions[frame_id]))
            continue

        # 3D
        gt = sclt_gt.skeleton.get_pose(frame_id=frame_id)
        occluded = occlusion['{:d}'.format(frame_id)]
        err_3d.add(entry=entry,
                   gt=gt,
                   frame_id=frame_id,
                   scale=scale,
                   occluded=occluded)

        # Local 3D
        local_entry = entry - entry[:, Joint.PELV:Joint.PELV + 1]
        local_gt = gt - gt[:, Joint.PELV:Joint.PELV + 1]
        err_3d_local.add(entry=local_entry,
                         gt=local_gt,
                         frame_id=frame_id,
                         scale=scale,
                         occluded=occluded)

        #
        # GT 2D
        #

        gt_2d = sclt_gt_2d.skeleton.get_pose(frame_id=frame_id)
        entry_2d = entry[:2, :] / entry[2, :]
        entry_2d[0, :] *= intrinsics[0, 0]
        entry_2d[1, :] *= intrinsics[1, 1]
        entry_2d[0, :] += intrinsics[0, 2]
        entry_2d[1, :] += intrinsics[1, 2]

        err_2d.add(entry=entry_2d,
                   gt=gt_2d[:2, :],
                   frame_id=frame_id,
                   occluded=occluded)

    # stats.paint(path_dest=os.path.join(path_scene, 'debug_eval'))
    mn, mx = np.min(sclt_gt.skeleton.poses, axis=(0, 2)), \
             np.max(sclt_gt.skeleton.poses, axis=(0, 2))
    err_3d.dimensions = (mx - mn) * scale

    assert len(missing['method']) < len(frame_ids) / 2, (missing, frame_ids)

    return OrderedDict({
        err_3d.title: err_3d,
        err_3d_local.title: err_3d_local,
        err_2d.title: err_2d,
        '_missing': missing
    })
Example #9
0
def show_folder(argv):
    # python3 stealth/pose/fit_full_video.py --show /home/amonszpa/workspace/stealth/data/video_recordings/scenelets/lobby15 opt1
    # python3 stealth/pose/visualization/show_charness_scores.py --show /media/data/amonszpa/stealth/shared/video_recordings/library1 -o opt1
    pjoin = os.path.join

    parser = argparse.ArgumentParser("Fit full video")
    parser.add_argument('--show', action='store_true')
    parser.add_argument("video", type=argparse_check_exists, help="Input path")
    parser.add_argument(
        '-o',
        '--opt-folder',
        help="Which optimization output to process. Default: opt1",
        default='opt1')
    parser.add_argument("--window-size",
                        type=int,
                        help="Window size in frames.",
                        default=20)

    args = parser.parse_args(argv)
    d = os.path.join(args.video, args.opt_folder)
    assert os.path.exists(d), "does not exist: %s" % d

    # parse video path
    if args.video.endswith(os.sep):
        args.video = args.video[:-1]
    name_query = os.path.split(args.video)[-1]
    print("split: %s" % repr(os.path.split(args.video)))
    p_query = pjoin(args.video, "skel_%s_unannot.json" % name_query) \
        if os.path.isdir(args.video) else args.video
    assert p_query.endswith('.json'), "Need a skeleton file"

    # load initial video path (local poses)
    query = Scenelet.load(p_query, no_obj=True)

    frame_ids = query.skeleton.get_frames()
    centroids = Skeleton.get_resampled_centroids(start=frame_ids[0],
                                                 end=frame_ids[-1],
                                                 old_frame_ids=frame_ids,
                                                 poses=query.skeleton.poses)

    depths_times_charnesses = []
    skeleton = Skeleton()
    depths = []
    skeleton.charness_poses = {}  # this is in Scenelet incorrectly...
    skeleton.score_fit = {}  # inventing this now
    skeleton.score_reproj = {}  # inventing this now
    for p in sorted(os.listdir(d)):
        d_time = pjoin(d, p)
        if not os.path.isdir(d_time):
            continue
        p_skel = next(
            f for f in os.listdir(d_time) if os.path.isfile(pjoin(d_time, f))
            and f.startswith('skel') and f.endswith('json') and '_00' in f)
        sclt = Scenelet.load(pjoin(d_time, p_skel))
        mn, mx = sclt.skeleton.get_frames_min_max()
        frame_id = mn + (mx - mn) // 2
        if query.skeleton.has_pose(frame_id):
            pos_3d = query.skeleton.get_centroid_3d(frame_id)
        else:
            lin_id = frame_id - frame_ids[0]
            pos_3d = centroids[lin_id, :]

        # put centroid for each joint
        skeleton.set_pose(frame_id=frame_id,
                          pose=np.tile(pos_3d[:, None], (1, 16)))
        with open(pjoin(d_time, 'avg_charness.json')) as fch:
            data = json.load(fch)
            set_or_max(skeleton.charness_poses, frame_id, data['avg_charness'])
            # if frame_id in skeleton.charness_poses:
            #     lg.warning("Maxing charness at frame %d" % frame_id)
            #     skeleton.charness_poses[frame_id] = max(
            #       skeleton.charness_poses[frame_id], data['avg_charness'])
            # else:
            #     skeleton.charness_poses[frame_id] = data['avg_charness']

        # fit scores
        if 'score_fit' in sclt.aux_info:
            set_or_max(skeleton.score_fit, frame_id,
                       sclt.aux_info['score_fit'])
        else:
            set_or_max(skeleton.score_fit, frame_id, 0.)

        if 'score_reproj' in sclt.aux_info:
            set_or_max(skeleton.score_reproj, frame_id,
                       sclt.aux_info['score_reproj'])
        else:
            set_or_max(skeleton.score_reproj, frame_id, 0.)

    fig = plt.figure(figsize=(16, 12), dpi=100)
    ax = fig.add_subplot(121, aspect='equal')
    X = []  # skeleton x
    Z = []  # skeleton z (depth)
    C = []  # charness
    F = []  # score_fit
    R = []  # score_reproj
    T = []  # times
    for frame_id in skeleton.get_frames():
        c = skeleton.get_joint_3d(6, frame_id=frame_id)
        X.append(c[0])
        Z.append(c[2])
        C.append(skeleton.charness_poses[frame_id])
        F.append(skeleton.score_fit[frame_id])
        R.append(skeleton.score_reproj[frame_id])
        T.append(frame_id)
    ax.plot(X, Z, 'k--')
    for frame_id in skeleton.get_frames():
        if frame_id % 5:
            continue
        c = skeleton.get_joint_3d(6, frame_id=frame_id)
        ax.annotate("%d" % frame_id, xy=(c[0], c[2]), zorder=5)
    cax = ax.scatter(X, Z, c=C, cmap='jet', zorder=5)
    fig.colorbar(cax)
    z_lim = (min(Z), max(Z))
    z_span = (z_lim[1] - z_lim[0]) // 2
    x_lim = min(X), max(X)
    x_span = (x_lim[1] - x_lim[0]) // 2
    pad = .5
    dspan = z_span - x_span
    if dspan > 0:
        ax.set_xlim(x_lim[0] - dspan - pad, x_lim[1] + dspan + pad)
        ax.set_ylim(z_lim[0] - pad, z_lim[1] + pad)
    else:
        ax.set_xlim(x_lim[0] - pad, x_lim[1] + pad)
        ax.set_ylim(z_lim[0] + dspan - pad, z_lim[1] - dspan + pad)
    ax.set_title('Fit score weighted characteristicness\ndisplayed at '
                 'interpolated initial path position')

    ax = fig.add_subplot(122)

    ax.plot(T, C, 'x--', label='max charness')
    charness_threshes = [0.4, 0.35, 0.3]
    mn_thr_charness = min(charness_threshes)
    mx_thr_charness = max(charness_threshes)
    for ct in charness_threshes:
        ax.plot([T[0], T[-1]], [ct, ct], 'r')
        ax.annotate("charness %g" % ct, xy=(T[0], ct + 0.005))

    charness_sorted = sorted([(fid, c)
                              for fid, c in skeleton.charness_poses.items()],
                             key=lambda e: e[1])

    to_show = []
    # Fitness
    divisor = 5.
    F_ = -np.log10(F) / divisor
    print(F_)
    ax.plot(T, F_, 'x--', label="-log_10(score) / %.0f" % divisor)
    mx_F_ = np.percentile(F_, 90)  # np.max(F_)
    for i, (t, f) in enumerate(zip(T, F_)):
        if f > mx_F_ or any(C[i] > ct for ct in charness_threshes):
            to_show.append(i)
            # ax.annotate("%.4f" % (F[i]), xy=(t, f), xytext=(t+4, f-0.02),
            #             arrowprops=dict(facecolor='none', shrink=0.03))
            # charness
            # ax.annotate("%.3f\n#%d" % (C[i], t), xy=(t, C[i]),
            #             xytext=(t-10, C[i]-0.02),
            #             arrowprops=dict(facecolor='none', shrink=0.03))

    windows = []  # [(t_start, t_max, t_end), ...]
    crossings = {}

    # Reproj
    R_ = -np.log10(R) / divisor
    # ax.plot(T, R_, 'x--', label="-log_10(score reproj) / %.0f" % divisor)
    mx_R_ = np.max(R_)
    is_above = [False for _ in charness_threshes]
    mx_above = []
    for i, (t, r) in enumerate(zip(T, R_)):
        # if i in to_show:
        # ax.annotate("%.4f" % (R[i]), xy=(t, r), xytext=(t-10, r+0.02),
        #             arrowprops=dict(facecolor='none', shrink=0.03))
        # ax.annotate("%d" % t, xy=(t, r - 0.01))
        if (i + 1 < len(C)) and (C[i] > C[i + 1]) and (C[i] > mn_thr_charness):
            mx_above.append((C[i], t))
        for thr_i, thr in enumerate(charness_threshes):
            if (C[i] > thr) != is_above[thr_i] \
              or (C[i] > mx_thr_charness and not is_above[thr_i]):
                step = 15 * (len(charness_threshes) - thr_i) \
                    if is_above[thr_i] \
                    else -15 * thr_i

                if is_above[thr_i]:
                    if 'down' not in crossings:
                        crossings['down'] = (C[i], t)
                    # else:
                    #     assert crossings['down'][0] > C[i], (crossings['down'][0], C[i])
                else:
                    if 'up' not in crossings:
                        crossings['up'] = (C[i - 1], t)
                    elif crossings['up'][0] < C[i - 1]:
                        crossings['up'] = (C[i - 1], t)

                # ax.annotate("%.3f\n#%d" % (C[i], t), xy=(t, C[i]),
                #             xytext=(t + step, C[i]-0.1),
                #             arrowprops=dict(facecolor='none', shrink=0.03))
                if C[i] < mn_thr_charness and is_above[thr_i]:
                    try:
                        c, t = max((e for e in mx_above), key=lambda e: e[0])
                        ax.annotate("%.3f\n#%d" % (c, t),
                                    xy=(t, c),
                                    xytext=(t + step, c + 0.1),
                                    arrowprops=dict(facecolor='none',
                                                    shrink=0.03))
                        mx_above = []
                        windows.append(
                            (crossings['up'][1], t, crossings['down'][1]))
                    except (KeyError, ValueError):
                        lg.warning("Can't find gap: %s, %s" %
                                   (crossings, mx_above))
                    crossings = {}

                is_above[thr_i] = C[i] > thr
                break

    for crossing in windows:
        for i, t in enumerate(crossing):
            c = skeleton.charness_poses[t]
            step = -15 + i * 10
            ax.annotate("%.3f\n#%d" % (c, t),
                        xy=(t, c),
                        xytext=(t + step, c - 0.1),
                        arrowprops=dict(facecolor='none', shrink=0.03))

    # extract_gaps([args.video])

    # labels
    ax.set_title("Scores and charness w.r.t time: max charness: #%d %g" %
                 (charness_sorted[-1][0], charness_sorted[-1][1]))
    ax.set_xlabel('integer time')
    ax.legend(loc='lower right')
    ax.grid(True)
    ax.yaxis.grid(which='both')
    ax.xaxis.set_ticks(np.arange(T[0] - 1, T[-1] + 1, 5))
    ax.set_yticks([])
    ax.set_ylim(0., 1.)
    ax.set_ylabel('higher is better')
    plt.suptitle("%s" % name_query)
    with open(os.path.join(d, 'charness_rank.csv'), 'w') as fout:
        fout.write("frame_id,charness\n")
        for fid_charness in reversed(charness_sorted):
            fout.write("{:d},{:g}\n".format(*fid_charness))
            print(fid_charness)
    # plt.show()
    p_out = os.path.join(d, 'charnesses.svg')
    plt.savefig(p_out)
    lg.debug("saved to %s" % p_out)
Example #10
0
    def to_skeleton(self, pose_ids, skeleton3d):
        """Use 'pose_ids' to convert back to an ordered Skeleton.

        Args:
            pose_ids (Dict[int, Dict[int, int]]):
                {frame_id => {actor_id => pose_id}}.
            skeleton3d (Skeleton):
                Skeleton containing 3D poses.
        Returns:
            out2d (Skeleton):
                2D skeleton with sorted actors.
            out3d (Skeleton):
                3D skeleton with sorted actors.
        """

        skeleton = self._skeleton
        n_actors = skeleton.n_actors
        frames_mod = skeleton.frames_mod
        min_frame_id = skeleton.min_frame_id

        out2d = copy.deepcopy(skeleton)
        out2d.clear_poses()
        out3d = copy.deepcopy(skeleton3d)
        out3d.clear_poses()
        for frame_id in pose_ids:
            for actor_id in range(n_actors):
                # expanded frame_id
                frame_id2_dst = Skeleton.unmod_frame_id(frame_id=frame_id,
                                                        actor_id=actor_id,
                                                        frames_mod=frames_mod)
                #
                # checks
                #

                assert (actor_id != 0) ^ (frame_id2_dst == frame_id), "no"
                frame_id_mod = out3d.mod_frame_id(frame_id=frame_id2_dst)

                assert frame_id_mod == frame_id, \
                    "No: %d %d %d" % (frame_id, frame_id2_dst, frame_id_mod)
                actor_id2 = out3d.get_actor_id(frame_id2_dst)
                assert actor_id2 == actor_id, \
                    "No: %s %s" % (actor_id, actor_id2)

                #
                # Work
                #

                # which pose explains this actor in this frame
                pose_id = pose_ids[frame_id][actor_id]
                # check, if actor found
                if pose_id < 0:
                    continue

                actor_and_frame_ids = self._pose_ids[frame_id][pose_id]
                assert actor_and_frame_ids.frame_id == frame_id
                # assert actor_and_frame_ids.actor_id == actor_id
                frame_id2_src = actor_and_frame_ids.frame_id2

                # 3D pose
                pose3d = skeleton3d.get_pose(frame_id=frame_id2_src)  # type: np.ndarray
                time = skeleton3d.get_time(frame_id=frame_id2_src)
                out3d.set_pose(frame_id=frame_id2_dst, pose=pose3d, time=time)

                # 2D pose
                pose2d = skeleton.get_pose(frame_id=frame_id2_src)
                assert skeleton.get_time(frame_id=frame_id2_src) == time, \
                    "Time mismatch: %g %g" \
                    % (skeleton.get_time(frame_id=frame_id2_src), time)
                out2d.set_pose(frame_id=frame_id2_dst, pose=pose2d, time=time)

                # confidence
                for jid, conf in skeleton.confidence[frame_id2_src].items():
                    out3d.set_confidence(frame_id=frame_id2_dst,
                                         joint=jid, confidence=conf)
                    out3d.set_visible(frame_id=frame_id2_dst, joint=jid,
                                      visible=conf > 0.5)
                    out2d.set_confidence(frame_id=frame_id2_dst,
                                         joint=jid, confidence=conf)
                    out2d.set_visible(frame_id=frame_id2_dst, joint=jid,
                                      visible=conf > 0.5)

        # Testing
        assert out2d.is_confidence_normalized()
        assert out3d.is_confidence_normalized()

        return out2d, out3d