Search code examples
pythonscikit-image

skimage.io.imsave is executed with empty file but without error


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:

  • read image, rotate image, save image

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.


Solution

  • 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)