我正在尝试使用jupyter笔记本中的ipywidget来显示.tif图像。下面的代码适用于.png和.jpg文件
from ipywidgets import Image
png_image_path = r"C:\Users\xxxxxxxx\Work\Exercises\images\000000000.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中没有正确显示

发布于 2021-04-12 11:24:49
事实上,您只是在PNG图像上做file.read(),这意味着木星小部件需要一个PNG或JPEG编码的图像,其中包含头部和压缩的像素数据。
如果使用GDAL打开TIFF,您将有一个Numpy数组,因此在传递到木星小部件之前,需要将其编码到“内存中”PNG或JPEG中。您可以使用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依赖项及其奇怪的信道排序的替代方法,您可以使用使用常规RGB排序的PIL/Pillow。在这种情况下,可以将从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()另外,请注意,通常情况下,TIFFs可能包含不能用8位JPEG表示的浮点或float64值,因此您可能需要重新缩放数据以适应较小的范围。
https://stackoverflow.com/questions/67054987
复制相似问题