Пример #1
0
 def test_empty_len_size(self):
     ts = TrackSet()
     nt.assert_true(ts, "Invalid track set instance constructed")
     l = len(ts)
     s = ts.size()
     nt.assert_equal(l, 0)
     nt.assert_equal(l, s)
Пример #2
0
 def test_empty_len_size(self):
     ts = TrackSet()
     nt.assert_true(ts, "Invalid track set instance constructed")
     l = len(ts)
     s = ts.size()
     nt.assert_equal(l, 0)
     nt.assert_equal(l, s)
Пример #3
0
 def test_new_nonempty(self):
     n = 10
     tracks = [Track(i) for i in xrange(n)]
     ts = TrackSet(tracks)
     nt.assert_true(ts, "Invalid track set instance constructed")
     nt.assert_equal(len(ts), n)
     nt.assert_equal(ts.size(), n)
Пример #4
0
 def test_new_nonempty(self):
     n = 10
     tracks = [Track() for _ in xrange(n)]
     ts = TrackSet(tracks)
     nt.assert_true(ts, "Invalid track set instance constructed")
     nt.assert_equal(len(ts), n)
     nt.assert_equal(ts.size(), n)
Пример #5
0
 def test_get_track_single(self):
     # get track when only track
     t = Track(0)
     ts = TrackSet([t])
     u = ts.get_track(0)
     # Check that they're the same underlying instance
     nt.assert_equal(ctypes.addressof(t.c_pointer.contents),
                     ctypes.addressof(u.c_pointer.contents))
Пример #6
0
    def test_all_frame_ids_single_track(self):
        # From a single track
        n = 10
        t = Track(1)
        for i in range(n):
            t.append(TrackState(i))
        ts = TrackSet([t])

        nt.assert_equal(ts.all_frame_ids(), set(range(10)))
Пример #7
0
    def test_tracklist_accessor(self):
        n = 10
        tracks = [Track(i) for i in range(n)]
        ts = TrackSet(tracks)
        ts_tracks = ts.tracks()

        nt.assert_equal(len(ts_tracks), n)
        for i, t in enumerate(ts_tracks):
            nt.assert_equal(t.id, i)
Пример #8
0
    def test_get_track_multiple(self):
        n = 10
        tracks = [Track(i) for i in range(n)]
        ts = TrackSet(tracks)

        # Check that they're the same underlying instance
        for i in range(n):
            nt.assert_equal(
                ctypes.addressof(ts.get_track(i).c_pointer.contents),
                ctypes.addressof(tracks[i].c_pointer.contents))
Пример #9
0
 def test_all_frame_ids_multitrack(self):
     # Across multiple tracks
     n = 10
     t1 = Track(1)
     for i in range(0, n):
         t1.append(TrackState(i))
     t2 = Track(2)
     for i in range(n, n + 5):
         t2.append(TrackState(i))
     ts = TrackSet([t1, t2])
     nt.assert_equal(ts.all_frame_ids(), set(range(n + 5)))
Пример #10
0
    def test_all_frame_ids_single_track(self):
        # From a single track
        n = 10
        t = Track(1)
        for i in range(n):
            t.append(TrackState(i))
        ts = TrackSet([t])

        nt.assert_equal(
            ts.all_frame_ids(),
            set(range(10))
        )
Пример #11
0
 def test_all_frame_ids_multitrack(self):
     # Across multiple tracks
     n = 10
     t1 = Track(1)
     for i in range(0, n):
         t1.append(TrackState(i))
     t2 = Track(2)
     for i in range(n, n+5):
         t2.append(TrackState(i))
     ts = TrackSet([t1, t2])
     nt.assert_equal(
         ts.all_frame_ids(),
         set(range(n+5))
     )
Пример #12
0
 def test_get_track_empty(self):
     # Empty set
     ts = TrackSet()
     nt.assert_raises(
         IndexError,
         ts.get_track, 0
     )
Пример #13
0
    def triangulate(self, cameras, tracks, landmarks):
        """
        Triangulate the landmark locations given sets of cameras and tracks

        This function only triangulates the landmarks with indices in the
        landmark map and which have support in the tracks and cameras

        :param cameras: cameras viewing the landmarks
        :type cameras: CameraMap

        :param tracks: tracks to use as constraints
        :type tracks: TrackSet

        :param landmarks: landmarks to triangulate
        :type landmarks: LandmarkMap

        :return: New landmarks instance of triangulated landmarks

        """
        # Copy pointer container for reference updating so we don't pollute the
        # input instance.
        lmap_ptr = LandmarkMap.c_ptr_type()(landmarks.c_pointer.contents)

        self._call_cfunc(
            'vital_algorithm_triangulate_landmarks_triangulate',
            [self.C_TYPE_PTR, CameraMap.c_ptr_type(), TrackSet.c_ptr_type(),
             ctypes.POINTER(LandmarkMap.c_ptr_type())],
            [self, cameras, tracks, ctypes.byref(landmarks)]
        )

        r_lmap = landmarks
        if ctypes.addressof(lmap_ptr.contents) != ctypes.addressof(landmarks.c_pointer.contents):
            r_lmap = LandmarkMap(from_cptr=lmap_ptr)

        return r_lmap
Пример #14
0
 def test_get_track_missing(self):
     # test failure to get track from set when set does have contents, but
     # TID is not present
     ts = TrackSet([Track(0), Track(1), Track(3)])
     nt.assert_raises(
         IndexError,
         ts.get_track, 2
     )
Пример #15
0
    def test_last_frame(self):
        # no tracks
        ts = TrackSet()
        nt.assert_equal(ts.last_frame(), 0)

        # one track
        t = Track(1)
        t.append(TrackState(1))
        t.append(TrackState(2))
        ts = TrackSet([t])
        nt.assert_equal(ts.last_frame(), 2)

        # two tracks
        t2 = Track(2)
        t2.append(TrackState(3))
        ts = TrackSet([t, t2])
        nt.assert_equal(ts.last_frame(), 3)
Пример #16
0
    def track(self, prev_tracks, frame_num, image, mask=None):
        """
        Extend a previous set of tracks using the given image.

        An optional mask image may be provided, where positive valued regions
        indicate regions of the input image to consider for feature tracking.
        The mask image must be of the same dimensions as the input image, other
        wise an exception is raised.

        :param prev_tracks: the tracks from previous tracking steps
        :type prev_tracks: TrackSet

        :param frame_num: the frame number of the current frame
        :type frame_num: int

        :param image: the image pixels for the current frame
        :type image: ImageContainer

        :param mask: Optional mask image that uses positive values to denote
                     regions of the input image to consider for feature
                     tracking. An empty sptr indicates no mask (default
                     value).
        :type mask: ImageContainer

        :return: an updated set a tracks including the current frame
        :rtype: TrackSet

        """
        tf_track_argtypes = [
            self.C_TYPE_PTR, TrackSet.C_TYPE_PTR, ctypes.c_uint,
            ImageContainer.C_TYPE_PTR
        ]
        tf_track_args = [self, prev_tracks, frame_num, image]
        tf_track_restype = TrackSet.C_TYPE_PTR

        if mask:
            tf_track = self.VITAL_LIB['vital_algorithm_track_features_'
                                      'track_with_mask']
            tf_track_argtypes.append(ImageContainer.C_TYPE_PTR)
            tf_track_args.append(mask)
        else:
            tf_track = self.VITAL_LIB['vital_algorithm_track_features_track']
        tf_track_argtypes.append(VitalErrorHandle.C_TYPE_PTR)

        tf_track.argtypes = tf_track_argtypes
        tf_track.restype = tf_track_restype

        with VitalErrorHandle() as eh:
            tf_track_args.append(eh)
            return TrackSet(from_cptr=tf_track(*tf_track_args))
Пример #17
0
    def initialize(self, cmap, lmap, tset):
        """
        Initialize the camera and landmark parameters given a set of tracks

        :param cmap: Cameras to initialize
        :type cmap: CameraMap

        :param lmap: Landmarks to initialize
        :type lmap: LandmarkMap

        :param tset: Tracks to use as constraints
        :type tset: TrackSet

        :return: New, initialized camera and landmark maps.
        :rtype: (CameraMap, LandmarkMap)

        """
        # make a separate copy of pointer container in prep for passing by ref
        cmap_ptr = CameraMap.c_ptr_type()(cmap.c_pointer.contents)
        lmap_ptr = LandmarkMap.c_ptr_type()(lmap.c_pointer.contents)

        self._call_cfunc(
            "vital_algorithm_initialize_cameras_landmarks_initialize", [
                self.C_TYPE_PTR,
                ctypes.POINTER(CameraMap.c_ptr_type()),
                ctypes.POINTER(LandmarkMap.c_ptr_type()),
                TrackSet.c_ptr_type()
            ],
            [self, ctypes.byref(cmap_ptr),
             ctypes.byref(lmap_ptr), tset])

        # Initialize new objects if "returned" pointers are different from input
        # objects
        r_cmap = cmap
        if ctypes.addressof(cmap_ptr.contents) != ctypes.addressof(
                cmap.c_pointer.contents):
            self._log.debug("Creating new CameraMap instance")
            r_cmap = CameraMap(from_cptr=cmap_ptr)
        r_lmap = lmap
        if ctypes.addressof(lmap_ptr.contents) != ctypes.addressof(
                lmap.c_pointer.contents):
            self._log.debug("Creating new LandmarkMap instance")
            r_lmap = LandmarkMap(from_cptr=lmap_ptr)

        return r_cmap, r_lmap
Пример #18
0
    def optimize(self, cmap, lmap, tset):
        """
        Optimize the camera and landmark parameters given a set of tracks

        :param cmap: Cameras to optimize
        :type cmap: CameraMap

        :param lmap: Landmarks to optimize
        :type lmap: LandmarkMap

        :param tset: Tracks to use as constraints
        :type tset: TrackSet

        :return: New, optimized Camera and Landmark maps.
        :rtype: (CameraMap, LandmarkMap)

        """
        # make a separate copy of pointer container in prep for passing by ref
        cmap_ptr = CameraMap.c_ptr_type()(cmap.c_pointer.contents)
        lmap_ptr = LandmarkMap.c_ptr_type()(lmap.c_pointer.contents)

        self._call_cfunc(
            'vital_algorithm_bundle_adjust_optimize',
            [self.C_TYPE_PTR,
             ctypes.POINTER(CameraMap.c_ptr_type()),
             ctypes.POINTER(LandmarkMap.c_ptr_type()),
             TrackSet.c_ptr_type()],
            [self, ctypes.byref(cmap_ptr), ctypes.byref(lmap_ptr), tset]
        )

        # Initialize new objects if "returned" pointers are different from input
        # objects
        r_cmap = cmap
        if ctypes.addressof(cmap_ptr.contents) != ctypes.addressof(cmap.c_pointer.contents):
            self._log.debug("Creating new CameraMap instance")
            r_cmap = CameraMap(from_cptr=cmap_ptr)
        r_lmap = lmap
        if ctypes.addressof(lmap_ptr.contents) != ctypes.addressof(lmap.c_pointer.contents):
            self._log.debug("Creating new LandmarkMap instance")
            r_lmap = LandmarkMap(from_cptr=lmap_ptr)

        return r_cmap, r_lmap
Пример #19
0
    def test_last_frame(self):
        # no tracks
        ts = TrackSet()
        nt.assert_equal(ts.last_frame(), 0)

        # one track
        t = Track(1)
        t.append(TrackState(1))
        t.append(TrackState(2))
        ts = TrackSet([t])
        nt.assert_equal(ts.last_frame(), 2)

        # two tracks
        t2 = Track(2)
        t2.append(TrackState(3))
        ts = TrackSet([t, t2])
        nt.assert_equal(ts.last_frame(), 3)
Пример #20
0
    def track(self, prev_tracks, frame_num, image, mask=None):
        """
        Extend a previous set of tracks using the given image.

        An optional mask image may be provided, where positive valued regions
        indicate regions of the input image to consider for feature tracking.
        The mask image must be of the same dimensions as the input image, other
        wise an exception is raised.

        :param prev_tracks:
        :param frame_num:
        :param image:
        :param mask:
        :return:

        """
        tf_track_argtypes = [
            self.C_TYPE_PTR, TrackSet.C_TYPE_PTR, ctypes.c_uint,
            ImageContainer.C_TYPE_PTR
        ]
        tf_track_args = [self, prev_tracks, frame_num, image]
        tf_track_restype = TrackSet.C_TYPE_PTR

        if mask:
            tf_track = self.VITAL_LIB['vital_algorithm_track_features_'
                                      'track_with_mask']
            tf_track_argtypes.append(ImageContainer.C_TYPE_PTR)
            tf_track_args.append(mask)
        else:
            tf_track = self.VITAL_LIB['vital_algorithm_track_features_track']
        tf_track_argtypes.append(VitalErrorHandle.C_TYPE_PTR)

        tf_track.argtypes = tf_track_argtypes
        tf_track.restype = tf_track_restype

        with VitalErrorHandle() as eh:
            tf_track_args.append(eh)
            return TrackSet(from_cptr=tf_track(*tf_track_args))
Пример #21
0
    def test_tracklist_accessor(self):
        n = 10
        tracks = [Track(i) for i in xrange(n)]
        ts = TrackSet(tracks)
        ts_tracks = ts.tracks()

        nt.assert_equal(len(ts_tracks), n)
        for i, t in enumerate(ts_tracks):
            nt.assert_equal(t.id, i)

        # constructing a new trackset from the returned list of tracks should
        # yield a trackset whose accessor should return the same list of tracks
        # (same C/C++ instances).
        ts2 = TrackSet(ts_tracks)
        ts2_tracks = ts2.tracks()
        for i in xrange(n):
            ctypes.addressof(ts2_tracks[0].c_pointer.contents) \
                == ctypes.addressof(ts2_tracks[0].c_pointer.contents)
Пример #22
0
    def triangulate(self, cameras, tracks, landmarks):
        """
        Triangulate the landmark locations given sets of cameras and tracks

        This function only triangulates the landmarks with indices in the
        landmark map and which have support in the tracks and cameras

        :param cameras: cameras viewing the landmarks
        :type cameras: CameraMap

        :param tracks: tracks to use as constraints
        :type tracks: TrackSet

        :param landmarks: landmarks to triangulate
        :type landmarks: LandmarkMap

        :return: New landmarks instance of triangulated landmarks

        """
        # Copy pointer container for reference updating so we don't pollute the
        # input instance.
        lmap_ptr = LandmarkMap.c_ptr_type()(landmarks.c_pointer.contents)

        self._call_cfunc('vital_algorithm_triangulate_landmarks_triangulate', [
            self.C_TYPE_PTR,
            CameraMap.c_ptr_type(),
            TrackSet.c_ptr_type(),
            ctypes.POINTER(LandmarkMap.c_ptr_type())
        ], [self, cameras, tracks,
            ctypes.byref(landmarks)])

        r_lmap = landmarks
        if ctypes.addressof(lmap_ptr.contents) != ctypes.addressof(
                landmarks.c_pointer.contents):
            r_lmap = LandmarkMap(from_cptr=lmap_ptr)

        return r_lmap
Пример #23
0
def subset_tracks(trackset, keep_fraction=0.75):
    """
    randomly drop a fraction of the track states per track in the given set,
    creating and returning new tracks in a new track-set.

    :type trackset: TrackSet
    :type keep_fraction: float
    """
    log = logging.getLogger(__name__)

    new_tracks = []
    for t in trackset.tracks():
        nt = Track(t.id)

        msg = 'track %d:' % t.id,
        for ts in t:
            if numpy.random.rand() < keep_fraction:
                nt.append(ts)
                msg += '.',
            else:
                msg += 'X',
        log.info(' '.join(msg))
        new_tracks.append(nt)
    return TrackSet(new_tracks)
Пример #24
0
def projected_tracks(lmap, cmap):
    """
    Use the cameras to project the landmarks back into their images.
    :type lmap: LandmarkMap
    :type cmap: CameraMap
    """
    tracks = []

    cam_d = cmap.as_dict()
    landmark_d = lmap.as_dict()

    for lid, l in landmark_d.iteritems():
        t = Track(lid)
        tracks.append(t)

        # Sort camera iteration to make sure that we go in order of frame IDs
        for fid in sorted(cam_d):
            cam = cam_d[fid]
            f = Feature(cam.project(l.loc))
            t.append(TrackState(fid, f))

        assert t.size == len(cam_d)

    return TrackSet(tracks)
Пример #25
0
 def test_get_track_single(self):
     # get track when only track
     t = Track(0)
     ts = TrackSet([t])
     u = ts.get_track(0)
Пример #26
0
 def test_new(self):
     ts = TrackSet()
Пример #27
0
 def test_empty_len_size(self):
     ts = TrackSet()
     l = len(ts)
     s = ts.size()
     nt.assert_equal(l, 0)
     nt.assert_equal(l, s)
Пример #28
0
def main():
    # Same logging format as C++, except for ',' separating milliseconds
    logging.basicConfig(format="%(asctime)s %(levelname)s %(filename)s(%(lineno)s): %(message)s")
    logging.getLogger().setLevel(logging.INFO)
    log = logging.getLogger(__name__)

    args = parse_args()

    register_plugins_once()
    c = default_config_block()

    # Read in config file if given
    if args.config:
        c.read(args.config)

    # Set algorithm configurations + update config-block
    image_reader, image_converter, feature_tracker = base_algorithms()
    image_reader.set_config(c)
    image_reader.get_config(c)
    image_converter.set_config(c)
    image_converter.get_config(c)
    feature_tracker.set_config(c)
    feature_tracker.get_config(c)

    if args.generate_config:
        check_config(c)
        c.write(args.generate_config)
        log.info("Generated configuration: %s", args.generate_config)
        sys.exit(0)

    if not check_config(c):
        raise RuntimeError("Configuration invalid. "
                           "Check above warning messages.")

    image_list_fp = c.get_value('image_list_file')
    mask_list_fp = c.get_value('mask_list_file')
    output_tracks_fp = c.get_value('output_tracks_file')

    # Read in image files, and optional mask files
    # iterate over track features function
    with open(image_list_fp) as f:
        frame_list = [l.strip() for l in f]
    if mask_list_fp:
        with open(mask_list_fp) as f:
            mask_list = [l.strip() for l in f]
    else:
        mask_list = [None] * len(frame_list)
    assert len(frame_list) == len(mask_list), \
        "Image and mask list is not congruent in size (%d images != %d " \
        "masks)" % (len(frame_list), len(mask_list))

    # Track over frames + masks
    track_set = TrackSet()
    for i, (f, m) in enumerate(itertools.izip(frame_list, mask_list)):
        log.info("Processing frame: %s", f)
        frame = image_converter.convert(image_reader.load(f))
        mask = (m and image_converter.convert(image_reader.load(m))) or None
        track_set = feature_tracker.track(track_set, i, frame, mask)
        # TODO: maptk::extract_feature_colors?

    log.info("Writing tracks file: %s", output_tracks_fp)
    safe_create_dir(os.path.dirname(output_tracks_fp))
    track_set.write_feature_tracks_file(output_tracks_fp)
Пример #29
0
 def test_new_nonempty(self):
     n = 10
     tracks = [Track(i) for i in range(n)]
     ts = TrackSet(tracks)
     nt.assert_equal(len(ts), n)
     nt.assert_equal(ts.size(), n)
Пример #30
0
 def test_new(self):
     ts = TrackSet()
     nt.assert_true(ts, "Invalid track set instance constructed")
Пример #31
0
def main():
    # Same logging format as C++, except for ',' separating milliseconds
    logging.basicConfig(
        format="%(asctime)s %(levelname)s %(filename)s(%(lineno)s): %(message)s"
    )
    logging.getLogger().setLevel(logging.INFO)
    log = logging.getLogger(__name__)

    args = parse_args()

    register_plugins_once()
    c = default_config_block()

    # Read in config file if given
    if args.config:
        c.read(args.config)

    # Set algorithm configurations + update config-block
    image_reader, image_converter, feature_tracker = base_algorithms()
    image_reader.set_config(c)
    image_reader.get_config(c)
    image_converter.set_config(c)
    image_converter.get_config(c)
    feature_tracker.set_config(c)
    feature_tracker.get_config(c)

    if args.generate_config:
        check_config(c)
        c.write(args.generate_config)
        log.info("Generated configuration: %s", args.generate_config)
        sys.exit(0)

    if not check_config(c):
        raise RuntimeError("Configuration invalid. "
                           "Check above warning messages.")

    image_list_fp = c.get_value('image_list_file')
    mask_list_fp = c.get_value('mask_list_file')
    output_tracks_fp = c.get_value('output_tracks_file')

    # Read in image files, and optional mask files
    # iterate over track features function
    with open(image_list_fp) as f:
        frame_list = [l.strip() for l in f]
    if mask_list_fp:
        with open(mask_list_fp) as f:
            mask_list = [l.strip() for l in f]
    else:
        mask_list = [None] * len(frame_list)
    assert len(frame_list) == len(mask_list), \
        "Image and mask list is not congruent in size (%d images != %d " \
        "masks)" % (len(frame_list), len(mask_list))

    # Track over frames + masks
    track_set = TrackSet()
    for i, (f, m) in enumerate(itertools.izip(frame_list, mask_list)):
        log.info("Processing frame: %s", f)
        frame = image_converter.convert(image_reader.load(f))
        mask = (m and image_converter.convert(image_reader.load(m))) or None
        track_set = feature_tracker.track(track_set, i, frame, mask)
        # TODO: maptk::extract_feature_colors?

    log.info("Writing tracks file: %s", output_tracks_fp)
    safe_create_dir(os.path.dirname(output_tracks_fp))
    track_set.write_feature_tracks_file(output_tracks_fp)