def geo_rescore(pid, model, method):
    """Apply geographic rescoring."""

    logging.info(str((pid, model, method)))
    session = SESSION()
    try:
        numpy.seterr(all='raise')

        session.query(Model) \
            .filter_by(filename=model) \
            .one()

        nms_method = scores.METHODS[method]

        # pylint: disable-msg=E1101
        detections = session.query(Detection) \
            .join(Model) \
            .filter(Detection.pid == pid) \
            .filter(Model.filename == model) \
            .filter(or_(*[m == None for m in nms_method.inputs]))
        # pylint: enable-msg=E1101

        nms_method = scores.METHODS[method]

        for method_input in nms_method.inputs:
            score_name = str(method_input).split('.')[-1]
            score = scores.SCORES[score_name]

            if score.compute is None:
                continue

            for detection in detections:
                value = score.compute(session, detection)

                existing = getattr(detection, score_name)

                if existing is not None:
                    if not math.fabs(existing - value) < 1e-8:
                        assert False

                setattr(detection, score_name, value)

        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
    return pid
def geo_rescore(pid, model, method):
    """Apply geographic rescoring."""

    logging.info(str((pid, model, method)))
    session = SESSION()
    try:
        numpy.seterr(all='raise')

        session.query(Model) \
            .filter_by(filename=model) \
            .one()

        nms_method = scores.METHODS[method]

        # pylint: disable-msg=E1101
        detections = session.query(Detection) \
            .join(Model) \
            .filter(Detection.pid == pid) \
            .filter(Model.filename == model) \
            .filter(or_(*[m == None for m in nms_method.inputs]))
        # pylint: enable-msg=E1101

        nms_method = scores.METHODS[method]

        for method_input in nms_method.inputs:
            score_name = str(method_input).split('.')[-1]
            score = scores.SCORES[score_name]

            if score.compute is None:
                continue

            for detection in detections:
                value = score.compute(session, detection)

                existing = getattr(detection, score_name)

                if existing is not None:
                    if not math.fabs(existing - value) < 1e-8:
                        assert False

                setattr(detection, score_name, value)

        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
    return pid
Exemple #3
0
def test(model, remote, methods, dataset_id):
    """Executes the testing protocol."""

    session = SESSION()
    try:
        test_set = session.query(Photo) \
            .filter_by(test=True, dataset_id=dataset_id)

        session.query(Model) \
            .filter_by(filename=model) \
            .one()

        for photo in test_set:
            logging.info(photo.id)

            celery_list = [detect.s(photo.id, model)]

            for method in methods:
                celery_list += [geo_rescore.s(model, method)]

            for method in methods:
                celery_list += [nms.s(model, method)]

            celery_task = celery.chain(celery_list)

            if remote:
                celery_task.apply_async()
            else:
                celery_task.apply()

    except:
        session.rollback()
        raise

    finally:
        session.close()
Exemple #4
0
def test(model, remote, methods, dataset_id):
    """Executes the testing protocol."""

    session = SESSION()
    try:
        test_set = session.query(Photo) \
            .filter_by(test=True, dataset_id=dataset_id)

        session.query(Model) \
            .filter_by(filename=model) \
            .one()

        for photo in test_set:
            logging.info(photo.id)

            celery_list = [detect.s(photo.id, model)]

            for method in methods:
                celery_list += [geo_rescore.s(model, method)]

            for method in methods:
                celery_list += [nms.s(model, method)]

            celery_task = celery.chain(celery_list)

            if remote:
                celery_task.apply_async()
            else:
                celery_task.apply()

    except:
        session.rollback()
        raise

    finally:
        session.close()
Exemple #5
0
def nms(pid, model, method):
    """Preforms NMS on detections."""

    session = SESSION()

    logging.info((pid, model, method))

    try:

        scoring_method = scores.METHODS[method]

        set_nms = str(scoring_method.output).split('.')[-1]

        # pylint: disable-msg=E1101
        mid, = session.query(Model.id) \
            .filter_by(filename=model) \
            .one()

        todo, = session.query(func.count(Detection.id)) \
            .filter(Detection.pid == pid) \
            .filter(or_(*[m == None for m in scoring_method.inputs])) \
            .filter(Detection.mid == mid) \
            .one()
        # pylint: enable-msg=E1101

        if todo > 0:
            raise Exception('Some input was not yet computed')

        while True:
            # pylint: disable-msg=E1101
            result = session.query(Detection) \
                .filter(Detection.pid == pid) \
                .filter(scoring_method.output == None) \
                .filter(Detection.mid == mid)
            # pylint: enable-msg=E1101

            result = result \
                .order_by(desc(scoring_method.score)) \
                .first()

            if result is None:
                break

            setattr(result, set_nms, True)

            overlap = query_utils.overlap(result, Detection)
            covered = overlap > 0.3

            # pylint: disable-msg=E1101
            blacklist = session.query(Detection) \
                .filter(Detection.pid == pid) \
                .filter(scoring_method.output == None) \
                .filter(Detection.mid == mid) \
                .filter(covered)
            # pylint: enable-msg=E1101

            for elt in blacklist:
                setattr(elt, set_nms, False)

        session.commit()

        return pid
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
Exemple #6
0
def detect(pid, model_filename):
    """Runs DPM and computes 3D pose."""

    logger = logging.getLogger('detect')
    logger.info((pid, model_filename))

    session = SESSION()
    try:
        # pylint: disable-msg=E1101
        num_detections, = session.query(func.count(Detection.id)) \
            .join(Model) \
            .filter(Detection.pid == pid) \
            .filter(Model.filename == model_filename) \
            .one()

        if num_detections > 0:
            logger.info('Already computed')
            return pid

        model = session.query(Model) \
            .filter_by(filename=model_filename) \
            .one()

        photo = session.query(Photo) \
            .options(joinedload('dataset')) \
            .filter_by(id=pid) \
            .one()

        vehicle_types = session.query(VehicleType) \
            .filter(VehicleType.id.in_([202, 8, 150, 63, 123, 16]))

        pydro_model = pydro.io.LoadModel(model.filename)
        image = scipy.misc.imread(
            os.path.join(IMAGE_DIR, photo.filename))
        pyramid = pydro.features.BuildPyramid(image, model=pydro_model)
        filtered_model = pydro_model.Filter(pyramid)
        parse_trees = list(filtered_model.Parse(model.thresh))

        # make sure we use at least one entry so we know we tried
        if len(parse_trees) == 0:
            parse_trees = list(
                itertools.islice(filtered_model.Parse(-numpy.inf), 1))

        assert len(parse_trees) > 0

        bbox_tuple = namedtuple('bbox_tuple', 'x1,x2,y1,y2')

        for tree in parse_trees:
            bbox = bbox_tuple(
                x1=tree.x1 / image.shape[1],
                x2=tree.x2 / image.shape[1],
                y1=tree.y1 / image.shape[0],
                y2=tree.y2 / image.shape[0],
            )
            score = tree.s
            angle = tree.child.rule.metadata.get('angle', None)

            if bbox.x1 > bbox.x2 or bbox.y1 > bbox.y2:
                continue

            car_pose_generator = compute_car_pose(
                photo,
                bbox,
                angle,
                vehicle_types
            )

            for lla, geom, vehicle_type, world_angle in car_pose_generator:
                det = Detection(
                    photo=photo,
                    x1=float(bbox.x1),
                    y1=float(bbox.y1),
                    x2=float(bbox.x2),
                    y2=float(bbox.y2),
                    score=float(score),
                    prob=float(
                        1.0 / (1.0 + math.exp(model.a * score + model.b))),
                    model=model,
                    angle=angle,
                    lla=lla,
                    geom=geom,
                    world_angle=float(world_angle),
                    vehicle_type=vehicle_type,
                )
                session.add(det)

        session.commit()

        return pid

    except Exception:
        session.rollback()
        raise

    finally:
        session.close()
def select_evaluation():
    """Selects the vehicles that will appear in NYC3DCars."""

    nyc3dcars_session = SESSION()
    labeler_session = labeler.SESSION()

    try:
        # Reset photos
        photos = nyc3dcars_session.query(Photo) \
            .options(joinedload('dataset'))

        for photo in photos:
            photo.daynight = None

        # Reset vehicles
        vehicles = nyc3dcars_session.query(Vehicle)
        for vehicle in vehicles:
            nyc3dcars_session.delete(vehicle)

        # Turn photos back on if they have at least 1 final revision
        # pylint: disable-msg=E1101
        photos = labeler_session.query(labeler.Photo) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .options(joinedload('daynights')) \
            .options(joinedload('annotations.flags')) \
            .options(joinedload('annotations')) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.User.trust == True) \
            .distinct()
        # pylint: enable-msg=E1101

        photos = list(photos)

        num_photos = len(photos)

        num_test = 0
        num_train = 0
        num_flagged = 0

        print('Checking for new photos')
        for labeler_photo in photos:
            # Do not consider photos that have been flagged
            num_flags = sum(
                len(annotation.flags)
                for annotation in labeler_photo.annotations
                if annotation.user.trust
            )
            if num_flags > 0:
                num_flagged += 1
                continue

            days = 0
            nights = 0

            for daynight in labeler_photo.daynights:
                if not daynight.user.trust:
                    continue
                if daynight.daynight == 'day':
                    days += 1
                else:
                    nights += 1
            if days + nights == 0:
                print('Need Day/Night for photo: %d' % labeler_photo.id)
                continue

            nyc3dcars_photo = nyc3dcars_session.query(Photo) \
                .filter_by(id=labeler_photo.id) \
                .one()

            if nyc3dcars_photo.test == True:
                num_test += 1
            elif nyc3dcars_photo.test == False:
                num_train += 1
            else:
                if num_train > num_test:
                    print('Test: %d' % labeler_photo.id)
                    nyc3dcars_photo.test = True
                    num_test += 1
                else:
                    print('Train: %d' % labeler_photo.id)
                    nyc3dcars_photo.test = False
                    num_train += 1

            if days > nights:
                nyc3dcars_photo.daynight = 'day'
            else:
                nyc3dcars_photo.daynight = 'night'
        print('New photos done')
        print('%d photos' % num_photos)
        print('%d flagged' % num_flagged)
        print('%d test' % num_test)
        print('%d train' % num_train)

        # pylint: disable-msg=E1101
        good_pids = nyc3dcars_session.query(Photo.id) \
            .filter(Photo.test != None) \
            .all()
        # pylint: enable-msg=E1101

        # get photos with 1 and 2 users
        # pylint: disable-msg=E1101
        photos_one_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) == 1)

        photos_two_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) == 2)

        photos_more_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) > 2)
        for photo in photos_more_user:
            print(photo.id)

        for photo, in photos_one_user:
            vehicles = labeler_session.query(labeler.Vehicle) \
                .select_from(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .options(joinedload('revision')) \
                .options(joinedload('revision.annotation')) \
                .options(joinedload('revision.annotation.user')) \
                .options(joinedload('occlusionrankings')) \
                .options(joinedload('occlusionrankings.occlusion_session')) \
                .options(joinedload('bbox_sessions')) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Annotation.pid == photo) \
                .filter(labeler.Revision.final == True) \
                .distinct()

            for vehicle in vehicles:
                convert_vehicle(nyc3dcars_session, vehicle)

        # get good vehicles for 2 user case
        for photo, in photos_two_user:
            annotations = labeler_session.query(labeler.Annotation) \
                .join(labeler.User) \
                .join(labeler.Revision) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Annotation.pid == photo) \
                .filter(labeler.Revision.final == True) \
                .all()
            assert len(annotations) == 2

            vehicles1 = labeler_session.query(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Revision.aid == annotations[0].id) \
                .filter(labeler.Revision.final == True) \
                .all()

            vehicles2 = labeler_session.query(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Revision.aid == annotations[1].id) \
                .filter(labeler.Revision.final == True) \
                .all()

            if len(vehicles1) > len(vehicles2):
                vehicles = vehicles1
            else:
                vehicles = vehicles2

            for vehicle in vehicles:
                print(vehicle.id)
                convert_vehicle(nyc3dcars_session, vehicle)

        num_vehicles, = nyc3dcars_session.query(
            func.count(Vehicle.id)) \
            .one()

        photo_test, = nyc3dcars_session.query(
            func.count(Photo.id)) \
            .filter(Photo.test == True) \
            .one()

        photo_train, = nyc3dcars_session.query(
            func.count(Photo.id)) \
            .filter(Photo.test == False) \
            .one()
        # pylint: enable-msg=E1101

        print('%d vehicles in dataset' % num_vehicles)
        print('%d images for training' % photo_train)
        print('%d images for testing' % photo_test)

        nyc3dcars_session.commit()
    except:
        nyc3dcars_session.rollback()
        labeler_session.rollback()
        raise
    finally:
        nyc3dcars_session.close()
        labeler_session.close()
def gen_results(model, methods, aos, dataset_id):
    """Computes PR curve and optionally OS-R curve."""

    session = SESSION()
    try:

        difficulties = {'full': []}

        daynights = {
            'both': [],
        }

        # pylint: disable-msg=E1101
        model_id, = session.query(Model.id) \
            .filter(Model.filename == model) \
            .one()

        todo, = session.query(func.count(Photo.id)) \
            .outerjoin((
                Detection,
                and_(
                    Detection.pid == Photo.id,
                    Detection.mid == model_id
                )
            )) \
            .filter(Photo.test == True) \
            .filter(Detection.id == None) \
            .filter(Photo.dataset_id == dataset_id) \
            .one()
        # pylint: enable-msg=E1101

        if todo > 0:
            msg = '%s is not ready. %d photos remaining' % (model, todo)
            logging.info(msg)
            return

        not_ready = False

        for name in methods:
            nms_method = scores.METHODS[name]
            # pylint: disable-msg=E1101
            todo, = session.query(func.count(Detection.id)) \
                .join(Model) \
                .join(Photo) \
                .filter(Photo.test == True) \
                .filter(Model.filename == model) \
                .filter(Photo.dataset_id == dataset_id) \
                .filter(nms_method.output == None) \
                .one()
            # pylint: enable-msg=E1101
            if todo > 0:
                msg = '%s is not ready.  %d %s NMS remaining' % (model, todo,
                                                                 name)
                logging.info(msg)
                not_ready = True

        if not_ready:
            return

        # pylint: disable-msg=E1101
        dataset_id = [Photo.dataset_id == dataset_id]
        # pylint: enable-msg=E1101

        for daynight, difficulty in itertools.product(daynights, difficulties):
            for method in methods:
                nms_method = scores.METHODS[method]
                selected = [nms_method.output == True]
                msg = '%s daynight: %s, difficulty: %s, method: %s' % (
                    model, daynight, difficulty, method)
                logging.info(msg)
                points = precision_recall(
                    session, nms_method.score,
                    dataset_id + daynights[daynight] + selected, dataset_id +
                    daynights[daynight] + difficulties[difficulty], model)
                name = '%s, %s' % (model, method)
                if aos:
                    points_aos = orientation_similarity(
                        session, nms_method.score,
                        dataset_id + daynights[daynight] + selected,
                        dataset_id + daynights[daynight] +
                        difficulties[difficulty], model)
                else:
                    points_aos = None

                print(points.shape)
                print(scipy.integrate.trapz(points[:, 0], points[:, 1]))
                filename = '%s-%s-%s-%s-pr.txt' % (model, daynight, difficulty,
                                                   method)
                print(filename)
                numpy.savetxt(filename, points)
                if points_aos is not None:
                    print(
                        scipy.integrate.trapz(points_aos[:, 0], points_aos[:,
                                                                           1]))
                    filename = '%s-%s-%s-%s-aos.txt' % (model, daynight,
                                                        difficulty, method)
                    print(filename)
                    numpy.savetxt(filename, points_aos)

        logging.info('done')

    except:
        raise
    finally:
        session.close()
def gen_dist_error(model, methods, dataset_id):
    """Generates the horizontal and vertical 3D error statistics."""

    session = SESSION()
    try:
        # pylint: disable-msg=E1101
        model_id, = session.query(Model.id) \
            .filter_by(filename=model) \
            .one()

        todo, = session.query(func.count(Photo.id)) \
            .outerjoin((
                Detection,
                and_(
                    Detection.pid == Photo.id,
                    Detection.mid == model_id
                )
            )) \
            .filter(Photo.test == True) \
            .filter(Detection.id == None) \
            .filter(Photo.dataset_id == dataset_id) \
            .one()
        # pylint: enable-msg=E1101

        if todo > 0:
            msg = '%s is not ready. %d photos remaining' % (model, todo)
            logging.info(msg)
            return

        not_ready = False

        for name in methods:
            nms_method = scores.METHODS[name]
            # pylint: disable-msg=E1101
            todo, = session.query(func.count(Detection.id)) \
                .join(Model) \
                .join(Photo) \
                .filter(Photo.test == True) \
                .filter(Model.filename == model) \
                .filter(Photo.dataset_id == dataset_id) \
                .filter(nms_method.output == None) \
                .one()
            # pylint: enable-msg=E1101
            if todo > 0:
                msg = '%s is not ready.  %d %s NMS remaining' % (
                    model, todo, name)
                logging.info(msg)
                not_ready = True

        if not_ready:
            return

        # pylint: disable-msg=E1101
        dataset_id = [Photo.dataset_id == dataset_id]
        # pylint: enable-msg=E1101

        for method in methods:
            nms_method = scores.METHODS[method]
            selected = [nms_method.output == True]
            msg = '%s method: %s' % (model, method)
            logging.info(msg)
            points = precision_recall(
                session,
                nms_method.score,
                dataset_id + selected,
                dataset_id, model
            )
            idx = numpy.abs(points[:, 0] - 0.9).argmin()
            logging.info(points[idx, :])
            labels = get_labels(
                session, nms_method.score, selected, [], model, points[idx, 2])
            dists = [l.dist for l in labels]
            dist_zs = [l.height_diff for l in labels]
            logging.info(
                (numpy.array(dists).mean(), numpy.array(dist_zs).mean()))

        logging.info('done')

    except:
        raise
    finally:
        session.close()
Exemple #10
0
def nms(pid, model, method):
    """Preforms NMS on detections."""

    session = SESSION()

    logging.info((pid, model, method))

    try:

        scoring_method = scores.METHODS[method]

        set_nms = str(scoring_method.output).split('.')[-1]

        # pylint: disable-msg=E1101
        mid, = session.query(Model.id) \
            .filter_by(filename=model) \
            .one()

        todo, = session.query(func.count(Detection.id)) \
            .filter(Detection.pid == pid) \
            .filter(or_(*[m == None for m in scoring_method.inputs])) \
            .filter(Detection.mid == mid) \
            .one()
        # pylint: enable-msg=E1101

        if todo > 0:
            raise Exception('Some input was not yet computed')

        while True:
            # pylint: disable-msg=E1101
            result = session.query(Detection) \
                .filter(Detection.pid == pid) \
                .filter(scoring_method.output == None) \
                .filter(Detection.mid == mid)
            # pylint: enable-msg=E1101

            result = result \
                .order_by(desc(scoring_method.score)) \
                .first()

            if result is None:
                break

            setattr(result, set_nms, True)

            overlap = query_utils.overlap(result, Detection)
            covered = overlap > 0.3

            # pylint: disable-msg=E1101
            blacklist = session.query(Detection) \
                .filter(Detection.pid == pid) \
                .filter(scoring_method.output == None) \
                .filter(Detection.mid == mid) \
                .filter(covered)
            # pylint: enable-msg=E1101

            for elt in blacklist:
                setattr(elt, set_nms, False)

        session.commit()

        return pid
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
def gen_results(model, methods, aos, dataset_id):
    """Computes PR curve and optionally OS-R curve."""

    session = SESSION()
    try:

        difficulties = {
            'full': []
        }

        daynights = {
            'both': [],
        }

        # pylint: disable-msg=E1101
        model_id, = session.query(Model.id) \
            .filter(Model.filename == model) \
            .one()

        todo, = session.query(func.count(Photo.id)) \
            .outerjoin((
                Detection,
                and_(
                    Detection.pid == Photo.id,
                    Detection.mid == model_id
                )
            )) \
            .filter(Photo.test == True) \
            .filter(Detection.id == None) \
            .filter(Photo.dataset_id == dataset_id) \
            .one()
        # pylint: enable-msg=E1101

        if todo > 0:
            msg = '%s is not ready. %d photos remaining' % (model, todo)
            logging.info(msg)
            return

        not_ready = False

        for name in methods:
            nms_method = scores.METHODS[name]
            # pylint: disable-msg=E1101
            todo, = session.query(func.count(Detection.id)) \
                .join(Model) \
                .join(Photo) \
                .filter(Photo.test == True) \
                .filter(Model.filename == model) \
                .filter(Photo.dataset_id == dataset_id) \
                .filter(nms_method.output == None) \
                .one()
            # pylint: enable-msg=E1101
            if todo > 0:
                msg = '%s is not ready.  %d %s NMS remaining' % (
                    model, todo, name)
                logging.info(msg)
                not_ready = True

        if not_ready:
            return

        # pylint: disable-msg=E1101
        dataset_id = [Photo.dataset_id == dataset_id]
        # pylint: enable-msg=E1101

        for daynight, difficulty in itertools.product(daynights, difficulties):
            for method in methods:
                nms_method = scores.METHODS[method]
                selected = [nms_method.output == True]
                msg = '%s daynight: %s, difficulty: %s, method: %s' % (
                    model, daynight, difficulty, method)
                logging.info(msg)
                points = precision_recall(
                    session,
                    nms_method.score,
                    dataset_id + daynights[daynight] + selected,
                    dataset_id +
                    daynights[daynight] + difficulties[difficulty],
                    model
                )
                name = '%s, %s' % (model, method)
                if aos:
                    points_aos = orientation_similarity(session,
                                                        nms_method.score,
                                                        dataset_id +
                                                        daynights[
                                                            daynight] + selected,
                                                        dataset_id +
                                                        daynights[daynight] + difficulties[
                                                            difficulty],
                                                        model
                                                        )
                else:
                    points_aos = None

                print(points.shape)
                print(scipy.integrate.trapz(points[:, 0], points[:, 1]))
                filename = '%s-%s-%s-%s-pr.txt' % (
                    model, daynight, difficulty, method)
                print(filename)
                numpy.savetxt(filename, points)
                if points_aos is not None:
                    print(scipy.integrate.trapz(
                        points_aos[:, 0], points_aos[:, 1]))
                    filename = '%s-%s-%s-%s-aos.txt' % (
                        model, daynight, difficulty, method)
                    print(filename)
                    numpy.savetxt(filename, points_aos)

        logging.info('done')

    except:
        raise
    finally:
        session.close()
Exemple #12
0
def select_evaluation():
    """Selects the vehicles that will appear in NYC3DCars."""

    nyc3dcars_session = SESSION()
    labeler_session = labeler.SESSION()

    try:
        # Reset photos
        photos = nyc3dcars_session.query(Photo) \
            .options(joinedload('dataset'))

        for photo in photos:
            photo.daynight = None

        # Reset vehicles
        vehicles = nyc3dcars_session.query(Vehicle)
        for vehicle in vehicles:
            nyc3dcars_session.delete(vehicle)

        # Turn photos back on if they have at least 1 final revision
        # pylint: disable-msg=E1101
        photos = labeler_session.query(labeler.Photo) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .options(joinedload('daynights')) \
            .options(joinedload('annotations.flags')) \
            .options(joinedload('annotations')) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.User.trust == True) \
            .distinct()
        # pylint: enable-msg=E1101

        photos = list(photos)

        num_photos = len(photos)

        num_test = 0
        num_train = 0
        num_flagged = 0

        print('Checking for new photos')
        for labeler_photo in photos:
            # Do not consider photos that have been flagged
            num_flags = sum(
                len(annotation.flags)
                for annotation in labeler_photo.annotations
                if annotation.user.trust)
            if num_flags > 0:
                num_flagged += 1
                continue

            days = 0
            nights = 0

            for daynight in labeler_photo.daynights:
                if not daynight.user.trust:
                    continue
                if daynight.daynight == 'day':
                    days += 1
                else:
                    nights += 1
            if days + nights == 0:
                print('Need Day/Night for photo: %d' % labeler_photo.id)
                continue

            nyc3dcars_photo = nyc3dcars_session.query(Photo) \
                .filter_by(id=labeler_photo.id) \
                .one()

            if nyc3dcars_photo.test == True:
                num_test += 1
            elif nyc3dcars_photo.test == False:
                num_train += 1
            else:
                if num_train > num_test:
                    print('Test: %d' % labeler_photo.id)
                    nyc3dcars_photo.test = True
                    num_test += 1
                else:
                    print('Train: %d' % labeler_photo.id)
                    nyc3dcars_photo.test = False
                    num_train += 1

            if days > nights:
                nyc3dcars_photo.daynight = 'day'
            else:
                nyc3dcars_photo.daynight = 'night'
        print('New photos done')
        print('%d photos' % num_photos)
        print('%d flagged' % num_flagged)
        print('%d test' % num_test)
        print('%d train' % num_train)

        # pylint: disable-msg=E1101
        good_pids = nyc3dcars_session.query(Photo.id) \
            .filter(Photo.test != None) \
            .all()
        # pylint: enable-msg=E1101

        # get photos with 1 and 2 users
        # pylint: disable-msg=E1101
        photos_one_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) == 1)

        photos_two_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) == 2)

        photos_more_user = labeler_session.query(labeler.Photo.id) \
            .select_from(labeler.Photo) \
            .join(labeler.Annotation) \
            .join(labeler.User) \
            .join(labeler.Revision) \
            .filter(labeler.User.trust == True) \
            .filter(labeler.Revision.final == True) \
            .filter(labeler.Photo.id.in_(good_pids)) \
            .group_by(labeler.Photo.id) \
            .having(func.count(labeler.Revision.id) > 2)
        for photo in photos_more_user:
            print(photo.id)

        for photo, in photos_one_user:
            vehicles = labeler_session.query(labeler.Vehicle) \
                .select_from(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .options(joinedload('revision')) \
                .options(joinedload('revision.annotation')) \
                .options(joinedload('revision.annotation.user')) \
                .options(joinedload('occlusionrankings')) \
                .options(joinedload('occlusionrankings.occlusion_session')) \
                .options(joinedload('bbox_sessions')) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Annotation.pid == photo) \
                .filter(labeler.Revision.final == True) \
                .distinct()

            for vehicle in vehicles:
                convert_vehicle(nyc3dcars_session, vehicle)

        # get good vehicles for 2 user case
        for photo, in photos_two_user:
            annotations = labeler_session.query(labeler.Annotation) \
                .join(labeler.User) \
                .join(labeler.Revision) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Annotation.pid == photo) \
                .filter(labeler.Revision.final == True) \
                .all()
            assert len(annotations) == 2

            vehicles1 = labeler_session.query(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Revision.aid == annotations[0].id) \
                .filter(labeler.Revision.final == True) \
                .all()

            vehicles2 = labeler_session.query(labeler.Vehicle) \
                .join(labeler.Revision) \
                .join(labeler.Annotation) \
                .join(labeler.User) \
                .filter(labeler.User.trust == True) \
                .filter(labeler.Revision.aid == annotations[1].id) \
                .filter(labeler.Revision.final == True) \
                .all()

            if len(vehicles1) > len(vehicles2):
                vehicles = vehicles1
            else:
                vehicles = vehicles2

            for vehicle in vehicles:
                print(vehicle.id)
                convert_vehicle(nyc3dcars_session, vehicle)

        num_vehicles, = nyc3dcars_session.query(
            func.count(Vehicle.id)) \
            .one()

        photo_test, = nyc3dcars_session.query(
            func.count(Photo.id)) \
            .filter(Photo.test == True) \
            .one()

        photo_train, = nyc3dcars_session.query(
            func.count(Photo.id)) \
            .filter(Photo.test == False) \
            .one()
        # pylint: enable-msg=E1101

        print('%d vehicles in dataset' % num_vehicles)
        print('%d images for training' % photo_train)
        print('%d images for testing' % photo_test)

        nyc3dcars_session.commit()
    except:
        nyc3dcars_session.rollback()
        labeler_session.rollback()
        raise
    finally:
        nyc3dcars_session.close()
        labeler_session.close()