LoginSignup
10
7

More than 5 years have passed since last update.

svsフォーマットの画像をjpgに変換した話

Last updated at Posted at 2018-09-02

SVS is 何?

SVSとはScanScopeVirtuelSlide略称であり、ScanScope専用のフォーマット。
主に病理画像の撮影に使われており、その他利用方法が存在しない。

どうして変換するの?

開けなくて困ってるから!!
誰ですかねこんなフォーマット作ったの。。。
色んな情報が詰め込まれていてサイズも大きいから大変。

ScanScopeインストールすればいい話だけどわざわざ開くのが面倒臭い。

どうやら変換できるAPIが存在するらしい

OpenSlideという専用ライブラリを使えば変換可能らしい
ドキュメントを見ながら手探りで使用してみる。

実際に変換してみた

導入環境

Ubuntu 16.04

インストール

python-openslide(本体)のインストール

sudo apt-get update
sudo apt-get install python-openslide

openslide-python(ライブラリ)のインストール

pip install --no-deps openslide-python

インタプリタ起動してimportできればOK

$ python
Python 3.6.5 (default, May  4 2018, 23:20:02)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import openslide
>>>

OK

APIの仕様

OpenSlide Python APIを読むとどうやら、

  1. svs形式の画像を読み込んでOpenSlide objectsを作る
  2. objectのread_region()メソッドを使用してjpg形式に変換
  3. 保存する

で出来そう。

いざやってみるも...

なんかエラー出た...

>>> osimg = OpenSlide("test.svs")
>>>
>>> osimg.dimensions
(27888, 21512)
>>> jpgimg = osimg.read_region((0,0), 0, osimg.dimensions)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/openslide/__init__.py", line 223, in read_region
    level, size[0], size[1])
  File "/openslide/lowlevel.py", line 260, in read_region
    return _load_image(buf, (w, h))
  File "/openslide/lowlevel.py", line 65, in _load_image
    return PIL.Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
  File "/PIL/Image.py", line 2398, in frombuffer
    core.map_buffer(data, size, decoder_name, None, 0, args)
MemoryError: Integer overflow in ysize
>>>

どうやらpillowの方でのエラーみたいだ。
pillowのfrombuffer()メソッドの仕様を探しているとgithubで解決策を見つけた。
ysizeが2^14、つまり16384を超えてしまっているが為にエラーが出ているらしい。

しょうがないから細かく変換してそれを結合する方針で行くことにした。
第一引数の(0,0)は切り取り開始位置を示しているので、例えば縦横5000pxで変換した後に次に変換する位置は
(0,5000)という具合になる。

結合は、以下のようにする。

def get_concat_h(im1, im2):
    dst = Image.new('RGB', (im1.width + im2.width, im1.height))
    dst.paste(im1, (0, 0))
    dst.paste(im2, (im1.width, 0))
    return dst

def get_concat_v(im1, im2):
    dst = Image.new('RGB', (im1.width, im1.height + im2.height))
    dst.paste(im1, (0, 0))
    dst.paste(im2, (0, im1.height))
    return dst

get_concat_h(im1, im1).save('dog_h_connect.jpg')
get_concat_v(im1, im1).save('dog_v_connect.jpg')

横に結合
h_resize.jpg
縦に結合
v_resize.jpg

ついに

やっとこさ変換出来ました。それにしても気持ち悪い。
qiita_resize.jpg
もっとスマートな方法があるような気がしてならない。。。
どなたかいい方法が分かる方教えてくださると嬉しいです。

終わりに

今回使用したコードは一応GitHubにあげています。

10
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7