1. 程式人生 > 其它 >python醫學病理圖片svs裝換

python醫學病理圖片svs裝換

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了很多方法(注:以下很多網站都得FQ...):

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。下面是我的程式碼,很簡單:


  1. import openslide

  2. import numpy as np

  3. import scipy.misc

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

  6.  
  7. img = np.array(test.read_region((0, 0), 0, test.dimensions))

  8. 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/

這個方法有點無腦了,直接讀取然後儲存,一點兒都不拖泥帶水。但是問題是,儲存後的圖片大小變得特別大,但是不會出現儲存不了的情況,也就是不會出現記憶體錯誤之類的現象而導致儲存失敗。下面是我的程式碼:


  1. import pyvips

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

  4. 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檔案格式儲存:


  1. import pyvips

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

  4. img.dzsave('test')

執行以上程式碼後,會生成兩份檔案,分別是:test.dzi,test_files,前者是單個檔案,後者是一個資料夾,裡面儲存了svs檔案不同解析度下的切片,test.dzi裡面的檔案內容如下:


  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <Image xmlns="http://schemas.microsoft.com/deepzoom/2008"

  3. Format="jpeg"

  4. Overlap="1"

  5. TileSize="254"

  6. >

  7. <Size

  8. Height="32893"

  9. Width="46000"

  10. />

  11. </Image>

要想將dzi檔案展示出來,有一個java庫叫做OpenSeaDragon(https://openseadragon.github.io/examples/tilesource-dzi/),將OpenSeaDragon下載下來並解壓放在任何一個你喜歡的本地資料夾中,重新命名為:openseadragon。此外還需要一個html檔案(源自:https://blog.csdn.net/qianqianyixiao1/article/details/50420398),這裡起名為test.html,內容如下:


  1.  
  2. <!DOCTYPE html>

  3. <html lang='en'>

  4.  
  5. <head>

  6. <meta charset='UTF-8'>

  7. <title>OpenSeadragon_Demo0</title>

  8. <script src='../openseadragon.min.js'></script>

  9. </head>

  10.  
  11. <body>

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

  13. </body>

  14.  
  15.  
  16. <script type='text/javascript'>

  17. OpenSeadragon({

  18. id: 'openSeadragon1',

  19. prefixUrl: '../images/',

  20. tileSources: {

  21. Image: {

  22. xmlns: 'http://schemas.microsoft.com/deepzoom/2008',

  23. Url: './test_files/',

  24. Overlap: '1',

  25. TileSize: '254',

  26. Format: 'jpeg',

  27. Size: {

  28. Height: '32893',

  29. Width: '46000'

  30. }

  31. }

  32. }

  33. });

  34. </script>

  35.  
  36. </html>

記得將裡面的資料替換成dzi檔案裡面的資料,然後就可以將test.dzi檔案刪除了。然後將test.html和test_files資料夾置於同一目錄(這裡我的目錄起名為:zoomFiles)下,然後放入到openseadragon資料夾中(下圖所示),然後你就可以點選test.html檔案,在網頁裡就能得到顯示對應的結果了(如下圖所示,最後一張為檔案存放規則)。