I am deskewing a tiff-image with the python lib "skimage" and try to save it back to disk. But I can not save an image with the call "skimage.io.imsave". It does not work. No errors are shown. It just write an 123.7 MB tiff-file with transparent background. If I show the rotated tiff image with skimage.io.show(), it shows me my desired result, but I can not save it.
Steps to reproduce:
Here is an small code example to reproduce it:
import skimage
def main():
print("Start main")
src_img_path = '/path/to/test.tiff'
dst_img_path = '/path/to/test_rotated.tiff'
sk_img = skimage.io.imread(src_img_path)
# skimage.io.imshow(sk_img)
# skimage.io.show()
tmp_rotated_skimage = skimage.transform.rotate(image=sk_img, angle=10)
# skimage.io.imshow(tmp_rotated_skimage)
# skimage.io.show()
skimage.io.imsave(dst_img_path, tmp_rotated_skimage)
### start program
main()
If I just save my readed tiff file without changing (rotating) it the filesize grows from 3.3 MB to 15.5 MB. Tried this short code and my other code also with an jpg and png file. Reading, showing and rotating works fine, but when I try to save them -> "TypeError: Cannot handle this data type: (1, 1, 3), <f8".
I check all build and run requirements from the scikit-image.org homepage [1] [1] https://scikit-image.org/docs/stable/user_guide/install.html#scientific-python-distributions
My OS is Arch (Kernel Linux 6.4.1-arch2-1 x86_64) and here are all version from the requirements list I got from pacman or yay
$ pacman -Q python-scikit-image
python-scikit-image 0.21.0-1
Build requirements from homepage ----- my versions
meson-python >=0.13 ----- meson-python 0.13.2-1
wheel ----- python-wheel 0.40.0-3
setuptools >=67 ----- python-setuptools 1:68.0.0-1
packaging >=21 ----- python-packaging 23.1-1
ninja ----- ninja 1.11.1-3
Cython >=0.29.32 ----- cython 0.29.36-1
pythran ----- python-pythran 0.13.1-2
numpy >=1.21.1 ----- python-numpy 1.25.0-1
Runtime requirements from homepage ----- my versions
numpy >=1.21.1 ----- python-numpy 1.25.0-1
scipy >=1.8 ----- python-scipy 1.11.1-1
networkx >=2.8 ----- python-networkx 3.1-1
pillow >=9.0.1 ----- python-pillow 10.0.0-1
imageio >=2.27 ----- python-imageio 2.31.1-1
tifffile >=2022.8.12 ----- python-tifffile 2023.7.4-1
PyWavelets >=1.1.1 ----- python-pywavelets 1.4.1-1
packaging >=21 ----- python-packaging 23.1-1
lazy_loader >=0.2 ----- python-lazy-loader 0.3-1
During installation some tests failed.
Successfully built scikit_image-0.21.0-cp311-cp311-linux_x86_64.whl
==> Starting check()...
dist/lib/skimage/exposure/tests/test_exposure.py ...............F.............
dist/lib/skimage/measure/tests/test_fit.py ...............F.............
dist/lib/skimage/measure/tests/test_moments.py ...............F.............
========== short test summary info ==========
FAILED dist/lib/skimage/exposure/tests/test_exposure.py::test_rescale_nan_warning[image-dtype] - ValueError: No warning raised matching:
FAILED dist/lib/skimage/measure/tests/test_fit.py::test_ellipse_parameter_stability - AssertionError:
FAILED dist/lib/skimage/measure/tests/test_moments.py::test_analytical_moments_calculation[3-1-float32] - assert 0.000110473855 < 0.0001
========== 3 failed, 7691 passed, 12 skipped, 63 deselected, 6 warnings in 191.23s (0:03:11) ==========
Would be grateful for any hint. Thanks.
Thank you Mark for the hint with the tifffile
library. ChatCPT pushed me also in the right direction. For me worked the data_type = 'uint8'
and one need to use preserve_range=True
and save it with tifffile.imwrite
.
Here is a small code example that works.
import skimage.io as io
from skimage.transform import rotate
import tifffile
# Path to input and output files
input_file = '/path/to/input.tiff'
output_file = '/path/to/output.tiff'
# Load the input image
image = io.imread(input_file)
# Rotate the image by x degrees clockwise
rotated_image = rotate(image=image, angle=10, preserve_range=True)
# Define a list of data types to attempt
data_types = ['uint8', 'uint16', 'float']
# Convert the data type of the rotated image to a data_type
rotated_image = rotated_image.astype('uint8')
# io.imshow(rotated_image)
# io.show()
# Save the rotated image as a TIFF file
tifffile.imwrite(output_file, rotated_image)