在 jupyter notebook 中显示 tif 文件 vie ipywidgets

Displaying tif files in jupyter notebook vie ipywidgets

我正在尝试使用 jupyter-notebooks 中的 ipywidgets 显示 .tif 图像。以下代码适用于 .png 和 .jpg 文件

from ipywidgets import Image
png_image_path = r"C:\Users\xxxxxxxx\Work\Exercises\images[=10=]0000000.png"
file = open(png_image_path, "rb")
im = file.read()

Image(
    value=im,
    width=300,
    height=400,
)

type(im) # <class 'bytes'>

上述代码中的 ipywidget 呈现了所需的图像。为了读取 tif 文件,我使用 gdal.

img = gdal.Open(tif_img_path).ReadAsArray()
print(img.shape) # (3, 1024, 1024)
print(img.transpose(1,2, 0).shape) # (1024, 1024, 3)

type(img.transpose(1,2,0).tobytes()) # <class 'bytes'>

Image(
    value=img.transpose(1,2,0).tobytes(),
    width=300,
    height=400,
)

我得到以下输出,图像在 ipywidget 中显示不正确

事实上,您只是对 PNG 图像执行 file.read() 这意味着 Jupyter 小部件需要 PNG 或 JPEG-encoded 图像,具有 header 和压缩像素数据。

如果你用 GDAL 打开你的 TIFF 你会得到一个 Numpy 数组,所以你需要在传递之前将它编码成 "in-memory" PNG 或 JPEG到 Jupyter 小部件。你可以用 OpenCV 这样做:

import cv2

# Open TIFF image into Numpy array
img = gdal.Open(tif_img_path).ReadAsArray()

# Encode into in-memory PNG for Jupyter
_, PNG = cv2.imencode('.png', img)

正如您在评论中正确指出的那样,OpenCV 使用 BGR 排序,因此您需要通过以下方式反转颜色通道的顺序:

RGBimage =  cv2.cvtColor(BGRimage, cv2.COLOR_BGR2RGB)

作为引入 OpenCV 依赖项及其怪异通道顺序的替代方法,您可以使用 PIL/Pillow,它使用常规RGB排序。在这种情况下,您将从 GDAL 获得的 Numpy 数组转换为 PNG 格式:

from io import BytesIO

im = ... read from GDAL ...

# Write Numpy array to in-memory PNG
membuf = BytesIO()
Image.fromarray(im).save(membuf, format="png") 

... you can now use membuf.getvalue()

另请注意,通常 TIFF 可能包含无法用 8 位 JPEG 表示的 float 或 float64 值,因此您可能需要 re-scale 您的数据以适应较小的范围。