示例#1
0
def add_image(image: omero.gateway.ImageWrapper,
              parent: Group,
              cache_dir: Optional[str] = None) -> int:
    """ Adds the image pixel data as array to the given parent zarr group.
        Optionally caches the pixel data in the given cache_dir directory.
        Returns the number of resolution levels generated for the image.
    """
    if cache_dir is not None:
        cache = True
        os.makedirs(os.path.join(cache_dir, str(image.id)),
                    mode=511,
                    exist_ok=True)
    else:
        cache = False
        cache_dir = ""

    size_c = image.getSizeC()
    size_z = image.getSizeZ()
    size_x = image.getSizeX()
    size_y = image.getSizeY()
    size_t = image.getSizeT()
    d_type = image.getPixelsType()

    zct_list = []
    for t in range(size_t):
        for c in range(size_c):
            for z in range(size_z):
                if cache:
                    # We only want to load from server if not cached locally
                    filename = os.path.join(
                        cache_dir,
                        str(image.id),
                        f"{z:03d}-{c:03d}-{t:03d}.npy",
                    )
                    if not os.path.exists(filename):
                        zct_list.append((z, c, t))
                else:
                    zct_list.append((z, c, t))

    pixels = image.getPrimaryPixels()

    def planeGen() -> np.ndarray:
        planes = pixels.getPlanes(zct_list)
        yield from planes

    planes = planeGen()

    # Target size for smallest multiresolution
    TARGET_SIZE = 96
    level_count = 1
    longest = max(size_x, size_y)
    while longest > TARGET_SIZE:
        longest = longest // 2
        level_count += 1

    field_groups = []
    for t in range(size_t):
        for c in range(size_c):
            for z in range(size_z):
                if cache:
                    filename = os.path.join(
                        cache_dir,
                        str(image.id),
                        f"{z:03d}-{c:03d}-{t:03d}.npy",
                    )
                    if os.path.exists(filename):
                        plane = numpy.load(filename)
                    else:
                        plane = next(planes)
                        numpy.save(filename, plane)
                else:
                    plane = next(planes)
                for level in range(level_count):
                    size_y = plane.shape[0]
                    size_x = plane.shape[1]
                    # If on first plane, create a new group for this resolution level
                    if t == 0 and c == 0 and z == 0:
                        field_groups.append(
                            parent.create(
                                str(level),
                                shape=(size_t, size_c, size_z, size_y, size_x),
                                chunks=(1, 1, 1, size_y, size_x),
                                dtype=d_type,
                            ))

                    # field_group = field_groups[level]
                    field_groups[level][t, c, z, :, :] = plane

                    if (level + 1) < level_count:
                        # resize for next level...
                        plane = cv2.resize(
                            plane,
                            dsize=(size_x // 2, size_y // 2),
                            interpolation=cv2.INTER_NEAREST,
                        )
    return level_count
示例#2
0
def add_raw_image(
    *,
    planes: Iterator[np.ndarray],
    size_z: int,
    size_c: int,
    size_t: int,
    d_type: np.dtype,
    parent: Group,
    level_count: int,
    cache_dir: Optional[str] = None,
    cache_file_name_func: Callable[[int, int, int], str] = None,
) -> Tuple[int, List[str]]:
    """Adds the raw image pixel data as array to the given parent zarr group.
    Optionally caches the pixel data in the given cache_dir directory.
    Returns the number of resolution levels generated for the image.

    planes: Generator returning planes in order of zct (whatever order
            OMERO returns in its plane generator). Each plane must be a
            numpy array with shape (size_y, sizex), or None to skip the
            plane.
    """

    if cache_dir is not None:
        cache = True
    else:
        cache = False
        cache_dir = ""

    dims = [dim for dim in [size_t, size_c, size_z] if dim != 1]
    axes = []
    if size_t > 1:
        axes.append("t")
    if size_c > 1:
        axes.append("c")
    if size_z > 1:
        axes.append("z")

    field_groups: List[Array] = []
    for t in range(size_t):
        for c in range(size_c):
            for z in range(size_z):
                if cache:
                    assert cache_file_name_func
                    filename = cache_file_name_func(z, c, t)
                    if os.path.exists(filename):
                        plane = numpy.load(filename)
                    else:
                        plane = next(planes)
                        os.makedirs(os.path.dirname(filename),
                                    mode=511,
                                    exist_ok=True)
                        numpy.save(filename, plane)
                else:
                    plane = next(planes)
                if plane is None:
                    continue
                for level in range(level_count):
                    size_y = plane.shape[0]
                    size_x = plane.shape[1]
                    # If on first plane, create a new group for this resolution level
                    if len(field_groups) <= level:
                        field_groups.append(
                            parent.create(
                                str(level),
                                shape=tuple(dims + [size_y, size_x]),
                                chunks=tuple([1] * len(dims) +
                                             [size_y, size_x]),
                                dtype=d_type,
                            ))

                    indices = []
                    if size_t > 1:
                        indices.append(t)
                    if size_c > 1:
                        indices.append(c)
                    if size_z > 1:
                        indices.append(z)

                    field_groups[level][tuple(indices)] = plane

                    if (level + 1) < level_count:
                        # resize for next level...
                        plane = cv2.resize(
                            plane,
                            dsize=(size_x // 2, size_y // 2),
                            interpolation=cv2.INTER_NEAREST,
                        )
    return (level_count, axes + ["y", "x"])