Example #1
0
def scale(images, target_img_size):
    """Scales a list of images to the target size

    Parameters
    ----------
    images : array_like
        A list of images (in Bob format) to be scaled to the target size
    target_img_size : int or tuple
        A tuple of size 2 as (H, W) or an integer where H==W

    Returns
    -------
    numpy.ndarray
        Scaled images
    """
    if isinstance(target_img_size, int):
        target_img_size = (target_img_size, target_img_size)

    # images are always batched
    images = check_array(images, allow_nd=True)

    output_shape = tuple(target_img_size)
    output_shape = tuple(images.shape[0:1]) + output_shape

    # If it's Bob batched RGB images
    if images.ndim > 3:
        images = to_matplotlib(images)
        images = resize(images, output_shape=output_shape)
        return to_bob(images) * 255
    else:
        # If it's Bob batched gray scaled images
        images = resize(images, output_shape=output_shape)
        return images * 255
def prepro(addr):

    image = to_bob(color.rgb2gray(io.imread(addr)))
    mask = LeeMask()(image)

    image = HistogramEqualization()(image, mask)
    # imshow(image)
    # image = image.astype('float64')/255.
    MC = MaximumCurvature(2.5)
    kappa = MC.detect_valleys(image, mask)
    Vt = MC.eval_vein_probabilities(kappa)
    Cd = MC.connect_centres(Vt)
    G = numpy.amax(Cd, axis=2)
    bina = MC.binarise(G)
    return bina
Example #3
0
        def _frames_generator():
            # read the frames one by one and yield them
            real_frame_numbers = self.indices[index[0]]
            for i, frame in enumerate(self.reader):

                frame = to_bob(frame)
                if i not in real_frame_numbers:
                    continue
                # make sure arrays are loaded in C order because we reshape them
                # by C order later. Also, index into the frames here
                frame = np.ascontiguousarray(frame)[index[1:]]
                # return a tuple of flat array to match what is expected by
                # field_dtype
                yield (frame.ravel(), )
                if i == real_frame_numbers[-1]:
                    break
Example #4
0
def test_video_as_array_vs_dask():
    import dask

    path = datafile("testvideo.avi", "bob.bio.video.test")
    start = time.time()
    video = bob.bio.video.VideoAsArray(path, selection_style="all")
    video = dask.array.from_array(video, (20, 1, 480, 640))
    video = video.compute(scheduler="single-threaded")
    load_time = time.time() - start

    start = time.time()
    reference = to_bob(np.array(list((imageio.get_reader(path).iter_data()))))
    load_time2 = time.time() - start
    # Here, we're also chunking each frame, but normally we would only chunk the first axis.
    print(
        f"FYI: It took {load_time:.2f} s to load the video with dask and {load_time2:.2f} s "
        "to load directly. The slower loading with dask is expected.")
    np.testing.assert_allclose(reference, video)
Example #5
0
def test_video_as_array():
    path = datafile("testvideo.avi", "bob.bio.video.test")

    video = bob.bio.video.VideoAsArray(path, selection_style="all")
    assert len(video) == 83, len(video)
    assert video.indices == range(83), video.indices
    assert video.shape == (83, 3, 480, 640), video.shape
    if platform.machine() == "arm64" and platform.system() == "Darwin":
        raise nose.SkipTest("Skipping test on arm64 macos")
    np.testing.assert_equal(video[0][:, 0, 0], np.array([78, 103, 100]))

    video_slice = video[1:2, 1:-1, 1:-1, 1:-1]
    assert video_slice.shape == (1, 1, 478, 638), video_slice.shape

    # test the slice against the video loaded by imageio directly
    video = to_bob(imageio.get_reader(path).get_data(1))
    video = video[1:-1, 1:-1, 1:-1]
    video = video[None, ...]
    np.testing.assert_allclose(video, video_slice)

    video = bob.bio.video.VideoAsArray(path, max_number_of_frames=3)
    assert len(video) == 3, len(video)
    assert video.indices == [13, 41, 69], video.indices
    assert video.shape == (3, 3, 480, 640), video.shape
    np.testing.assert_equal(video[-1][:, 0, 0], np.array([75, 100, 97]))

    # pickle video and unpickle to see if it works
    with tempfile.NamedTemporaryFile(suffix=".pkl") as f:
        pickle.dump(video, f)
        f.seek(0)
        pickle.load(f)

    assert (
        str(video) ==
        f"VideoAsArray: {video.path!r} {video.dtype!r} {video.ndim!r} {video.shape!r} {video.indices!r}"
    ), str(video)
Example #6
0
    def __getitem__(self, index):
        # logger.debug("Getting frame %s from %s", index, self.path)

        # In this method, someone is requesting indices thinking this video has
        # the shape of self.shape but self.shape is determined through
        # select_frames parameters. What we want to do here is to translate
        # ``index`` to real indices of the video file given that we want to load
        # only the selected frames. List of the selected frames are stored in
        # self.indices

        # If only one frame is requested, first translate the index to the real
        # frame number in the video file and load that

        if isinstance(index, int):
            idx = self.indices[index]
            return self.transform(
                np.asarray([to_bob(self.reader.get_data(idx))]))[0]

        if not (isinstance(index, tuple) and len(index) == self.ndim
                and all(isinstance(idx, slice) for idx in index)):
            raise NotImplementedError(
                f"Indxing like {index} is not supported yet!")

        # dask.array.from_array sometimes requests empty arrays
        if all(i == slice(0, 0) for i in index):
            return np.array([], dtype=self.dtype)

        def _frames_generator():
            # read the frames one by one and yield them
            real_frame_numbers = self.indices[index[0]]
            for i, frame in enumerate(self.reader):

                frame = to_bob(frame)
                if i not in real_frame_numbers:
                    continue
                # make sure arrays are loaded in C order because we reshape them
                # by C order later. Also, index into the frames here
                frame = np.ascontiguousarray(frame)[index[1:]]
                # return a tuple of flat array to match what is expected by
                # field_dtype
                yield (frame.ravel(), )
                if i == real_frame_numbers[-1]:
                    break

        iterable = _frames_generator()
        # compute the final shape given self.shape and index
        # see https://stackoverflow.com/a/36188683/1286165
        shape = [
            len(range(*idx.indices(dim)))
            for idx, dim in zip(index, self.shape)
        ]
        # field_dtype contains information about dtype and shape of each frame
        # numpy black magic: https://stackoverflow.com/a/12473478/1286165 allows
        # us to yield frame by frame in _frames_generator which greatly speeds
        # up loading the video
        field_dtype = [("", (self.dtype, (np.prod(shape[1:]), )))]
        total_number_of_frames = shape[0]
        video = np.fromiter(iterable, field_dtype, total_number_of_frames)
        # view the array as self.dtype to remove the field_dtype
        video = np.reshape(video.view(self.dtype), shape, order="C")

        return self.transform(video)