最近在公司一直忙于做svs文件的处理工作,期间看了很多的博客还有国外的一些api文档,感觉稍微有了点了解,所以打算写下这篇博客记录这段时间的工作情况;

SVS文件是什么?

最开始拿到SVS文件一脸懵逼的,这货长这样(在windows下可以用Aperio ImageScope这个开源软件打开):

我现在接触的这种图片的大小一般在60M-1.5G之间,可以将图片放大到20倍左右,上面的这张图片来自于网站https://openslide.org/demo/,支持网页在线查看,有兴趣小伙伴可以去这个网站看看。当图片放大到最大分辨率时,可以看到组织里面的每一个细胞,可以说真的非常高清了。

SVS文件如何转存成通用格式(保持高分辨率)?这里以上面链接里面的 CMU-1-JP2K-33005.svs 文件为例,文件大小为:132.6M

我首先想到了opencv,因为图片处理这一块opencv比较方便。但是令我想不到的是,opencv竟然读取的时候就出错了“ cv2.error: OpenCV(3.4.2) /io/opencv/modules/imgcodecs/src/loadsave.cpp:74: error: (-215:Assertion failed) pixels <= (1<<30) in function 'validateInputImageSize' ”,说明svs文件大小超出范围,于是我只能换其他方法。

然后我google了很多方法(注:以下很多网站都得翻墙...):

1. OpenSlide(openslide-python): https://openslide.org/

OpenSlide这是一个开源C库,有python的接口,很好用。具体的openslide的使用,大家可以自行百度,这里有一个不错的链接:https://blog.csdn.net/weixin_41787032/article/details/79817926

不得不说,openslide对于病理图片的切片处理还是很不错的,但是要想把保存整张高分辨率图片,我很惊讶地发现,图片的大小以倍数增加(使用tiff格式存储,大概扩大了十倍,但是如果以jpg格式的话,图片确实会很小,但是是属于有损压缩,这里并没有选择。话说png也是个不错的选择),因为我取的是 level=0下的dimensions,这样可以保持图片的最大分辨率,但是与此同时,如果图片再大一点或者电脑的性能略低的话,电脑就有可能卡死,或者报MemoryError的错误,于是我放弃了继续使用openslide。下面是我的代码,很简单:

import openslide
import numpy as np
import scipy.misc

test = openslide.open_slide('test.svs')

img = np.array(test.read_region((0, 0), 0, test.dimensions))
scipy.misc.imsave('test.tif', img)

2. libvips(pyvips): http://jcupitt.github.io/libvips/API/current/Examples.md.html

libvips也是一个C库,但是也有python接口,叫pyvips,使用方法请查看官方文档:https://libvips.github.io/pyvips/

这个方法有点无脑了,直接读取然后存储,一点儿都不拖泥带水。但是问题是,存储后的图片大小变得特别大,但是不会出现存储不了的情况,也就是不会出现内存错误之类的现象而导致存储失败。下面是我的代码:

import pyvips

img = pyvips.Image.new_from_file('test.svs', access='sequential')
img.write_to_file('test.tif')

3. reaConverter(windows软件,支持命令行批量操作)

这是一款windos下的软件,可以支持多种格式的图片自动转换,这是链接:https://www.reaconverter.com/convert/svs_to_tiff.html。问题是,转换过后的图片大小依然非常大,而且转换时间很长,每一样都是我所不能接受的。而且,软件也是付费的,伤不起。。。(软件长这个样子)

其实,对于svs文件的高分辨率存储,我现在也还是没有太好的解决办法。我现在所能存储的结果都是,文件变得特别大,这样对于存储以及后续的处理都非常麻烦,所以我们研究了一下,还是决定对svs文件进行切片处理,然后进行识别等一系列操作,存储这一环节就被省略掉了。如果大家有什么好的建议不妨探讨一下;

SVS文件的显示

这里我就直接说方法了,也就是很牛掰的Deep Zoom。微软有一个软件叫做DeepZoomComposer,原理和这个一样,可以实现将一张高清大图分成好几个分辨率下的小图,并且小图是由一张张小的切片组成的,下面是这种图片的效果(左边是缩略图,右边是最大分辨率下眼睛部位的图片):

既然这么牛掰的技术,python肯定也会有相应的api的。有很多库都支持deep zoom,像:openslide,py_wsi,pyvips等等,不过这里我还是要用pyvips,不为什么,只是因为简单无脑。。。下面是将svs文件转换成dzi文件格式保存:

import pyvips

img = pyvips.Image.new_from_file('test.svs', access='sequential')
img.dzsave('test')

执行以上代码后,会生成两份文件,分别是:test.dzi,test_files,前者是单个文件,后者是一个文件夹,里面存储了svs文件不同分辨率下的切片,test.dzi里面的文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"
  Format="jpeg"
  Overlap="1"
  TileSize="254"
  >
  <Size 
    Height="32893"
    Width="46000"
  />
</Image>

要想将dzi文件展示出来,有一个java库叫做OpenSeaDragon(https://openseadragon.github.io/examples/tilesource-dzi/),将OpenSeaDragon下载下来并解压放在任何一个你喜欢的本地文件夹中,重命名为:openseadragon。此外还需要一个html文件(源自:https://blog.csdn.net/qianqianyixiao1/article/details/50420398),这里起名为test.html,内容如下:


<!DOCTYPE html>
<html lang='en'>

<head>
    <meta charset='UTF-8'>
    <title>OpenSeadragon_Demo0</title>
    <script src='../openseadragon.min.js'></script>
</head>

<body>
    <div id='openSeadragon1' style='width:1850px; height:960px;'></div>
</body>


<script type='text/javascript'>
    OpenSeadragon({
        id: 'openSeadragon1',
        prefixUrl: '../images/',
        tileSources: {
            Image: {
                xmlns: 'http://schemas.microsoft.com/deepzoom/2008',
                Url: './test_files/',
                Overlap: '1',
                TileSize: '254',
                Format: 'jpeg',
                Size: {
                    Height: '32893',
                    Width: '46000'
                }
            }
        }
    });
</script>

</html>

记得将里面的数据替换成dzi文件里面的数据,然后就可以将test.dzi文件删除了。然后将test.html和test_files文件夹置于同一目录(这里我的目录起名为:zoomFiles)下,然后放入到openseadragon文件夹中(下图所示),然后你就可以点击test.html文件,在网页里就能得到显示对应的结果了(如下图所示,最后一张为文件存放规则)。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐