예제 #1
0
파일: im_utils.py 프로젝트: manzt/wsireg
def tf_get_largest_series(image_filepath):
    """
    Determine largest series for .scn files by examining metadata
    For other multi-series files, find the one with the most pixels

    Parameters
    ----------
    image_filepath: str
        path to the image file

    Returns
    -------
    largest_series:int
        index of the largest series in the image data
    """
    fp_ext = Path(image_filepath).suffix.lower()
    tf_im = TiffFile(image_filepath)
    if fp_ext == ".scn":
        scn_meta = xml2dict(tf_im.scn_metadata)
        image_meta = scn_meta.get("scn").get("collection").get("image")
        largest_series = np.argmax([
            im.get("scanSettings").get("objectiveSettings").get("objective")
            for im in image_meta
        ])
    else:
        largest_series = np.argmax([
            np.prod(np.asarray(series.shape), dtype=np.int64)
            for series in tf_im.series
        ])
    return largest_series
예제 #2
0
def convert_nd2_to_ome_tiff(path, outpath):
    """
    Convert an nd2 file to an .ome.tif by saving each tile under a separate series.

    Uses the BigTIFF format to write the new .ome.tiff file.
    """

    path_to_nd2 = str(path)

    omexml = get_editable_omexml(path_to_nd2)
    limit = omexml.image_count

    xml_dict = tifffile.xml2dict(omexml.to_xml())
    with ND2Reader(path_to_nd2) as images:
        print(images.sizes)
        images.iter_axes = 'v'
        images.bundle_axes = "zcyx"
        with tifffile.TiffWriter(outpath, bigtiff=True) as tif:
            for series, tile in enumerate(images):
                # TODO: seems like, for some weird reason, the tiles are rotated incorrectly? Why?
                # Maybe it has to do with the order of the bundle axes

                rotated_tile = np.rot90(tile, k=1, axes=(2, 3))
                series_metadata = xml_dict["OME"]["Image"][series]
                tif.save(rotated_tile.astype(np.uint16),
                         contiguous=False,
                         metadata=series_metadata)
예제 #3
0
def ome_tifffile_to_arraylike(image_filepath):
    ome_metadata = xml2dict(TiffFile(image_filepath).ome_metadata)
    im_dims, im_dtype = get_tifffile_info(image_filepath)

    largest_series_idx = tf_get_largest_series(image_filepath)

    series_metadata = ome_metadata.get("OME").get("Image")

    if isinstance(series_metadata, list):
        series_metadata = series_metadata[largest_series_idx]

    if isinstance(series_metadata.get("Pixels").get("Channel"), list):
        samples_per_pixel = (series_metadata.get("Pixels").get("Channel")
                             [0].get("SamplesPerPixel"))
    else:
        samples_per_pixel = (series_metadata.get("Pixels").get("Channel").get(
            "SamplesPerPixel"))

    is_rgb = guess_rgb(im_dims)

    image = zarr.open(
        imread(image_filepath, aszarr=True, series=largest_series_idx))

    if isinstance(image, zarr.Group):
        image = image[0]

    image = da.from_zarr(image)
    if samples_per_pixel:
        if is_rgb is False and samples_per_pixel >= 3:
            image = image.transpose(1, 2, 0)

    return image, image_filepath
예제 #4
0
def test_ome_save(tmp_path, bundle_test_dir, ome_xml, z_size):
    data = np.zeros((z_size, 20, 20, 2), dtype=np.uint8)
    image = Image(
        data,
        image_spacing=(27 * 10 ** -6, 6 * 10 ** -6, 6 * 10 ** -6),
        axes_order="ZYXC",
        channel_names=["a", "b"],
        shift=(10, 9, 8),
        name="Test",
    )
    ImageWriter.save(image, tmp_path / "test.tif")

    with tifffile.TiffFile(tmp_path / "test.tif") as tiff:
        assert tiff.is_ome
        assert isinstance(tiff.ome_metadata, str)
        meta_data = tifffile.xml2dict(tiff.ome_metadata)["OME"]["Image"]
        assert "PhysicalSizeX" in meta_data["Pixels"]
        assert meta_data["Pixels"]["PhysicalSizeX"] == 6
        assert "PhysicalSizeXUnit" in meta_data["Pixels"]
        assert meta_data["Pixels"]["PhysicalSizeXUnit"] == "µm"
        assert len(meta_data["Pixels"]["Channel"]) == 2
        assert meta_data["Pixels"]["Channel"][0]["Name"] == "a"
        assert meta_data["Pixels"]["Channel"][1]["Name"] == "b"
        assert meta_data["Name"] == "Test"
        xml_file = etree.fromstring(tiff.ome_metadata.encode("utf8"))  # nosec
        ome_xml.assert_(xml_file)
    read_image = TiffImageReader.read_image(tmp_path / "test.tif")
    assert np.allclose(read_image.spacing, image.spacing)
    assert np.allclose(read_image.shift, image.shift)
    assert read_image.channel_names == ["a", "b"]
    assert read_image.name == "Test"
예제 #5
0
def test_xml2dict():
    sample_text = """
    <level1>
        <level2>3.5322</level2>
    </level1>
    """
    data = tifffile.xml2dict(sample_text)
    assert math.isclose(data["level1"]["level2"], 3.5322)
예제 #6
0
 def metadata(self, raw=False):
     """Read metadata from file and return as dict (default) or XML."""
     if self.metadata_size <= 0:
         return u'' if raw else None
     fh = self._fh
     with fh.lock:
         fh.seek(self.data_offset - self.metadata_size)
         metadata = fh.read(self.metadata_size)
     if raw:
         return unicode(metadata, 'utf-8')
     try:
         return xml2dict(metadata)['METADATA']
     except Exception:
         return unicode(metadata, 'utf-8')
예제 #7
0
def parse_dispim_meta(impath):
    # parse TiffFile.ome_metadata to extract diSPIM info
    with tf.TiffFile(impath) as t:
        meta = t.ome_metadata
        # tifffile version > 2019.2.22
        if isinstance(meta, str):
            meta = tf.xml2dict(meta)["OME"]
    im0 = meta["Image"][0] if isinstance(meta["Image"],
                                         list) else meta["Image"]
    out = {"channels": [], "nS": len(meta["Image"])}
    for x in "XYZCT":
        out["n" + x] = im0["Pixels"]["Size" + x]
    for x in "XYZ":
        out["d" + x] = im0["Pixels"]["PhysicalSize" + x]
    for chan in im0["Pixels"]["Channel"]:
        out["channels"].append(chan["Name"])
    out["dzRatio"] = out["dZ"] / out["dX"]
    return out
예제 #8
0
    def __init__(
        self,
        image_fp,
        image_res,
        mask=None,
        pre_reg_transforms=None,
        preprocessing=None,
        channel_names=None,
        channel_colors=None,
    ):
        self.image_filepath = image_fp
        self.image_res = image_res
        self.image = None
        self.tf = TiffFile(self.image_filepath)
        self.reader = "tifffile"

        self.ome_metadata = xml2dict(self.tf.ome_metadata)

        (
            self.im_dims,
            self.im_dtype,
        ) = self._get_image_info()

        self.im_dims = tuple(self.im_dims)

        # self.n_ch = self.im_dims[2] if self.is_rgb else self.im_dims[0]
        self.mask = self.read_mask(mask)

        if preprocessing is None:
            self.preprocessing = std_prepro()
        else:
            self.preprocessing = std_prepro()
            self.preprocessing.update(preprocessing)

        self.pre_reg_transforms = pre_reg_transforms

        self.channel_names = channel_names
        self.channel_colors = channel_colors
        self.original_size_transform = None
예제 #9
0
def slice_ome_tiff(input_filepath,
                   output_filepath,
                   start,
                   end,
                   use_bigtiff=False):
    """
    Build a new .ome.tiff with only the series that fall in the range start:end included (+ metadata).
    """
    # TODO: Add an IndexError or whatever later

    input_ome_tiff = tifffile.TiffFile(input_filepath)

    xml = input_ome_tiff.ome_metadata
    xml_dict = tifffile.xml2dict(xml)

    print(input_filepath)
    with tifffile.TiffWriter(output_filepath, bigtiff=use_bigtiff) as tif:
        for index in range(start, end):
            print(index)
            tile = input_ome_tiff.series[index].asarray()
            tile_metadata = xml_dict["OME"]["Image"][index]
            tif.save(tile.astype(np.uint16),
                     contiguous=False,
                     metadata=tile_metadata)
예제 #10
0
 def data(self, raw=True):
     """Read metadata from file and return as XML (default) or dict."""
     self._fh.seek(self.xml_offset)
     xml = self._fh.read(self.xml_size)
     xml = xml.replace(b'\r\n', b'\n').replace(b'\r', b'\n')  # ???
     return unicode(xml, 'utf-8') if raw else xml2dict(xml)
예제 #11
0
def read_xml(fh, filesize, raw=True):
    """Read XML from file and return as unicode string (default) or dict."""
    xml = stripnull(fh.read(filesize))
    return unicode(xml, 'utf-8') if raw else xml2dict(xml)
예제 #12
0
def find_ome_magnification(ome_xml):
    metadata = tifffile.xml2dict(ome_xml)