(Live)使用pyvips查看大图像



我最近发现了很棒的pyvips包,并想用它来分析在自制幻灯片扫描仪(不是我自己构建的)上获取的数据。我沿着一个方形样本的边缘扫描了大约4000个1024x1024像素的贴图(样本的中心部分没有被记录)。所有磁贴都保存为单个二进制文件。我已经编写了一个python类,它从二进制文件返回所需的瓷砖作为numpy数组,并且还给出了特定瓷砖的(x, y)坐标。不幸的是,瓷砖没有排列在网格上。

我首先确定整个图像的总宽度和高度,并初始化一个正确大小的黑色图像,然后使用insert函数将瓦片放置在正确的位置。合成图像约为120k x 120k像素,但大部分图像是空的。最后,我使用matplotlib绘制结果图像。

import pyvips
import numpy as np
import matplotlib.pyplot as plt
# class to read tiles from data file
sr = TileReader("path_to_scan_file")
# some stuff to determine the width and height of the total image...
# create empty image for inserting tiles
im = pyvips.Image.black(width, height)
# loop over all tiles and place tile at correct position
for i in range(sr.num_tiles()):
frame, coord = sr.ReadFrame(i)
tile = pyvips.Image.new_from_array(frame)
im = im.insert(tile, coord[0], coord[1])
# plot result
plt.imshow(im.numpy())
plt.show()
# save file
im.write_to_file('full_image.tiff')

在循环中生成完整的图像似乎非常快。然而,绘制或保存数据不是。(显然,)绘图只适用于一小部分贴图(~10)。我还试着将数据保存到一个金字塔tiff中。但是,写入映像需要几个小时,并且生成的文件似乎已损坏或太大而无法打开。不幸的是,如果没有管理员权限,我无法安装nip2。

我希望能够手动选择我可以用于进一步处理的合成图像的感兴趣的区域。与生成的图像交互以实现此功能的最佳/最快方式是什么?

您可以使用crop剪切出图像的大块并将其传递给其他内容。它不会渲染整个东西,它只会渲染你需要的部分,所以它会很快。

类似:

# loop over all tiles and place at correct position
# do this once on startup
for i in range(sr.num_tiles()):
frame, coord = sr.ReadFrame(i)
tile = pyvips.Image.new_from_array(frame)
im = im.insert(tile, coord[0], coord[1])
# left, top, width, height
# hook these numbers up to eg. a scrollbar
# do the crop again for each scrollbar movement
tile = im.crop(0, 0, 1000, 1000)
# plot result
plt.imshow(tile.numpy())
plt.show()

如果你想花哨一点,最好的解决方案可能是vips_sink_screen():

https://www.libvips.org/API/current/libvips-generate.html vips-sink-screen

这将允许您在平移和缩放时从任何管道异步生成像素,但遗憾的是它需要C。这里有一个使用此API的示例图像查看器:

https://github.com/jcupitt/vipsdisp

在后台运行vips_sink_screen()以生成各种比例的GPU纹理,然后使用该纹理集以60 fps (ish)的速度绘制屏幕,当您平移和缩放时。它可以非常快速地显示巨大的动态计算图像。

最新更新