【问题标题】:Display TIFF Image On Juypyter Notebook using Python Without Saving / Downloading使用 Python 在 Jupyter Notebook 上显示 TIFF 图像而不保存/下载
【发布时间】:2017-02-28 16:42:45
【问题描述】:

我正在使用 Web 服务,使用请求根据传递的参数获取图像。我得到的第一个响应是带有文件参考 URL 的 XML 模式。

<?xml version="1.0"?>
<Coverages schemaLocation="http://localhost/server/schemas/wcs/1.1.1/wcsCoverages.xsd">
<Coverage>
    <Title>Filename</Title>
    <Abstract/>
    <Identifier>Filename</Identifier>
    <Reference href="http://localhost/server/temp/filename.tif"/>
</Coverage>
</Coverages>

接下来使用xml.etree.ElementTree 提取URL。接下来,我需要在 Jupyter Notebook 上播放该 tiff 图像(或任何其他图像),而无需下载(因为一个图像有时可能超过 50 或 100 MB)

目前我正在下载并在读取文件数据并将其转换为数组(作为 pyplot 绘图图像数组/矩阵)后绘制文件。

import requests as req # request wcs urls
import xml.etree.ElementTree as ET # used for xml parsing
import matplotlib.pyplot as plt # display image
import gdal

# Download the File to local directory using Chunks 
    chunk_size=1024
    local_filename = url.split('/')[-1] # Filename from url
    r = req.get(url, stream=True)
    with open(local_filename, 'wb') as f:
        for chunk in r.iter_content(chunk_size): 
            if chunk:
                f.write(chunk)

    # Read File Raster Data as Array using Gdal
    gtif = gdal.Open(local_filename)
    georaster = gtif.ReadAsArray()

    # Plot image using matplotlib
    plt.imshow(georaster)
    plt.title(local_filename)
    plt.show()

那么有什么方法可以将来自请求 API 的原始响应文件直接转换为图像数组(以块或整体)并显示在笔记本上(无需下载并占用本地目录空间)

获取 tiff 文件的原始响应如下

resp2 = req.get('tiffFielurl')
rawdata = resp2.content
rawdata[0:10]

Output: b'MM\x00*\x00\x00\x00\x08\x00\x10'

我尝试搜索这个问题,但没有找到任何好的答案,所以如果有任何相关问题或重复,请提供链接。

【问题讨论】:

  • 您可以使用 Matplotlib 显示远程图像,如类似 StackOverflow 问题中所述:How to plot remote image (from http url)
  • @Brian 似乎您给出的链接中提到的解决方案仅使用“PNG”文件,我尝试请求 TIFF 文件并收到以下错误。 " ValueError: 无效的 PNG 标头 "
  • 实际上,在尝试了多种不同的方法之后,我无法从 url 中找到任何与 tiff 文件配合良好的东西(至少在我手中)。您可以尝试使用 io.BytesIO 或 np.fromstring 或 np.frombuffer。如果不了解更多关于您的图像数据(预期数据类型和大小)以及访问我可以重现的示例,我将无法进一步帮助您。祝你好运,如果你找到任何有效的方法,请告诉我。

标签: python matplotlib httprequest jupyter-notebook tiff


【解决方案1】:

您可以尝试使用ipyplot 包绘制 tiff 图像

import ipyplot

ipyplot.plot_images(
    ['https://file-examples.com/wp-content/uploads/2017/10/file_example_TIFF_1MB.tiff',
    'https://file-examples.com/wp-content/uploads/2017/10/file_example_TIFF_1MB.tiff',
    'https://file-examples.com/wp-content/uploads/2017/10/file_example_TIFF_1MB.tiff'],
    img_width=250)

【讨论】:

    【解决方案2】:

    在做了这么多研究并尝试了不同的解决方案之后,在我看来,执行上述过程的唯一方法,即现在显示 Tiff 文件是 使用 gdal 下载和读取数据并转换为数组并使用 matplotlib 显示 .

    由于以下链接中提到的解决方案只接受“PNG”文件。

    How to plot remote image (from http url)

    得出的结论是,我们需要我也尝试过但失败的 PIL 库。

    from PIL import Image
    resp2 = req.get('tiffFielurl')
    resp2.raw.decode_content = True
    im = Image.open(resp2.raw)
    im
    

    给出输出:

    <PIL.TiffImagePlugin.TiffImageFile image mode=I;16BS size=4800x4800 at 0x11CB7C50>
    

    将 PIL 对象转换为 numpy 数组,甚至从 PIL 对象获取数据或像素都会导致无法识别的模式错误。

    im.getdata()
    im.getpixels((0,0))
    numpy.array(im)
    

    所有错误都相同

        257         if not self.im or\
        258            self.im.mode != self.mode or self.im.size != self.size:
    --> 259             self.im = Image.core.new(self.mode, self.size)
        260         # create palette (optional)
        261         if self.mode == "P":
    
    ValueError: unrecognized mode
    

    PIL 甚至不支持上面 PIL 的 Tiff 对象中定义的 16 位有符号整数像素。

    https://pillow.readthedocs.io/en/4.0.x/handbook/concepts.html#concept-modes

    【讨论】:

      猜你喜欢
      • 2023-01-16
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2020-09-21
      相关资源
      最近更新 更多