Я не покупаю ни минуты, чтобы произошла ошибка округления или какая-то ошибка, связанная с декодированием JPEG, как предполагает связанная статья.
Во-первых, потому что ваше изображение является целым числом, в частности uint8
, поэтому нет округления с плавающей запятой, и, во-вторых, потому что сжатие вашего изображения TIF не является JPEG - на самом деле сжатия нет.Вы можете убедиться в этом сами, если вы используете ImageMagick и делаете:
identify -verbose a.tif
или если вы используете tiffinfo
, который поставляется с libtiff
, например:
tiffinfo -v a.tif
Итак, я провел несколько экспериментов, сгенерировав образцы изображений с ImageMagick следующим образом:
# Make 8x8 pixel TIF full of RGBA(64,128,192) with full opacity
convert -depth 8 -size 8x8 xc:"rgba(64,128,192,1)" a.tif
# Make 8x8 pixel TIFF with 4 rows per strip
convert -depth 8 -define tiff:rows-per-strip=4 -size 8x8 xc:"rgba(64,128,192,1)" a.tif
И OpenCV смог прочитать все эти данные правильно,однако, когда я сделал следующее, все пошло не так.
# Make 8x8 pixel TIFF with RGB(64,128,192) with 50% opacity
convert -depth 8 -define tiff:rows-per-strip=1 -size 8x8 xc:"rgba(64,128,192,0.5)" a.tif
И значения вышли в OpenCV как 32, 64, 96 - да, точно ПОЛОВИНА правильные значения - как OpenCV предварительно умножает альфа.Поэтому я попытался с непрозрачностью 25%, и значения вышли на 1/4 от правильных.Итак, я подозреваю, что есть ошибка в OpenCV , которая предварительно умножает альфа.
Если вы посмотрите на свои значения, вы увидите, что tifffile
и skimage
читают первый пиксель как:
[ 79 88 70 182 ]
если вы посмотрите на альфа этого пикселя, это 0,713725 (182/255), и если вы умножите каждое из этих значений на это, вы получите:
[ 50 63 56 182 ]
Это именно то, что OpenCV сделал.
В качестве обходного пути, я думаю, вы могли бы разделить на альфа для правильного масштабирования.
В случае, еслиаргумент в том, что OpenCV преднамеренно предварительно умножает альфа, тогда возникает вопрос, почему он делает это для файлов TIFF, но НЕ для файлов PNG:
# Create 8x8 PNG image full of rgb(64,128,192) with alpha=0.5
convert -depth 8 size 8x8 xc:"rgba(64,128,192,0.5)" a.png
Проверка с помощью OpenCV:
import cv2
c = cv2.imread('a.png',cv2.IMREAD_UNCHANGED)
In [4]: c.shape
Out[4]: (8, 8, 4)
In [5]: c
Out[5]:
array([[[192, 128, 64, 128],
[192, 128, 64, 128],
...
...
В случае, если кто-то думает, что значения в файле TIF как OpenCV сообщает о них, я могу только сказать, что я написал rgb (64,128,192) с прозрачностью 50%, и япроверил каждое из следующего и обнаружил, что они все согласны , с единственным исключением OpenCV - это именно то, что содержится в файле:
- ImageMagick v7
- libvips v8
- Adobe Photoshop CC 2017
- PIL/ Подушка v5.2.0
- GIMP v2.8
- scikit-image v0.14