libvips / pyvips

python binding for libvips using cffi
MIT License
650 stars 50 forks source link

How to get the mpp of the tif file created by pyvips.write_to_file function #164

Open vankhoa21991 opened 4 years ago

vankhoa21991 commented 4 years ago

Hello,

Can we have the possibility to get the mpp of the tif file created by the pyvips.write_to_file function?

jcupitt commented 4 years ago

Hello @vankhoa21991, could you explain what MPP is?

vankhoa21991 commented 4 years ago

It's micrometers/pixel, as the size of one pixel

jcupitt commented 4 years ago

Ah OK -- you can get xres and yres, which are in pixels / mm.

jcupitt commented 4 years ago

Oh, or do you want to write a TIFF file with a specific resolution?

vankhoa21991 commented 4 years ago

We have a function for that? It would be great

jcupitt commented 4 years ago

You can do:

image.write_to_file("x.tif", xres=1000, yres=1000)

And it'll set the res to that many pixels per millimetre. You can also set the xres/yres metadata items and it'll use those.

vankhoa21991 commented 4 years ago

I read an svs image using both openslide and pyvips, and then the property aperio.MPP from openslide gives me 0.2522 mpp, and the xres, and yres from pyvips give me 1 for both.

For pyvips, I read the image with the new_from_file function.

How I can understand this?

jcupitt commented 4 years ago

Ah I didn't realize you were working with slide images.

Yes, libvips openslideload does not read the openslide resolution fields, perhaps it should.

You can handle it yourself in the meantime, something like:

#!/usr/bin/python3

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1], access="sequential")

mpp_x = float(image.get("openslide.mpp-x"))
mpp_y = float(image.get("openslide.mpp-y"))

# that's microns per pixel, convert to pixels per mm
xres = 100.0 / mpp_x
yres = 100.0 / mpp_x

image.write_to_file(sys.argv[2], xres=xres, yres=yres)

Then:

./res.py ~/pics/openslide/CMU-1.svs x.tif[tile,pyramid,compression=jpeg]

Making:

$ tiffinfo x.tif 
TIFF Directory at offset 0x58da386 (93168518)
  Image Width: 46000 Image Length: 32914
  Tile Width: 128 Tile Length: 128
  Resolution: 2004.01, 2004.01 pixels/cm
  Bits/Sample: 8
...
vankhoa21991 commented 4 years ago

Thanks for your help, with the command you suggest above:

image.write_to_file("x.tif", xres=1000, yres=1000)

Is there anyway we can check the mpp of the output x.tif file, because all the metadata is gone, and we can not check it again with mpp_x = float(image.get("openslide.mpp-x"))

jcupitt commented 4 years ago

Sure, run tiffinfo on a tiff file to see a dump of all the metadata.

If you write a file with properties=True, libvips will add a lot of XML to the IMAGEDESCRIPTION tag, including all the openslide fields.

vankhoa21991 commented 4 years ago

Great, you helped me alot, thanks.

zhangguy commented 2 months ago
# that's microns per pixel, convert to pixels per mm
xres = 100.0 / mpp_x
yres = 100.0 / mpp_x

@jcupitt Hi, I might be wrong, but shouldn't it be

> xres = 1000.0 / mpp_x
> yres = 1000.0 / mpp_x

since 1 mm = 1000 micron?

jcupitt commented 2 months ago

Ooooop! You're quite right, thank you.