【问题标题】:how to convert dzi files to multi-tile pyramidal tiff format如何将 dzi 文件转换为多瓦锥体 tiff 格式
【发布时间】:2019-11-15 09:36:10
【问题描述】:

参考答案(how to convert dzi (deep zoom) files to full image

我是这个话题的菜鸟,如果我错了,请纠正。

我正在尝试从 .dzi(深度缩放图像)格式创建多平铺 tiff,我的做法是:

(i) 选择最高级别的文件夹。

(ii) 将m行的n列(m_n.jpeg,我指的是以这种格式保存的图像)全部垂直拼接为png图像。所以它们占据了相当大的空间。

(iii) 最后,我使用 pyvips.Image.write_to_file() 将所有这些垂直的 png 图像水平合并为一个完整的图像 png。

(iv) 最后使用vips im_save,我将全图png转为tiff。

我现在担心的是,这个过程需要将近 2 个小时才能为 30,000 个 base_tiles 制作完整的图像 png,而且它还占 10+ GB 的大小(完整图像 png)。

有没有更好更快的方法来进行 .dzi 到 tiff 的转换?

【问题讨论】:

  • 是的,这似乎是基本做法。您是否将每个中间合并保存为文件?我想如果可以的话,在内存中完成这一切会更有效率。我不确定哪种工具最适合(看起来您正在使用 VIPS ......也许他们有批处理操作的技术)。顺便说一句,如果您的图块一侧大约有 256 个像素,并且最大级别有 30,000 个,那将是一个侧面大约有 44,000 个像素的图像,也就是大约 20 亿像素。我不知道你得到了多少压缩,但 10GB 似乎是合理的。
  • 嗨 iangilman,谢谢你的想法,我所有的图像都是 512x512,最后的合并都是使用 pyvips 在内存中进行的,但是这个转换总共需要大约 2 个小时才能写出图像到磁盘,这有点太花时间了,有没有更好的方法?
  • 我真的不知道,但看起来你从 jcupitt 那里得到了一些很好的帮助!

标签: imagemagick tiff deepzoom openseadragon openslide


【解决方案1】:

libvips 有一个 arrayjoin 运算符,可以将一组图块连接到一个大图像中。

你可以像这样使用它(在 linux 命令行上):

vips arrayjoin "$(ls *.jpeg | sort -t_ -k2g -k1g)" x.tif[tile,pyramid,compression=jpeg] --across 20

这将加载当前目录中的所有 JPG 图像,将它们组合成一个巨大的网格,包含 20 张图像,并写入 TIFF 金字塔。显然,您需要检查网格的大小,并调整 across 参数。

$() 部分将x_y.jpg 形式的文件名按数字顺序先按 y 排序,然后按 x 排序。没有它,瓷砖会被调换,很烦人。

假设重叠为 0。如果您的图块有重叠,您需要设置 hspacingvspacing 选项来控制图块的定位方式。例如:

vips arrayjoin "$(ls *.jpg | sort -t_ -k2g -k1g)" x.tif --across 20 --hspacing 254 --vspacing 254

将每 254 个像素水平和垂直放置图块。

arrayjoin 必须能够打开所有输入图像,因此它需要大量文件描述符。大多数 linux 默认每个进程一次最多打开 1024 个文件,因此您可能需要提高该数量。通常您只需编辑几个配置文件并注销并再次登录。我将我的系统设置为 65536,但您可以使用任何数字。

Windows 对每个进程有 2000 个文件的硬性限制,您无法更改。您需要在该平台上分段组装。

这是一个有效的例子。首先,创建一个没有重叠的深度缩放金字塔:

john@kiwi:~/pics/x$ vips dzsave ~/pics/k2.jpg x --overlap 0
john@kiwi:~/pics/x$ cd x_files/11
john@kiwi:~/pics/x/x_files/11$ ls
0_0.jpeg  0_7.jpeg  1_5.jpeg  2_3.jpeg  3_1.jpeg  3_8.jpeg  4_6.jpeg  5_4.jpeg
0_1.jpeg  0_8.jpeg  1_6.jpeg  2_4.jpeg  3_2.jpeg  4_0.jpeg  4_7.jpeg  5_5.jpeg
0_2.jpeg  1_0.jpeg  1_7.jpeg  2_5.jpeg  3_3.jpeg  4_1.jpeg  4_8.jpeg  5_6.jpeg
0_3.jpeg  1_1.jpeg  1_8.jpeg  2_6.jpeg  3_4.jpeg  4_2.jpeg  5_0.jpeg  5_7.jpeg
0_4.jpeg  1_2.jpeg  2_0.jpeg  2_7.jpeg  3_5.jpeg  4_3.jpeg  5_1.jpeg  5_8.jpeg
0_5.jpeg  1_3.jpeg  2_1.jpeg  2_8.jpeg  3_6.jpeg  4_4.jpeg  5_2.jpeg
0_6.jpeg  1_4.jpeg  2_2.jpeg  3_0.jpeg  3_7.jpeg  4_5.jpeg  5_3.jpeg

您可以看到它是由 6 宽和 9 下的瓷砖组成的网格。

现在重新组装瓷砖并写成 TIFF 金字塔:

john@kiwi:~/pics/x/x_files/11$ vips arrayjoin "$(ls *.jpeg | sort -t_ -k2g -k1g)" x.tif[tile,pyramid,compression=jpeg] --across 6
john@kiwi:~/pics/x/x_files/11$ vipsheader x.tif 
x.tif: 1524x2286 uchar, 3 bands, srgb, tiffload_stream

使用 pyvips 会是这样的:

#!/usr/bin/env python3

import pyvips

tiles_across = 142
tiles_down = 150

tiles = [pyvips.Image.new_from_file(f"{x}_{y}.jpeg", access="sequential")
         for y in range(tiles_down) for x in range(tiles_across)]
im = pyvips.Image.arrayjoin(tiles, across=tiles_across)

im.write_to_file("x.jpg")

在这台笔记本电脑上加入 21,000 个磁贴大约需要 10 分钟和 6GB 内存。

【讨论】:

  • 您好 jcupitt,非常感谢您的回复,但我不明白参数 --across 是什么,它的作用是什么?以及我对 0_0.jpeg 到 146_216.jpeg 的文件夹的命令应该如何,我是这个主题的新手,所以需要更多帮助。谢谢。
  • across 是网格中的瓦片数,请查看文档。你需要--across 217。我会先尝试一个小网格,也许是 20 x 20。
  • 嗨 jcupitt,它对于 31 列的图块非常有效,但是随着文件数量的增加,例如有 124 列的地方,我收到以下错误:命令:/var/www /html/eqtribe/acquired_data/131/grid_1/base_tiles/000_files/14 错误:bash:/usr/bin/vips:参数列表太长
  • 如果你的命令对于 bash 来说太长了,你需要切换到 Python 之类的东西。只需打开所有图块并将列表传递给pyvips.Image.arrayjoin()
  • 我添加了一个 pyvips 示例。
猜你喜欢
  • 1970-01-01
  • 2021-07-06
  • 2021-01-28
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
相关资源
最近更新 更多