未验证 提交 881c1aa5 编写于 作者: M Michael Fujarski 提交者: GitHub

Loading 16-bit tiff images (#5005)

Pull Request regarding Issue #2987 

PIL.Image conversion from I;16 to L or RGB are unsuccessful as for now.
See the corresponding Issue in the Pillow GitHub (Opened 2018, so no
changes to be expected)
https://github.com/python-pillow/Pillow/issues/3011

The proposed changes at least fix this issue for the mode 'I;16' and
delivers a possible solution for other modes (eg. I;16B/L/N).

This results in a correct calculation of the preview thumbnail and the
actual image, the annotation will be performed on.

We have used this solution on our own dataset and created annotations
accordingly.
上级 6bcc8219
......@@ -83,6 +83,7 @@ from online detectors & interactors) (<https://github.com/opencv/cvat/pull/4543>
non-ascii paths while adding files from "Connected file share" (issue #4428)
- Removed unnecessary volumes defined in docker-compose.serverless.yml
(<https://github.com/openvinotoolkit/cvat/pull/4659>)
- Added support for Image files that use the PIL.Image.mode 'I;16'
- Project import/export with skeletons (<https://github.com/opencv/cvat/pull/4867>,
<https://github.com/opencv/cvat/pull/5004>)
- Shape color is not changed on canvas after changing a label (<https://github.com/opencv/cvat/pull/5045>)
......
......@@ -17,7 +17,7 @@ import av
import numpy as np
from natsort import os_sorted
from pyunpack import Archive
from PIL import Image, ImageFile
from PIL import Image, ImageFile, ImageOps
from random import shuffle
from cvat.apps.engine.utils import rotate_image
from cvat.apps.engine.models import DimensionType, SortingMethod
......@@ -127,9 +127,25 @@ class IMediaReader(ABC):
else:
preview = obj
preview = rotate_within_exif(preview)
# TODO - Check if the other formats work. I'm only interested in I;16 for now. Sorry @:-|
# Summary:
# Images in the Format I;16 definitely don't work. Most likely I;16B/L/N won't work as well.
# Simple Conversion from I;16 to I/RGB/L doesn't work as well.
# Including any Intermediate Conversions doesn't work either. (eg. I;16 to I to L)
# Seems like an internal Bug of PIL
# See Issue for further details: https://github.com/python-pillow/Pillow/issues/3011
# Issue was opened 2018, so don't expect any changes soon and work with manual conversions.
mode: str = preview.mode
if mode == "I;16":
preview = np.array(preview, dtype=np.uint16) # 'I;16' := Unsigned Integer 16, Grayscale
image = image - image.min() # In case the used range lies in [a, 2^16] with a > 0
preview = preview / preview.max() * 255 # Downscale into real numbers of range [0, 255]
preview = preview.astype(np.uint8) # Floor to integers of range [0, 255]
preview = Image.fromarray(preview, mode="L") # 'L' := Unsigned Integer 8, Grayscale
preview = ImageOps.equalize(preview) # The Images need equalization. High resolution with 16-bit but only small range that actually contains information
preview.thumbnail(PREVIEW_SIZE)
return preview.convert('RGB')
return preview
@abstractmethod
def get_image_size(self, i):
......@@ -589,6 +605,23 @@ class IChunkWriter(ABC):
im_data = np.array(image)
im_data = im_data * (2**8 / im_data.max())
image = Image.fromarray(im_data.astype(np.int32))
# TODO - Check if the other formats work. I'm only interested in I;16 for now. Sorry @:-|
# Summary:
# Images in the Format I;16 definitely don't work. Most likely I;16B/L/N won't work as well.
# Simple Conversion from I;16 to I/RGB/L doesn't work as well.
# Including any Intermediate Conversions doesn't work either. (eg. I;16 to I to L)
# Seems like an internal Bug of PIL
# See Issue for further details: https://github.com/python-pillow/Pillow/issues/3011
# Issue was opened 2018, so don't expect any changes soon and work with manual conversions.
if image.mode == "I;16":
image = np.array(image, dtype=np.uint16) # 'I;16' := Unsigned Integer 16, Grayscale
image = image - image.min() # In case the used range lies in [a, 2^16] with a > 0
image = image / image.max() * 255 # Downscale into real numbers of range [0, 255]
image = image.astype(np.uint8) # Floor to integers of range [0, 255]
image = Image.fromarray(image, mode="L") # 'L' := Unsigned Integer 8, Grayscale
image = ImageOps.equalize(image) # The Images need equalization. High resolution with 16-bit but only small range that actually contains information
converted_image = image.convert('RGB')
image.close()
buf = io.BytesIO()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册