Example #1
0
def load_images(path_images, n=50):
    images = {}
    shape_orig = None
    logging.info("Reading images...")
    path_images_pickle = os.path.join(path_images, 'images_0.pickle')
    if os.path.exists(path_images_pickle):
        logging.warning("Reading PICKLE from %s" % path_images_pickle)
        _gen = (os.path.join(path_images, path_file)
                for path_file in os.listdir(path_images)
                if path_file.endswith('pickle')
                and path_file.startswith('images_'))

        pool = multiprocessing.Pool(4)
        processes = []
        for path_file in _gen:
            processes.append(
                pool.apply_async(func=_load_chunk, args=[path_file]))
        pool.close()
        pool.join()
        for process in processes:
            pickled = process.get()
            if isinstance(pickled, tuple) and len(pickled) == 2:
                images.update(pickled[0])
                shape_orig = pickled[1]
            else:
                images.update(pickled)
        assert shape_orig is not None, \
            "Shape orig must be in one of the files"
    else:
        # load images
        _gen = (f for f in os.listdir(path_images) if f.endswith('jpg'))
        for f in _gen:
            frame_id = int(os.path.splitext(f)[0].split('_')[1])
            images[frame_id], shape_orig = \
                load_image(os.path.join(path_images, f))
        del frame_id, f, _gen
        #
        # save pickles
        #

        # sorted list of frame_ids
        keys = sorted(list(images.keys()))
        for id_pickle, i in enumerate(range(0, len(keys), n)):
            range_end = min(i + n, len(keys))
            _keys = keys[i:range_end]
            _images = {frame_id: images[frame_id] for frame_id in _keys}
            path_file = os.path.join(path_images,
                                     "images_%d.pickle" % id_pickle)
            with open(path_file, 'wb') as file_out:
                to_dump = (_images, shape_orig) \
                    if not i \
                    else _images
                pickle.dump(to_dump, file_out, protocol=-1)
                lg.debug("Saved to %s" % path_file)

        # pickle.dump((images, shape_orig), open(path_images_pickle, 'wb'))
        # logging.info("Saved PICKLE to %s" % path_images_pickle)
    logging.info("Finished loading images...")

    return images, shape_orig
Example #2
0
def get_grid_shapely(occup, res_orig):
    assert res_orig.shape == (4, ), "Expected xyz-theta resolution"
    room = occup.room
    assert room.shape == (3, 2), "Assumed 3D room shape"
    res_target = (occup.resolution[0], occup.resolution[2])

    start_x = room[0, 0] - res_orig[0] / 2.
    end_x = room[0, 1] + res_orig[0] / 2.
    span_x = (end_x - start_x)
    diff_x = span_x - int(span_x / res_target[0]) * res_target[0]
    start_x += diff_x / 2.
    end_x -= res_target[0]  # last square ends at end_x + res_target

    start_y = room[2, 0] - res_orig[2] / 2.
    end_y = room[2, 1] + res_orig[2] / 2.
    span_y = (end_y - start_y)
    diff_y = span_y - int(span_y / res_target[1]) * res_target[1]
    start_y += diff_y / 2.
    end_y -= res_target[1]  # last square ends at end_y + res_target

    grid_size = occup.get_grid_size()
    polys = []
    lg.debug("start_x: %s, end_x: %s, res_target: %s" %
             (start_x, end_x, res_target))
    for ix, x in enumerate(np.arange(start_x, end_x, res_target[0])):
        if ix >= grid_size[0]:
            continue
        for iy, y in enumerate(np.arange(start_y, end_y, res_target[1])):
            if iy >= grid_size[2]:
                continue
            box = geom.box(x, y, x + res_target[0], y + res_target[1])
            polys.append(GridPoly(box, area=box.area, xy=(ix, iy)))
        #assert iy == grid_size[2] - 1, "No: %s %s" % (iy, grid_size)
    #assert ix == grid_size[0] - 1, "No: %s %s %s" % (ix, x, grid_size)
    return polys
Example #3
0
    def add_frame(self, frame_id, n_vars):
        for pose_id in range(n_vars):
            try:
                self._constr[frame_id].append(len(self._vars))
            except KeyError:
                self._constr[frame_id] = [len(self._vars)]

            self._vars[(frame_id, pose_id)] = len(self._vars)
        lg.debug("vars: %s" % self._vars)
Example #4
0
def plot_charness(scenes, d_dir, ch_thresh=0.5):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    charnesses = [s.charness for s in scenes if s.charness > ch_thresh]
    ax.hist(charnesses, bins=30, cumulative=True)
    plt.title("Cumulative charness above %g" % ch_thresh)
    p = os.path.join(d_dir, 'charnesses.png')
    plt.savefig(p, dpi=200)
    lg.debug("Saved charnesses to %s" % p)
    plt.close()
Example #5
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 #6
0
def get_rectangle(poly, angle):
    """

    :param poly:
    :param angle:
    :return:
        [cx, cy, theta, sx, sy]
    """
    poly2 = saffinity.affine_transform(
        poly,
        [np.cos(angle), -np.sin(angle),
         np.sin(angle),
         np.cos(angle), 0, 0]  # a, b, d, e, cx, cy
    )

    params = [
        poly.centroid.x, poly.centroid.y, angle,
        poly2.bounds[2] - poly2.bounds[0], poly2.bounds[3] - poly2.bounds[1]
    ]

    if False:
        fig = plt.figure()
        ax = fig.add_subplot(111, aspect='equal')
        ax.add_artist(PolygonPatch(poly, facecolor='b', alpha=0.9))
        lg.debug("poly: %s,\nangle: %s" % (poly, np.rad2deg(angle)))
        lg.debug("bounds: %s" % repr(poly.bounds))
        lg.debug("poly2.centroid: %s" % poly2.centroid)
        lg.debug("poly.centroid: %s" % poly.centroid)
        dc = (poly.centroid.x - poly2.centroid.x,
              poly.centroid.y - poly2.centroid.y)
        lg.debug("dc: %s" % repr(dc))
        poly2 = saffinity.translate(poly2, dc[0], dc[1])
        ax.add_artist(PolygonPatch(poly2, facecolor='r', alpha=0.8))
        ax.set_xlim(min(poly.bounds[0], poly2.bounds[0]),
                    max(poly.bounds[2], poly2.bounds[2]))
        ax.set_ylim(min(poly.bounds[1], poly2.bounds[1]),
                    max(poly.bounds[3], poly2.bounds[3]))

        plt.show()

    return params
    def test(py_p, py_poly):
        np.set_printoptions(suppress=True)
        with open('/tmp/test_p_poly_dist.json', 'r') as fin:
            jdata = json.load(fin)

        wrapped = []
        for row in py_poly:
            wrapped.append(np.concatenate((row, row[0:1, :])))
        wrapped = np.array(wrapped, dtype=np.float64)
        lg.debug("wrapped:\n%s" % wrapped)
        graph = tf.Graph()
        with graph.as_default(), tf.device('/gpu:0'):
            p = tf.Variable(initial_value=py_p,
                            dtype=tf.float64,
                            trainable=False)
            poly = tf.Variable(initial_value=wrapped,
                               dtype=tf.float64,
                               trainable=False)
            # d, g, sel = PointPolyDistanceEstimator.point_poly_distance(p, poly)
            d = PointPolyDistanceEstimator.point_poly_distance(p, poly)

        with tf.Session(graph=graph) as session:
            # init
            session.run(tf.global_variables_initializer())

            o_d = session.run(d)
            # o_d, o_g, o_sel = session.run([d, g, sel])
            # lg.debug("gradients: %s" % o_g)
            # lg.debug("sel: %s" % o_sel)

        lg.debug("o_d (%s):\n%s" % (repr(o_d.shape), o_d))
        assert np.allclose(o_d,
                           np.squeeze(np.array(jdata['d']), axis=-1), atol=0.001), \
            "no:\n%s\n%s\n%s\n%s" \
            % ('o_d: ', o_d,
               'gt d: ', np.squeeze(np.array(jdata['d']), axis=-1))
Example #8
0
def main(argv):
    np.set_printoptions(suppress=True, linewidth=200)
    pjoin = os.path.join

    parser = argparse.ArgumentParser("matcher")
    parser.add_argument("d_scenelets",
                        type=argparse_check_exists,
                        help="Folder containing scenelets")
    parser.add_argument("video", type=argparse_check_exists, help="Input path")
    parser.add_argument("--gap-size-limit",
                        type=int,
                        help="Smallest gap size to still explain")
    args = parser.parse_args(argv)
    d_query = os.path.dirname(args.video)

    # 2d keypoint rescale
    p_im = pjoin(d_query, 'origjpg', 'color_00100.jpg')
    im_ = cv2.imread(p_im)
    shape_orig = im_.shape
    scale_2d = shape_orig[0] / float(INPUT_SIZE)

    query = Scenelet.load(args.video, no_obj=True)
    tr_ground = np.array(query.aux_info['ground'], dtype=np.float32)
    print("tr: %s" % tr_ground)

    name_query = os.path.basename(args.video).split('_')[1]
    query_2d = Scenelet.load(pjoin(d_query,
                                   "skel_%s_2d_00.json" % name_query)).skeleton
    p_intr = pjoin(d_query, 'intrinsics.json')
    intr = np.array(json.load(open(p_intr, 'r')), dtype=np.float32)
    lg.debug("intr: %s" % intr)

    gaps = find_gaps(query.skeleton, min_pad=1)

    p_scenelets_pickle = pjoin(args.d_scenelets, 'match_gap_scenelets.pickle')
    if os.path.exists(p_scenelets_pickle):
        scenelets = pickle_load(open(p_scenelets_pickle, 'rb'))
    else:
        scenelets = read_scenelets(args.d_scenelets, limit=0)
        pickle.dump(scenelets, open(p_scenelets_pickle, 'wb'))

    p_out_sclts = pjoin(d_query, 'fill')
    if os.path.exists(p_out_sclts):
        shutil.rmtree(p_out_sclts)
    os.makedirs(p_out_sclts)
    times = []
    for gap_id, gap in enumerate(gaps):
        lg.debug("gap is %s" % repr(gap))
        if gap[1] - gap[0] < args.gap_size_limit:
            continue
        with Timer("gap %d" % gap_id) as timer:
            chosen = []
            for sc_id, sclt in enumerate(scenelets):
                lg.info("scenelet %d / %d" % (sc_id, len(scenelets)))
                sclt = scenelets[sc_id]
                ground_obj = next(ob for ob in sclt.objects.values()
                                  if ob.label == 'floor')
                ground_part = ground_obj.get_part_by_name('floor')
                lg.debug("floor: %s" % ground_part)
                ground_transform = ground_part.obb.as_transform()
                lg.debug("floor: %s" % ground_transform)
                # sys.exit(0)
                # chosen.extend(
                out_sclts = match(query,
                                  d_query,
                                  query_2d,
                                  sclt,
                                  intr,
                                  gap,
                                  tr_ground,
                                  scale=scale_2d)
                if not len(out_sclts):
                    continue
                # pick best from scene
                chosen.append(
                    [out_sclts[0][i]
                     for i in range(len(out_sclts[0]))] + [sc_id])
                # break

            # os.system("rm %s/skel_%s_fill_%03d_%03d__*.json"
            #           % (p_out_sclts, name_query, gap[0], gap[1]))
            chosen = sorted(chosen, key=lambda score_sclt: score_sclt[0])
            for sid, (score, out_sclt, sc_id) in enumerate(chosen):
                p_out = pjoin(
                    p_out_sclts, "skel_%s_fill_%03d_%03d__%02d.json" %
                    (name_query, gap[0], gap[1], sid))
                out_sclt.save(p_out)
                if sid > 5:
                    break
        times.append(timer.get_elapsed_ms())
    lg.info("mean time per gap: %s" % np.mean(times))
Example #9
0
def match(query_full,
          d_query,
          query_2d_full,
          scene,
          intr,
          gap,
          tr_ground,
          scale,
          thresh_log_conf=7.5,
          w_3d=0.01,
          fps=3,
          step_samples=100):
    with_y = False  # optimize for y as well
    np.set_printoptions(suppress=True, linewidth=220)

    pjoin = os.path.join

    len_gap = gap[1] - gap[0] + 1
    query, q_v = get_partial_scenelet(query_full,
                                      start=gap[0],
                                      end=gap[1] + 1,
                                      fps=1)
    q_v_sum = np.sum(q_v)
    q_v_sum_inv = np.float32(1. / q_v_sum)
    # lg.debug("q_v_sum: %s/%s" % (q_v_sum, q_v.size))
    # scene_min_y = scene.skeleton.get_min_y(tr_ground)
    # lg.debug("scene_min_y: %s" % repr(scene_min_y))

    mid_frames = range(len_gap * fps,
                       scene.skeleton.poses.shape[0] - len_gap * fps,
                       step_samples)
    if not len(mid_frames):
        return []

    scenelets, sc_v = (np.array(e) for e in zip(*[
        get_partial_scenelet(
            scene, mid_frame_id=mid_frame_id, n_frames=len_gap, fps=fps)
        for mid_frame_id in mid_frames
    ]))
    # for i, (scenelet, sc_v_) in enumerate(zip(scenelets, sc_v)):
    #     mn = np.min(scenelet[sc_v_.astype('b1'), 1, :])
    #     scenelets[i, :, 1, :] -= mn
    # mn = np.min(scenelets[i, sc_v_.astype('b1'), 1, :])
    # scenelets = np.array(scenelets, dtype=np.float32)
    # sc_v = np.array(sc_v, dtype=np.int32)
    # print("sc_v: %s" % sc_v)
    # print("q_v: %s" % q_v)

    lg.debug("have %d/%d 3D poses in scenelet, and %d/%d in query" %
             (np.sum(sc_v), sc_v.shape[0], np.sum(q_v), q_v.shape[0]))

    query_2d = np.zeros((len_gap, 2, 16), dtype=np.float32)
    conf_2d = np.zeros((len_gap, 1, 16), dtype=np.float32)
    for lin_id, frame_id in enumerate(range(gap[0], gap[1] + 1)):

        if query_2d_full.has_pose(frame_id):
            query_2d[lin_id, :, :] = query_2d_full.get_pose(frame_id)[:2, :]
        # else:
        #     lg.warning("Query2d_full does not have pose at %d?" % frame_id)

        # im = im_.copy()
        if query_2d_full.has_confidence(frame_id):
            # print("showing %s" % frame_id)
            for joint, conf in query_2d_full._confidence[frame_id].items():
                log_conf = abs(np.log(conf)) if conf >= 0. else 0.
                # print("conf: %g, log_conf: %g" % (conf, log_conf))
                # if log_conf <= thresh_log_conf:
                #     p2d = scale * query_2d_full.get_joint_3d(joint,
                #                                              frame_id=frame_id)
                #     p2d = (int(round(p2d[0])), int(round(p2d[1])))
                #     cv2.circle(im, center=p2d,
                #                radius=int(round(3)),
                #                color=(1., 1., 1., 0.5), thickness=1)
                conf_2d[lin_id, 0, joint] = max(
                    0., (thresh_log_conf - log_conf) / thresh_log_conf)

            # cv2.imshow('im', im)
            # cv2.waitKey(100)
    # while cv2.waitKey() != 27: pass
    conf_2d /= np.max(conf_2d)

    # scale from Denis' scale to current image size
    query_2d *= scale

    # move to normalized camera coordinates
    query_2d -= intr[:2, 2:3]
    query_2d[:, 0, :] /= intr[0, 0]
    query_2d[:, 1, :] /= intr[1, 1]

    #
    # initialize translation
    #

    # centroid of query poses
    c3d = np.mean(query[q_v.astype('b1'), :, :], axis=(0, 2))
    # estimate scenelet centroids
    sclt_means = np.array([
        np.mean(scenelets[i, sc_v[i, ...].astype('b1'), ...], axis=(0, 2))
        for i in range(scenelets.shape[0])
    ],
                          dtype=np.float32)
    # don't change height
    sclt_means[:, 1] = 0
    scenelets -= sclt_means[:, None, :, None]
    lg.debug("means: %s" % repr(sclt_means.shape))
    if with_y:
        np_translation = np.array([c3d for i in range(scenelets.shape[0])],
                                  dtype=np.float32)
    else:
        np_translation = np.array(
            [c3d[[0, 2]] for i in range(scenelets.shape[0])], dtype=np.float32)
    np_rotation = np.array(
        [np.pi * (i % 2) for i in range(scenelets.shape[0])],
        dtype=np.float32)[:, None]
    n_cands = np_translation.shape[0]
    graph = tf.Graph()
    with graph.as_default(), tf.device('/gpu:0'):
        # 3D translation
        translation_ = tf.Variable(initial_value=np_translation,
                                   name='translation',
                                   dtype=tf.float32)
        t_y = tf.fill(dims=(n_cands, ),
                      value=(tr_ground[1, 3]).astype(np.float32))
        # t_y = tf.fill(dims=(n_cands,), value=np.float32(0.))
        lg.debug("t_y: %s" % t_y)
        if with_y:
            translation = translation_
        else:
            translation = tf.concat(
                (translation_[:, 0:1], t_y[:, None], translation_[:, 1:2]),
                axis=1)

        lg.debug("translation: %s" % translation)
        # 3D rotation (Euler XYZ)
        rotation = tf.Variable(np_rotation, name='rotation', dtype=tf.float32)
        # lg.debug("rotation: %s" % rotation)

        w = tf.Variable(conf_2d, trainable=False, name='w', dtype=tf.float32)

        pos_3d_in = tf.Variable(query,
                                trainable=False,
                                name='pos_3d_in',
                                dtype=tf.float32)
        # pos_3d_in = tf.constant(query, name='pos_3d_in', dtype=tf.float32)

        pos_2d_in = tf.Variable(query_2d,
                                trainable=False,
                                name='pos_2d_in',
                                dtype=tf.float32)
        # pos_2d_in = tf.constant(query_2d, name='pos_2d_in',
        #                         dtype=tf.float32)

        pos_3d_sclt = tf.Variable(scenelets,
                                  trainable=False,
                                  name='pos_3d_sclt',
                                  dtype=tf.float32)
        # print("pos_3d_sclt: %s" % pos_3d_sclt)

        # rotation around y
        my_zeros = tf.zeros((n_cands, 1), dtype=tf.float32, name='my_zeros')
        # tf.add_to_collection('to_init', my_zeros)
        my_ones = tf.ones((n_cands, 1))
        # tf.add_to_collection('to_init', my_ones)
        c = tf.cos(rotation, 'cos')
        # tf.add_to_collection('to_init', c)
        s = tf.sin(rotation, 'sin')
        # t0 = tf.concat([c, my_zeros, -s], axis=1)
        # t1 = tf.concat([my_zeros, my_ones, my_zeros], axis=1)
        # t2 = tf.concat([s, my_zeros, c], axis=1)
        # transform = tf.stack([t0, t1, t2], axis=2, name="transform")
        # print("t: %s" % transform)
        transform = tf.concat(
            [c, my_zeros, -s, my_zeros, my_ones, my_zeros, s, my_zeros, c],
            axis=1)
        transform = tf.reshape(transform, ((-1, 3, 3)), name='transform')
        print("t2: %s" % transform)
        # lg.debug("transform: %s" % transform)

        # transform to 3d
        # pos_3d = tf.matmul(transform, pos_3d_sclt) \
        #          + tf.tile(tf.expand_dims(translation, 2),
        #                    [1, 1, int(pos_3d_in.shape[2])])
        # pos_3d = tf.einsum("bjk,bcjd->bcjd", transform, pos_3d_sclt)
        shp = pos_3d_sclt.get_shape().as_list()
        transform_tiled = tf.tile(transform[:, None, :, :, None],
                                  (1, shp[1], 1, 1, shp[3]))
        # print("transform_tiled: %s" % transform_tiled)
        pos_3d = tf.einsum("abijd,abjd->abid", transform_tiled, pos_3d_sclt)
        # print("pos_3d: %s" % pos_3d)
        pos_3d += translation[:, None, :, None]
        #pos_3d = pos_3d_sclt
        # print("pos_3d: %s" % pos_3d)

        # perspective divide
        # pos_2d = tf.divide(
        #     tf.slice(pos_3d, [0, 0, 0], [n_cands, 2, -1]),
        #     tf.slice(pos_3d, [0, 2, 0], [n_cands, 1, -1]))
        pos_2d = tf.divide(pos_3d[:, :, :2, :], pos_3d[:, :, 2:3, :])

        # print("pos_2d: %s" % pos_2d)

        diff = pos_2d - pos_2d_in
        # mask loss by 2d key-point visibility
        # print("w: %s" % w)
        # w_sum = tf.reduce_sum()
        masked = tf.multiply(diff, w)
        # print(masked)
        # loss_reproj = tf.nn.l2_loss(masked)
        # loss_reproj = tf.reduce_sum(tf.square(masked[:, :, 0, :])
        #                             + tf.square(masked[:, :, 1, :]),
        #                             axis=[1, 2])
        masked_sqr = tf.square(masked[:, :, 0, :]) \
                     + tf.square(masked[:, :, 1, :])
        loss_reproj = tf.reduce_sum(masked_sqr, axis=[1, 2])
        # lg.debug("loss_reproj: %s" % loss_reproj)

        # distance from existing 3D skeletons
        d_3d = q_v_sum_inv * tf.multiply(pos_3d - query[None, ...],
                                         q_v[None, :, None, None],
                                         name='diff_3d')
        # print(d_3d)

        loss_3d = w_3d * tf.reduce_sum(tf.square(d_3d[:, :, 0, :]) + tf.square(
            d_3d[:, :, 1, :]) + tf.square(d_3d[:, :, 2, :]),
                                       axis=[1, 2],
                                       name='loss_3d_each')
        # print(loss_3d)

        loss = tf.reduce_sum(loss_reproj) + tf.reduce_sum(loss_3d)

        # optimize
        optimizer = ScipyOptimizerInterface(loss,
                                            var_list=[translation_, rotation],
                                            options={'gtol': 1e-12})

    with Timer('solve', verbose=True) as t:
        with tf.Session(graph=graph) as session:
            session.run(tf.global_variables_initializer())
            optimizer.minimize(session)
            o_pos_3d, o_pos_2d, o_masked, o_t, o_r, o_w, o_d_3d, \
                o_loss_reproj, o_loss_3d, o_transform, o_translation = \
                session.run([
                    pos_3d, pos_2d, masked, translation, rotation, w,
                    d_3d, loss_reproj, loss_3d, transform, translation])
            o_masked_sqr = session.run(masked_sqr)
        # o_t, o_r = session.run([translation, rotation])
    # print("pos_3d: %s" % o_pos_3d)
    # print("pos_2d: %s" % o_pos_2d)
    # print("o_loss_reproj: %s, o_loss_3d: %s" % (o_loss_reproj, o_loss_3d))
    # print("t: %s" % o_t)
    # print("r: %s" % o_r)
    chosen = sorted((i for i in range(o_loss_reproj.shape[0])),
                    key=lambda i2: o_loss_reproj[i2] + o_loss_3d[i2])
    lg.info("Best candidate is %d with error %g + %g" %
            (chosen[0], o_loss_reproj[chosen[0]], o_loss_3d[chosen[0]]))
    # print("masked: %s" % o_masked)
    # opp = np.zeros_like(o_pos_3d)
    # for i in range(o_pos_3d.shape[0]):
    #     for j in range(o_pos_3d.shape[1]):
    #         for k in range(16):
    #             opp[i, j, :2, k] = o_pos_3d[i, j, :2, k] / o_pos_3d[i, j, 2:3, k]
    #             # opp[i, j, 0, k] *= intr[0, 0]
    #             # opp[i, j, 1, k] *= intr[1, 1]
    #             # opp[i, j, :2, k] *= intr[1, 1]
    #             a = o_pos_2d[i, j, :, k]
    #             b = opp[i, j, :2, k]
    #             if not np.allclose(a, b):
    #                 print("diff: %s, %s" % (a, b))

    o_pos_2d[:, :, 0, :] *= intr[0, 0]
    o_pos_2d[:, :, 1, :] *= intr[1, 1]
    o_pos_2d += intr[:2, 2:3]

    # for cand_id in range(o_pos_2d.shape[0]):
    if False:
        # return
        # print("w: %s" % o_w)
        # print("conf_2d: %s" % conf_2d)
        # lg.debug("query_2d[0, 0, ...]: %s" % query_2d[0, 0, ...])
        query_2d[:, 0, :] *= intr[0, 0]
        query_2d[:, 1, :] *= intr[1, 1]
        # lg.debug("query_2d[0, 0, ...]: %s" % query_2d[0, 0, ...])
        query_2d += intr[:2, 2:3]
        # lg.debug("query_2d[0, 0, ...]: %s" % query_2d[0, 0, ...])

        ims = {}
        for cand_id in chosen[:5]:
            lg.debug("starting %s" % cand_id)
            pos_ = o_pos_2d[cand_id, ...]
            for lin_id in range(pos_.shape[0]):
                frame_id = gap[0] + lin_id
                try:
                    im = ims[frame_id].copy()
                except KeyError:
                    p_im = pjoin(d_query, 'origjpg',
                                 "color_%05d.jpg" % frame_id)
                    ims[frame_id] = cv2.imread(p_im)
                    im = ims[frame_id].copy()
                # im = im_.copy()
                for jid in range(pos_.shape[-1]):

                    xy2 = int(round(query_2d[lin_id, 0, jid])), \
                          int(round(query_2d[lin_id, 1, jid]))
                    # print("printing %s" % repr(xy))
                    cv2.circle(im,
                               center=xy2,
                               radius=5,
                               color=(10., 200., 10.),
                               thickness=-1)

                    if o_masked[cand_id, lin_id, 0, jid] > 0 \
                       or o_w[lin_id, 0, jid] > 0:
                        xy = int(round(pos_[lin_id, 0, jid])), \
                             int(round(pos_[lin_id, 1, jid]))
                        # print("printing %s" % repr(xy))
                        cv2.circle(im,
                                   center=xy,
                                   radius=3,
                                   color=(200., 10., 10.),
                                   thickness=-1)
                        cv2.putText(im,
                                    "d2d: %g" %
                                    o_masked_sqr[cand_id, lin_id, jid],
                                    org=((xy2[0] - xy[0]) // 2 + xy[0],
                                         (xy2[1] - xy[1]) // 2 + xy[1]),
                                    fontFace=1,
                                    fontScale=1,
                                    color=(0., 0., 0.))
                        cv2.line(im, xy, xy2, color=(0., 0., 0.))
                        d3d = o_d_3d[cand_id, lin_id, :, jid]
                        d3d_norm = np.linalg.norm(d3d)
                        if d3d_norm > 0.:
                            cv2.putText(
                                im,
                                "%g" % d3d_norm,
                                org=((xy2[0] - xy[0]) // 2 + xy[0] + 10,
                                     (xy2[1] - xy[1]) // 2 + xy[1]),
                                fontFace=1,
                                fontScale=1,
                                color=(0., 0., 255.))

                cv2.putText(im,
                            text="%d::%02d" % (cand_id, lin_id),
                            org=(40, 80),
                            fontFace=1,
                            fontScale=2,
                            color=(255., 255., 255.))

                # pos_2d_ = np.matmul(intr, pos_[lin_id, :2, :] / pos_[lin_id, 2:3, :])
                # for p2d in pos_2d_
                cv2.imshow('im', im)
                cv2.waitKey()
            break

        while cv2.waitKey() != 27:
            pass

    out_scenelets = []
    for cand_id in chosen[:1]:
        lg.debug("score of %d is %g + %g = %g" %
                 (cand_id, o_loss_reproj[cand_id], o_loss_3d[cand_id],
                  o_loss_reproj[cand_id] + o_loss_3d[cand_id]))
        scenelet = Scenelet()
        rate = query_full.skeleton.get_rate()
        prev_time = None
        for lin_id, frame_id in enumerate(range(gap[0], gap[1] + 1)):
            time_ = query_full.get_time(frame_id)
            if lin_id and rate is None:
                rate = time_ - prev_time
            if time_ == frame_id:
                time_ = prev_time + rate
            scenelet.skeleton.set_pose(frame_id=frame_id,
                                       pose=o_pos_3d[cand_id, lin_id, :, :],
                                       time=time_)
            prev_time = time_
        tr = np.concatenate((np.concatenate(
            (o_transform[cand_id, ...], o_translation[cand_id, None, :].T),
            axis=1), [[0., 0., 0., 1.]]),
                            axis=0)
        tr_m = np.concatenate(
            (np.concatenate((np.identity(3), -sclt_means[cand_id, None, :].T),
                            axis=1), [[0., 0., 0., 1.]]),
            axis=0)
        tr = np.matmul(tr, tr_m)
        for oid, ob in scene.objects.items():
            if ob.label in ('wall', 'floor'):
                continue
            ob2 = copy.deepcopy(ob)
            ob2.apply_transform(tr)
            scenelet.add_object(obj_id=oid, scene_obj=ob2, clone=False)
        scenelet.name_scene = scene.name_scene
        out_scenelets.append((o_loss_reproj[cand_id], scenelet))
    return out_scenelets
Example #10
0
def show_images(images, data, thresh_log_conf=Conf.get().path.thresh_log_conf):
    _confs = []
    for frame_str in sorted(data):
        try:
            frame_id = int(frame_str.split('_')[1])
        except ValueError:
            print("skipping key %s" % frame_id)
            continue
        pose_in = np.asarray(data[frame_str][u'centered_3d'])
        pose_in_2d = np.asarray(data[frame_str][u'pose_2d'])
        visible = np.asarray(data[frame_str][u'visible'])
        vis_f = np.asarray(data[frame_str][u'visible_float'])

        # pose_id = pose_ids[frame_id]
        im = cv2.cvtColor(images[frame_id], cv2.COLOR_RGB2BGR)
        for i in range(pose_in.shape[0]):
            c = (.7, .2, .7, 1.)
            # if i == pose_id:
            #     c = (0., 1., 0., 1.)
            _confs.append(vis_f[i:i+1, :])
            color = tuple(int(c_ * 255) for c_ in c[:3])
            threshed = get_conf_thresholded(vis_f[i:i+1, :], dtype_np=np.float32,
                                            thresh_log_conf=thresh_log_conf)
            lg.debug("avg_vis: %s" % threshed)
            avg_vis = np.count_nonzero(threshed > 0.05, axis=1)
            # if avg_vis > 0.4:
            p2d_mean = np.mean(pose_in_2d[i, :, 1])
            cv2.putText(im, "%.2f" % (avg_vis / threshed.shape[1]),
                        (int(p2d_mean) - 20, 40), 1, 2, thickness=2,
                        color=(200, 200, 200))

            for j in range(pose_in_2d.shape[1]):
                p2d = pose_in_2d[i, j, :]
                conf = get_conf_thresholded(conf=vis_f[i, j],
                                            thresh_log_conf=thresh_log_conf,
                                            dtype_np=np.float32)
                if conf > 0.5:
                    cv2.circle(
                      im, (p2d[1], p2d[0]), radius=3, color=color, thickness=-1)
                    cv2.putText(im, ("%.2f" % conf)[1:],
                                (p2d[1], p2d[0]), 1, 1, color=color,
                                thickness=2)
                # if conf > 0.:
                #     cv2.putText(im, "%.2f" % avg_vis,
                #                 (p2d[1], p2d[0]), 1, 2, color=color)

            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)
        cv2.imshow("im", im)
        cv2.imwrite("/tmp/im_%04d.jpg" % frame_id, im)
        cv2.waitKey(100)
    # _confs = np.array(_confs).flatten()
    # _confs[_confs < 0.] = 0.
    # _confs = np.sort(_confs)
    # tr = 1. / (1. + np.exp(-5000. * _confs + 5))
    # print("here: %g" % np.exp(0.001))
    # plt.figure()
    # # plt.hist(_confs, bins=100)
    # sel = tr > 0.5
    # tr0 = tr[sel]
    # plt.scatter(_confs[sel], tr0, facecolor=None, edgecolor='g')
    # sel1 = tr < 0.5
    # plt.scatter(_confs[sel1], tr[sel1], facecolor=None, edgecolor='r')
    # plt.plot([0., 0.003], [0.5, 0.5], 'k')
    # plt.plot([0.001, 0.001], [0., 1.], 'k')
    # # plt.plot([0, len(_confs)], [np.log10(np.exp(-7.5)),
    # #                             np.log10(np.exp(-7.5))])
    # # plt.plot([0, len(_confs)], [np.exp(0.001) - 1., np.exp(0.001) - 1.])
    # # tr = 1. / (1 + np.log10(_confs))
    # # print("showing %s" % _confs)
    # plt.title('Transformed confidence: 1/(1 + exp(-5000x + 5))')
    # plt.xlim(-0.0001, 0.003)
    # plt.show()
    # plt.close()
    sys.exit(0)
Example #11
0
def main(argv=None):
    np.set_printoptions(suppress=True)
    parser = argparse.ArgumentParser()
    parser.add_argument('d', help="Folder of scene")
    parser.add_argument('-resolution',
                        help='Target resolution for occupancy map',
                        default=0.1)
    parser.add_argument(
        '-thresh-area',
        help='Ratio of occupancy map cell area that has to be occupied '
        'for it to count as occupied',
        default=0.1)
    parser.add_argument('-postfix',
                        type=str,
                        help="Scene postfix for augmentation",
                        default="")
    args = parser.parse_args(argv if argv is not None else sys.argv)
    res_target = args.resolution
    if args.postfix and len(args.postfix) and not args.postfix.startswith('_'):
        args.postfix = "_%s" % args.postfix

    path_parent, name_input = os.path.split(os.path.abspath(args.d))
    lg.warning("name input: %s" % name_input)
    path_for_tf = os.path.abspath(
        os.path.join(path_parent, os.pardir, 'dataset'))
    # if 'video' not in path_parent else os.path.join(path_parent, 'dataset')
    if not os.path.exists(path_for_tf):
        os.makedirs(path_for_tf, mode=0o0775)

    lg.debug("Loading scenelet...")
    path_scenelet = os.path.join(args.d, "skel_%s.json" % name_input)
    scenelet = Scenelet.load(path_scenelet)
    lg.debug("Scenelet: %s" % scenelet)

    path_state_pickle = os.path.join(args.d, "state%s.pickle" % args.postfix)
    if not os.path.exists(path_state_pickle):
        lg.error("Does not exist: %s" % path_state_pickle)
        return False

    # assert os.path.exists(path_state_pickle), \
    #     "Does not exist: %s" % path_state_pickle
    lg.debug("Loading volume...")
    state = pickle_load(open(path_state_pickle, 'rb'))
    lg.debug("Loaded volume...")

    lg.debug("Creating scene from scenelet")
    if not no_vis:
        vis = Visualizer(win_size=(1024, 1024))
        vis.add_coords()
    else:
        vis = None
    # scene = Scene(scenelet.name_scenelet)
    # colors = {0: (200., 0., 0.), 1: (0., 200., 0.), 2: (0., 0., 200.)}
    # unit_x = np.array((1., 0., 0.))

    occup = State(room=state.room,
                  tr_ground_inv=None,
                  res_theta=state.resolution[3],
                  resolution=[res_target, res_target, res_target])
    occup.get_volume(labels_to_lin_ids_arg=state.get_labels_to_lin_ids())
    occup_angle = np.ones(shape=(len(
        occup.volume), occup.volume[0].shape[0], occup.volume[0].shape[1], 1),
                          dtype=np.float32) * -1.
    assert np.min(occup_angle) < 0. and np.max(occup_angle) < 0., "Not empty"

    grid_polys = get_grid_shapely(occup=occup, res_orig=state.resolution)
    occup.volume.flags.writeable = True
    volume_occp = occup.volume
    angles = sorted(state.get_angles())
    labels_to_lin_ids = occup.get_labels_to_lin_ids()
    had_vtk_problem = no_vis

    plt.figure()

    rects = []
    for oid, ob in scenelet.objects.items():
        assert oid >= 0, "Need positive here"
        label = ob.label
        if label in TRANSLATIONS_CATEGORIES:
            label = TRANSLATIONS_CATEGORIES[label]

        if label not in labels_to_lin_ids:
            continue

        try:
            poly = get_poly([part.obb for part in ob.parts.values()])
        except ValueError as e:
            print("\n===========\n\nShapely error: %s for %s\n\n" %
                  (e, (label, oid, ob)))
            with open('error.log', 'a') as f:
                f.write("[%s] %d, %s, %s\n" % (args.d, oid, label, ob))
            continue

        ob_angle = ob.get_angle(positive_only=True)
        assert 0. <= ob_angle <= 2 * np.pi, "No: %g" % ob_angle

        rect = get_rectangle(poly, ob_angle)
        rect.extend([oid, CATEGORIES[label]])
        rects.append(rect)

        cat_id = labels_to_lin_ids[label]  # cat_id in volume, not categories
        for gp in grid_polys:
            # skip, if not occupied enough
            if gp.poly.intersection(poly).area / gp.area < args.thresh_area:
                continue
            # save occupancy
            gp.occupancy = 1.
            id_angle_lower = None
            id_angle_upper = None
            if ob_angle > angles[-1]:
                id_angle_lower = len(angles) - 1
                id_angle_upper = 0
            else:
                for id_angle, angle in enumerate(angles):
                    if ob_angle < angle:
                        id_angle_upper = id_angle
                        id_angle_lower = id_angle - 1
                        break
            assert id_angle_lower is not None \
                   and id_angle_upper is not None, \
                "Wrong?"
            assert id_angle_upper != id_angle_lower, \
                "? %s %s" % (id_angle_lower, id_angle_upper)

            # cache
            xy = gp.xy

            # zero means empty in occupancy,
            # so object ids are shifted with 1
            # we need object ids to filter "untouched" objects
            # in tfrecords_create
            if volume_occp[cat_id, xy[0], xy[1], id_angle_lower] == 0 \
               or label in CATEGORIES_DOMINANT:
                volume_occp[cat_id, xy[0], xy[1], id_angle_lower] = oid + 1
            if volume_occp[cat_id, xy[0], xy[1], id_angle_upper] == 0 \
               or label in CATEGORIES_DOMINANT:
                volume_occp[cat_id, xy[0], xy[1], id_angle_upper] = oid + 1

            # angles are right now not per-category, but per-scene
            # hence, an object can only overwrite, if it's usually "above"
            # other objects, e.g. a table
            # this is a hack for a z-test
            if occup_angle[cat_id, xy[0], xy[1], 0] < 0. \
               or label in CATEGORIES_DOMINANT:
                occup_angle[cat_id, xy[0], xy[1], 0] = ob_angle

        if not had_vtk_problem:
            color = COLORS_CATEGORIES[label] if label in COLORS_CATEGORIES \
                else (200., 200., 200.)
            try:
                for id_part, part in ob.parts.items():
                    vis.add_mesh(MeshOBJ.from_obb(part.obb),
                                 name="ob_%02d_part_%02d" % (oid, id_part),
                                 color=color)
            except AttributeError:
                print("VTK problem...")
                had_vtk_problem = True
    #plt.savefig()
    plt.close()
    if not had_vtk_problem:
        vis.set_camera_pos(pos=(0., -1., 0.))
        vis.camera().SetFocalPoint(0., 0., 0.)
        vis.camera().SetViewUp(-1., 0., 0.)
        vis.set_camera_type(is_ortho=True)
        vis.camera().SetParallelScale(3.)
    # vis.show()

    name_recording = "%s_%s" % (os.path.basename(args.d), args.postfix) \
        if args.postfix else os.path.basename(args.d)
    lg.info("name_recording: %s" % name_recording)

    path_out_occp = os.path.join(os.path.dirname(args.d), os.pardir,
                                 'occupancy', name_recording)
    if not os.path.exists(path_out_occp):
        os.makedirs(path_out_occp)

    # prepare www storage
    www_grid = {'evidence': {}, 'occ': {}}

    # normalize evidence maps
    vmax = 0.
    ims = {}
    for cat, cat_id in labels_to_lin_ids.items():
        ims[cat] = np.squeeze(
            np.sum(state.volume[cat_id, :, :, :], axis=2, keepdims=True))
        vmax = max(vmax, np.max(ims[cat]))

    # gather joined occupancy map
    im_sum = None

    # for each evidence category
    for cat, cat_id in labels_to_lin_ids.items():
        im = ims[cat] / vmax * 255.
        path_out_im = os.path.join(path_out_occp, "e_%s.jpg" % cat)
        cv2.imwrite(path_out_im, im)
        # lg.debug("wrote to %s" % path_out_im)
        www_grid['evidence'][cat] = path_out_im

        im = np.squeeze(volume_occp[cat_id, :, :, 0])
        path_out_im = os.path.join(path_out_occp, "o_%s.jpg" % cat)
        cv2.imwrite(path_out_im, im * 255.)
        # lg.debug("wrote to %s" % path_out_im)
        www_grid['occ'][cat] = path_out_im

        if im_sum is None:
            im_sum = im.copy()
        else:
            im_sum = np.maximum(im, im_sum)

    #
    # save dataset
    #
    name_input_old = name_input
    if args.postfix is not None and len(args.postfix):
        name_input = "%s_%s" % (name_input, args.postfix)

    # state
    path_state_dest = os.path.join(path_for_tf, "state_%s.pickle" % name_input)
    shutil.copyfile(path_state_pickle, path_state_dest)
    lg.info("Copied\n\t%s to\n\t%s" % (path_state_pickle, path_state_dest))

    # occupancy
    path_occup_dest = os.path.join(path_for_tf, "occup_%s.pickle" % name_input)
    pickle.dump(occup, open(path_occup_dest, 'wb'), -1)
    lg.info("Wrote to %s" % path_occup_dest)

    # occupancy_angle
    path_occup_angle_dest = os.path.join(path_for_tf,
                                         "angle_%s.npy" % name_input)
    min_angle = np.min(occup_angle)
    assert min_angle < 0., "No empty cells??"
    lg.debug("min angle is %s" % min_angle)
    np.save(open(path_occup_angle_dest, 'wb'), occup_angle)
    lg.info("Wrote to %s" % path_occup_angle_dest)

    # skeleton
    path_copied = shutil.copy2(path_scenelet, path_for_tf)
    lg.info("Copied\n\t%s to \n\t%s" % (path_scenelet, path_copied))

    # charness skeleton
    name_skeleton_charness = "skel_%s-charness.json" % name_input_old
    path_scenelet_charness = os.path.join(args.d, name_skeleton_charness)
    assert os.path.exists(path_scenelet_charness), \
        "Does not exist: %s" % path_scenelet_charness
    shutil.copy2(path_scenelet_charness, path_for_tf)
    assert os.path.exists(os.path.join(path_for_tf, name_skeleton_charness)), \
        "Does not exist: %s" % os.path.join(path_for_tf,
                                            name_skeleton_charness)

    # rectangles
    name_rectangles = "rectangles_%s.npy" % name_input_old
    path_rectangles = os.path.join(path_for_tf, name_rectangles)
    np.save(open(path_rectangles, 'wb'), rects)

    #
    # visualize
    #

    path_out_im = os.path.join(path_out_occp, '3d.png')
    if not had_vtk_problem:
        vis.save_png(path_out_im)
    www_grid['3d'] = path_out_im

    path_out_im = os.path.join(path_out_occp, 'o_sum.png')
    max_im_sum = np.max(im_sum)
    if max_im_sum > 0.:
        cv2.imwrite(path_out_im, im_sum / max_im_sum * 255.)
    else:
        cv2.imwrite(path_out_im, im_sum * 255.)
    www_grid['o_sum'] = path_out_im

    path_www = os.path.join(path_out_occp, os.pardir)
    with open(os.path.join(path_www, 'index.html'), 'a') as f:
        f.write("<style> img {image-rendering: pixelated; } </style>\n")
        f.write("<script>\n")
        f.write("</script>\n")
        f.write("<h3>%s</h3>" % os.path.basename(args.d))
        f.write('<table>\n')

        f.write("<tr>\n")
        f.write("<th>3d</th>")
        f.write("<th>Occupancy sum</th>")
        for cat in www_grid['evidence']:
            f.write("\t<th>%s</th>\n" % cat)
        f.write("<th></th>\n")  # titles
        f.write("</tr>\n")

        f.write("<tr>\n")
        # 3D
        f.write("\t<td rowspan=\"2\">\n")
        path_im = os.path.relpath(www_grid['3d'], path_www)
        f.write("\t<a href=\"%s\">\n"
                "\t\t<img src=\"%s\" height=\"400\" />\n"
                "\t</a>\n" % (path_im, path_im))

        # Evidence sum
        f.write("\t<td rowspan=\"2\">\n")
        path_im = os.path.relpath(www_grid['o_sum'], path_www)
        f.write("\t<a href=\"%s\">\n"
                "\t\t<img src=\"%s\" height=\"400\" />\n"
                "\t</a>\n" % (path_im, path_im))
        # Evidence
        for cat in www_grid['evidence']:
            f.write("<td style=\"padding-bottom: 2px\">\n")
            path_im = os.path.relpath(www_grid['evidence'][cat], path_www)
            f.write("\t<a href=\"%s\">\n"
                    "\t\t<img src=\"%s\" height=\"200\" />\n"
                    "\t</a>\n" % (path_im, path_im))
            f.write("</td>\n")
        f.write("<td>Evidence</td>\n")

        f.write("\t</td>\n")
        f.write("</tr>\n")

        f.write("<tr>\n")
        for cat in www_grid['occ']:
            f.write("<td>\n")
            path_im = os.path.relpath(www_grid['occ'][cat], path_www)
            f.write("\t<a href=\"%s\">\n"
                    "\t\t<img src=\"%s\" height=\"200\" />\n"
                    "</a>\n" % (path_im, path_im))
            f.write("</td>\n")
        f.write("<td>Occupancy map</td>\n")
        f.write("</tr>")

        f.write('</table>')

    return True
Example #12
0
def show_output(tf_vars, deb_oo, deb_jo, d_query, session, smooth_pairs,
                d_postfix, f_postfix, um):
    colors = stealth_colors
    p_deb = os.path.join(d_query, 'debug_isec' + d_postfix)
    if not os.path.exists(p_deb):
        os.makedirs(p_deb)
    #     os.system("rm %s/*.png" % p_deb)
    #     os.system("rm %s/*.svg" % p_deb)
    # else:

    # assert np.allclose(tf_vars.oo_mask_same.eval(),
    #                    tf_vars.oo_mask_same_2.eval())
    # assert np.allclose(tf_vars.oo_mask_cat.eval(),
    #                    tf_vars.oo_mask_cat_2.eval())
    # assert np.allclose(tf_vars.oo_mask_interacting_2,
    #                    tf_vars._oo_mask_interacting.eval())
    # assert np.isclose(tf_vars._oo_mask_interacting_sum_inv.eval(),
    #                   tf_vars.oo_mask_interacting_sum_inv_2.eval())

    obj_vxs_t = tf_vars.obj_2d_vertices_transformed
    o_obj_vxs_t, o_joints, o_smooth_pairs, distances, o_mgrid_vxs_t = \
        session.run([obj_vxs_t, deb_jo['joints'], smooth_pairs,
                     deb_jo['d'], tf_vars._obj_2d_mgrid_vertices_transformed])
    o_polys, o_poly_indices = session.run(
        [tf_vars.obj_2d_polys, tf_vars._obj_2d_poly_transform_indices])
    o_oo_mask, o_d_oo = session.run([deb_oo['oo_mask'], deb_oo['d_oo']])
    py_cat_ids = np.squeeze(tf_vars.cat_ids_polys.eval(), axis=0)
    lg.debug("distances: %s" % repr(distances.shape))
    lg.debug("obj_vxs_t: %s" % repr(o_obj_vxs_t.shape))
    lg.debug("joints: %s" % repr(o_joints.shape))

    mn1 = np.min(o_obj_vxs_t, axis=0)[[0, 2]]
    mx1 = np.max(o_obj_vxs_t, axis=0)[[0, 2]]
    mn2 = np.min(o_smooth_pairs, axis=0)
    mn2 = np.minimum(mn2[:3], mn2[3:])[[0, 2]]
    mx2 = np.max(o_smooth_pairs, axis=0)
    mx2 = np.maximum(mx2[:3], mx2[3:])[[0, 2]]
    mn = np.minimum(mn1, mn2)
    mx = np.maximum(mx1, mx2)
    assert o_joints.shape[0] // 5 == distances.shape[0]
    o_joints = o_joints.reshape(5, -1, 3)[0, ...]
    assert o_polys.shape[0] == distances.shape[1]

    fig = plt.figure()
    ax0 = fig.add_subplot(111, aspect='equal')
    # for pair in o_smooth_pairs:
    #     ax0.plot([pair[0], pair[3]], [pair[2], pair[5]], 'k--')

    # for id_pnt in range(1, o_joints.shape[0]):
    #     pnt0 = o_joints[id_pnt, :]
    o_joints_ordered = np.asarray([
        e[1]
        for e in sorted([(um.pids_2_scenes[pid].frame_id, o_joints[pid, ...])
                         for pid in range(o_joints.shape[0])],
                        key=lambda e: e[0])
    ])
    assert o_joints_ordered.ndim == 2 and o_joints_ordered.shape[1] == 3
    ax0.plot(o_joints_ordered[:, 0], o_joints_ordered[:, 2], 'kx--')

    for id_poly in range(distances.shape[1]):
        idx_t = o_poly_indices[id_poly, 0]
        color = tuple(c / 255. for c in colors[(idx_t + 1) % len(colors)])
        d_sum = 0.
        # poly = np.concatenate((
        #     o_obj_vxs_t[4*id_poly:4*(id_poly+1), :],
        #     o_obj_vxs_t[4*id_poly:4*id_poly+1, :]))

        # ax0.plot(o_polys[id_poly, :, 0], o_polys[id_poly, :, 2], color=color)
        shapely_poly = geom.asPolygon(o_polys[id_poly, :, [0, 2]].T)
        patch = PolygonPatch(shapely_poly,
                             facecolor=color,
                             edgecolor=color,
                             alpha=0.25)
        ax0.add_artist(patch)
        cat = next(cat for cat in CATEGORIES
                   if CATEGORIES[cat] == py_cat_ids[id_poly])
        xy = (shapely_poly.centroid.xy[0][0] - 0.1,
              shapely_poly.centroid.xy[1][0])
        ax0.annotate(cat, xy=xy, color=color, fontsize=6)
        for id_pnt in range(distances.shape[0]):
            d_ = distances[id_pnt, id_poly]
            if d_ < 0.:
                pnt = o_joints[id_pnt, :]
                ax0.scatter(pnt[0],
                            pnt[2],
                            s=(5 * (1 + d_))**2,
                            color=color,
                            zorder=5)
                d_sum += distances[id_pnt, id_poly]
                ax0.annotate("%.2f" % d_,
                             xy=(np.random.rand() * 0.1 + pnt[0] - 0.05,
                                 np.random.rand() * 0.1 + pnt[2] - 0.05),
                             fontsize=4)

        for id_pnt in range(o_d_oo.shape[0]):
            d_ = o_d_oo[id_pnt, id_poly]
            if d_ < 0.:
                pnt = o_mgrid_vxs_t[id_pnt, :]
                ax0.scatter(pnt[0],
                            pnt[2],
                            s=(7 * (1 + d_))**2,
                            edgecolor=color,
                            zorder=5,
                            color=(1., 1., 1., 0.))
                ax0.annotate("%.2f" % d_,
                             xy=(np.random.rand() * 0.1 + pnt[0] - 0.05,
                                 np.random.rand() * 0.1 + pnt[2] - 0.05),
                             fontsize=8,
                             color='r',
                             zorder=6)

    # fig.suptitle("d_sum: %s" % d_sum)
    p_out = os.path.join(p_deb, "op_%s.png" % f_postfix)
    plt.draw()
    ax0.set_xlim(mn[0] - 0.2, mx[0] + 0.2)
    ax0.set_ylim(mn[1] - 0.2, mx[1] + 0.2)
    # plt.show()

    try:
        fig.savefig(p_out, dpi=300)
        lg.debug("saved to %s" % p_out)
    except PermissionError as e:
        lg.error("Could not save %s" % e)

    plt.close(fig)
Example #13
0
def _load_chunk(path_file):
    lg.debug("Opening %s" % path_file)
    with open(path_file, 'rb') as fil:
        return pickle.load(fil)
Example #14
0
def main(argv):
    pjoin = os.path.join  # cache long name
    parser = argparse.ArgumentParser(
        "Find characteristic scene times",
        description="Scans a directory of short scenelets (exported from "
        "Matlab), and looks up their full version in the original "
        "scenes. It exports a new scenelet containing all poses "
        "between the start and end times of the input short "
        "scenelets. Matching is done by name."
        "Scenelets below time length limit and not enough objects "
        "are thrown away."
        "It also saves the scenelet characteristicness into the "
        "output scenelet files.")
    parser.add_argument(
        'd',
        type=argparse_check_exists,
        help="Folder containing PiGraphs scenelets. E.g. "
        "/mnt/thorin_data/stealth/shared/"
        "pigraph_scenelets__linterval_squarehist_large_radiusx2")
    parser.add_argument('s',
                        type=argparse_check_exists,
                        help="Folder containing PiGraphs full scenes. E.g. "
                        "/mnt/thorin_data/stealth/shared/scenes_pigraphs")
    parser.add_argument('-l',
                        '--limit-len',
                        type=int,
                        help="Minimum length for a scenelet",
                        default=10)  # changed from `5` on 15/1/2018
    parser.add_argument(
        '--dist-thresh',
        type=float,
        help='Distance threshold for object pruning. Typically: 0.2 or 0.5.',
        default=.5)
    # parse arguments
    args = parser.parse_args(argv)
    parts_to_remove = ['sidetable']
    lg.warning("Will remove all parts named %s" % parts_to_remove)

    # read scenes and scenelets
    p_pickle = pjoin(args.d, 'scenes_and_scenelets.pickle')
    if os.path.exists(p_pickle):
        lg.info("reading from %s" % p_pickle)
        scenes, scenelets = pickle_load(open(p_pickle, 'rb'))
        lg.info("read from %s" % p_pickle)
    else:
        scenelets = read_scenelets(args.d)
        scenes = read_scenelets(args.s)
        scenes = {scene.name_scene: scene for scene in scenes}
        pickle.dump((scenes, scenelets), open(p_pickle, 'wb'), protocol=-1)
        lg.info("wrote to %s" % p_pickle)

    # Read characteristicnesses (to put them into the scenelet).
    p_charness = pjoin(args.d, "charness__gaussian.mat")
    pose_charness, scenelet_names = read_charness(p_charness,
                                                  return_hists=False,
                                                  return_names=True)

    # output folder
    d_scenelets_parent = os.path.dirname(args.d)
    d_dest = pjoin(d_scenelets_parent, 'deb',
                   "%s_full_sampling" % args.d.split(os.sep)[-1])
    # makedirs_backed
    if os.path.exists(d_dest):
        i = 0
        while i < 100:
            try:
                os.rename(d_dest, "%s.bak.%02d" % (d_dest, i))
                break
            except OSError:
                i += 1
    os.makedirs(d_dest)

    # _is_close = is_close  # cache namespace lookup
    # processing
    for sclt in scenelets:
        # cache skeleton
        skeleton = sclt.skeleton

        if 'scene09' in sclt.name_scenelet or 'scene10' in sclt.name_scenelet:
            lg.debug("here")
        else:
            continue

        # prune objects
        per_cat = {}
        cnt = 0
        for oid, scene_obj in sclt.objects.items():
            close_, dist = is_close(scene_obj,
                                    skeleton,
                                    args.dist_thresh,
                                    return_dist=True)
            label = scene_obj.label
            if 'chair' in label or 'couch' in label or 'stool' in label:
                label = 'sittable'

            try:
                per_cat[label].append((dist, oid))
            except KeyError:
                per_cat[label] = [(dist, oid)]
            if scene_obj.label != 'floor':
                cnt += 1

        per_cat = {k: sorted(v) for k, v in per_cat.items()}

        name_scene = sclt.name_scene.split('__')[0]
        if '-no-coffeetable' in name_scene:
            name_scene = name_scene[:name_scene.find('-no-coffeetable')]
        scene = scenes[name_scene]

        if 'shelf' not in per_cat:
            for oid, ob in scene.objects.items():
                if ob.label == 'shelf':
                    close_, dist = is_close(ob,
                                            skeleton,
                                            args.dist_thresh,
                                            return_dist=True)
                    oid_ = oid
                    while oid_ in sclt.objects:
                        oid_ += 1
                    sclt.add_object(oid_, ob)
                    cnt += 1
                    try:
                        per_cat['shelf'].append((dist, oid_))
                    except KeyError:
                        per_cat['shelf'] = [(dist, oid_)]

        if 'shelf' in per_cat:
            assert len(per_cat['shelf']) == 1, "TODO: keep all shelves"

        oids_to_keep = [
            v[0][1] for v in per_cat.values() if v[0][0] < args.dist_thresh
        ]

        if not len(oids_to_keep):  # there is always a floor
            lg.warning("Skipping %s, not enough objects: %s" %
                       (sclt.name_scenelet, per_cat))
            continue

        # if 'gates392_mati3_2014-04-30-21-13-46__scenelet_25' \
        #     == sclt.name_scenelet:
        #     lg.debug("here")
        # else:
        #     continue

        # copy skeleton with dense sampling in time
        mn, mx = skeleton.get_frames_min_max()
        # assert mn == 0, "This usually starts indexing from 0, " \
        #                 "no explicit problem, just flagging the change."
        time_mn = floor(skeleton.get_time(mn))
        time_mx = ceil(skeleton.get_time(mx))

        # artificially prolong mocap scenes
        if 'scene' in name_scene and (time_mx - time_mn < 60):
            d = (time_mx - time_mn) // 2 + 1
            time_mn -= d
            time_mx += d
        # lookup original scene name
        # mn_frame_id_scene, mx_frame_id_scene = \
        #     scene.skeleton.get_frames_min_max()

        frame_ids_old = skeleton.get_frames()
        times_old = [skeleton.get_time(fid) for fid in frame_ids_old]
        for frame_id in frame_ids_old:
            skeleton.remove_pose(frame_id)

        for frame_id in range(time_mn, time_mx + 1):
            if not scene.skeleton.has_pose(frame_id):
                continue
            pose = scene.skeleton.get_pose(frame_id=frame_id)
            # scale mocap skeletons
            fw = scene.skeleton.get_forward(frame_id=frame_id,
                                            estimate_ok=False)
            sclt.set_pose(frame_id=frame_id,
                          angles=None,
                          pose=pose,
                          forward=fw,
                          clone_forward=True)

        if 'scene0' in name_scene or 'scene10' in name_scene:
            mx_old = np.max(sclt.skeleton.poses[:, 1, :])
            sclt.skeleton.poses *= 0.8
            mx_new = np.max(sclt.skeleton.poses[:, 1, :])
            sclt.skeleton.poses[1, :] += mx_new - mx_old + 0.05
        _frames = sclt.skeleton.get_frames()

        # check length
        if len(_frames) < args.limit_len:
            lg.warning("Skipping %s, because not enough frames: %s" %
                       (sclt.name_scene, _frames))
            continue

        # save charness
        try:
            id_charness = next(i for i in range(len(scenelet_names))
                               if scenelet_names[i] == sclt.name_scenelet)
            sclt.charness = pose_charness[id_charness]
        except StopIteration:
            lg.error("Something is wrong, can't find %s, %s in charness db "
                     "containing names such as %s." %
                     (sclt.name_scene, sclt.name_scenelet, scenelet_names[0]))
            sclt.charness = 0.4111111

        _mn, _mx = (_frames[0], _frames[-1])
        assert _mn >= time_mn, "not inside? %s < %s" % (_mn, time_mn)
        assert _mx <= time_mx, "not inside? %s < %s" % (_mx, time_mx)
        if len(_frames) < len(frame_ids_old):
            lg.warning("Not more frames than interpolated "
                       "scenelet?\n%s\n%s\n%s" %
                       (_frames, frame_ids_old, times_old))

        oids = list(sclt.objects.keys())
        for oid in oids:
            if oid not in oids_to_keep:
                lg.debug("removed %s" % sclt.objects[oid])
                sclt.objects.pop(oid)
            else:
                obj = sclt.objects[oid]
                part_ids_to_remove = [
                    part_id for part_id, part in obj.parts.items()
                    if part.label in parts_to_remove
                ]
                if len(part_ids_to_remove) == len(obj.parts):
                    sclt.objects.pop(oid)
                else:
                    for part_id in part_ids_to_remove:
                        lg.debug("removed %s" %
                                 sclt.objects[obj].parts[part_id])
                        obj.parts.pop(part_id)
        if len(sclt.objects) < 2 and next(iter(
                sclt.objects.values())).label == 'floor':
            lg.debug("finally removing scenelet: %s" % sclt.objects)
            continue

        # save in the scene folder
        d_dest_scene = pjoin(d_dest, name_scene)
        if not os.path.exists(d_dest_scene):
            os.makedirs(d_dest_scene)
        sclt.save(pjoin(d_dest_scene, "skel_%s" % sclt.name_scenelet))
Example #15
0
def identify_actors(data):
    m = Model('Stealth actors')

    problem = ActorProblem()

    objective = None
    prev_pose_in_2d = None
    prev_frame_id = None
    for frame_str in sorted(data):
        try:
            frame_id = int(frame_str.split('_')[1])
        except ValueError:
            print("skipping key %s" % frame_id)
            continue

        pose_in = np.array(data[frame_str][u'centered_3d'])
        pose_in_2d = np.array(data[frame_str][u'pose_2d'])
        visible = np.array(data[frame_str][u'visible'])
        assert pose_in_2d.ndim == 3, "no: %s" % repr(pose_in_2d.shape)

        problem.add_frame(frame_id, pose_in_2d.shape[0])

        if prev_pose_in_2d is not None:
            for prev_pose_id in range(prev_pose_in_2d.shape[0]):
                prev_pose = prev_pose_in_2d[prev_pose_id, :, :]
                for pose_id in range(pose_in_2d.shape[0]):
                    pose = pose_in_2d[pose_id, :, :]
                    dist = prev_pose - pose
                    lg.debug("dist: %s" % repr(dist.shape))
                    cost = np.sum(np.linalg.norm(dist, axis=1), axis=0)
                    lg.debug("cost: %s" % cost)
                    problem.add_cost(prev_frame_id, prev_pose_id, frame_id, pose_id, cost)

        prev_pose_in_2d = pose_in_2d
        prev_frame_id = frame_id

    gb_vars = m.addVars(problem.get_n_vars(), vtype=GRB.BINARY)

    for (lin_id0, lin_id1), cost in problem._pw.items():
        # lin_id0 = problem.get_lin_id(prev_frame_id, prev_pose_id)
        # lin_id1 = problem.get_lin_id(frame_id, pose_id)
        objective += gb_vars[lin_id0] * gb_vars[lin_id1] * cost

    for frame_id, lin_ids in problem._constr.items():
        constr = None
        for lin_id in lin_ids:
            if constr is None:
                constr = gb_vars[lin_id]
            else:
                constr += gb_vars[lin_id]
        m.addConstr(constr == 1)

    m.setObjective(objective, GRB.MINIMIZE)
    # m.solver.callSolver(m)
    m.optimize()

    pose_ids = dict()
    for lin_id, v in enumerate(m.getVars()):
        print(v.varName, v.x)
        if v.x > 0.5:
            frame_id, pose_id = problem.get_frame_id_pose_id(lin_id)
            assert frame_id not in pose_ids, "no"
            pose_ids[frame_id] = pose_id

    # if we have more, pick the first...
    # if len(pose_in.shape) > 2:
    #     pose_in = pose_in[0, :, :]
    #     pose_in_2d = pose_in_2d[0, :, :]
    #     visible = visible[0]

    return pose_ids
Example #16
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 #17
0
def filter_outliers(skel_ours_2d, winsorize_limit=0.05, show=False):
    lg.debug('[filter_outliers] Filtering based on 2D displacement...')
    seq = skel_ours_2d.poses[:, :2, :]
    displ = seq[1:, :, :] - seq[:-1, :, :]
    frames = np.array(skel_ours_2d.get_frames_mod())
    assert displ.shape[0] == seq.shape[0] - 1 \
        and displ.shape[1] == seq.shape[1] \
        and displ.shape[2] == seq.shape[2], \
        "No: %s" % displ.shape
    displ = np.linalg.norm(displ, axis=1)
    assert displ.shape == (seq.shape[0] - 1, seq.shape[2]), \
        "No: %s" % repr(displ.shape)

    if show:
        plt.figure()
    # Ensure we only filter consequtive frames
    dtime = frames[1:] - frames[:-1]
    # lg.debug("delta time: %s" % dtime)

    out = scipy.stats.mstats.winsorize(displ, limits=winsorize_limit)
    # diff = np.linalg.norm(out - displ, axis=1)
    diff = out - displ
    fraction_corrected = np.sum((diff < -1.).astype('i4'), axis=1) \
                         / float(diff.shape[1])
    # print("diff: %s" % diff)

    # threshold changed from 5. to 0.6 on 19/1/2018
    # threshold changed from 0.6 to 0.5 on 20/1/2018
    lin_ids_to_remove = np.argwhere(fraction_corrected > 0.6)
    frame_ids_to_remove = \
        [skel_ours_2d.get_frame_id_for_lin_id(lin_id)
         for lin_id in np.squeeze(lin_ids_to_remove, axis=1).tolist()
         if dtime[lin_id] == 1
         and (lin_id+1 >= dtime.size or dtime[lin_id+1] == 1)]
    cpy = copy.deepcopy(skel_ours_2d)
    for frame_id in frame_ids_to_remove:
        lg.debug("Removing frame_id %d because it jumped in 2D." % frame_id)
        skel_ours_2d.remove_pose(frame_id)
        for frame_id_ in skel_ours_2d._frame_ids.keys():
            if frame_id_ != frame_id:
                assert np.allclose(skel_ours_2d.get_pose(frame_id_),
                                   cpy.get_pose(frame_id_)), \
                    "No (frame_id: %d, lin_id: %d, old lin_id: %d)\nnew: %s\nold:\n%s" \
                    % (frame_id_, skel_ours_2d.get_lin_id_for_frame_id(frame_id_),
                       cpy.get_lin_id_for_frame_id(frame_id_),
                       skel_ours_2d.get_pose(frame_id_),
                       cpy.get_pose(frame_id_)
                       )

    # mask = np.where(diff < 10., True, False)
    # if mask[-1]:
    #     mask = np.append(mask, mask[-1])
    # else:
    #     mask = np.insert(mask, 0, mask[0])
    # print(mask)
    # skel_ours_2d._poses = skel_ours_2d._poses[mask, :, :]
    # assert list(skel_ours_2d._frame_ids.values()) == sorted(list(skel_ours_2d._frame_ids.values())), \
    #     "Not sorted: %s" % list(skel_ours_2d._frame_ids.values())
    # skel_ours_2d._frame_ids = dict((k, v) for i, (k, v) in enumerate(skel_ours_2d._frame_ids.items()) if mask[i])
    # assert list(skel_ours_2d._frame_ids.values()) == sorted(list(skel_ours_2d._frame_ids.values())), \
    #     "Not sorted: %s" % list(skel_ours_2d._frame_ids.values())
    if show:
        plt.plot(diff, 'k')
        plt.plot(displ[:, 6], 'g')
        plt.plot(out[:, 6], 'b')
        plt.show()
    return skel_ours_2d, frame_ids_to_remove