OpenSlide indroduction

Table of content
  1. 1. OpenSlide
  2. 2. Windows install
  3. 3. Problems
  4. 4. Ubuntu install
  5. 5. WSI operation
    1. 5.1. read slide and close

OpenSlide

https://openslide.org/

OpenSlide is a C library that provides simple interfaces to process Whole-Slide-Images (also known as virtual slides). WSIs are very high resolution images used in digital pathology. These images usually have several gigabytes and can not be easily read with standard tools or libraries because the uncompressed images often occupy tens of gigabytes which consume huge of RAM. WSI is scanned with multi-resolution, while OpenSlide can support read a small amount of image data at the resolution closest to a specifical magnification level.

OpenSlide supports many popular WSI format:

  • Aperio (.svs, .tif)
  • Hamamatsu (.ndpi, .vms, .vmu)
  • Leica (.scn)
  • MIRAX (.mrxs)
  • Philips (.tiff)
  • Sakura (.svslide)
  • Trestle (.tif)
  • Ventana (.bif, .tif)
  • Generic tiled TIFF (.tif)

Although it is written by C, Python and Java bindings are also provided, and some other bindings are contributed in the Github such as Ruby, Rust.

In this post, I’ll introduce how ot install OpenSlide and OpenSlide-Python binding in Windows and Ubuntu, and give some examples.

Windows install

OpenSlide and OpenSlide-Python are different,that must be installed seperately. OpenSlide is the core library, while the other is the implementation of the interface.

OpenSlide Python document: https://openslide.org/api/python/

Download OpenSlide: https://openslide.org/download/

windows binaries

First, download OpenSlide windows binaries and extract them to a folder.

Sencond, install OpenSlide Python package. It is not recommended to install OpenSlide Python with conda here, I have tried several times with conda, but got the PackageNotFoundError:

Package not found

To work around, use pip to install:

1
pip install openslide-python
install with pip

In my computer, openslide-python 1.2.0 is installed.

Then, according to the document, in Python, import in a with os.add_dll_directory() statement:

1
2
3
4
5
6
7
8
9
10
# The path can also be read from a config file, etc.
OPENSLIDE_PATH = r'c:\path\to\openslide-win64\bin'

import os
if hasattr(os, 'add_dll_directory'):
# Python >= 3.8 on Windows
with os.add_dll_directory(OPENSLIDE_PATH):
import openslide
else:
import openslide

Problems

However, when importing the openslide’s python binding, I got the WinError 127, here is my error message:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-2-f3638bbb3565> in <module>
7 # Python >= 3.8 on Windows
8 with os.add_dll_directory(OPENSLIDE_PATH):
----> 9 import openslide
10 else:
11 import openslide

C:\ProgramData\Anaconda3\lib\site-packages\openslide\__init__.py in <module>
28 from PIL import Image
29
---> 30 from openslide import lowlevel
31
32 # For the benefit of library users

C:\ProgramData\Anaconda3\lib\site-packages\openslide\lowlevel.py in <module>
52 if platform.system() == 'Windows':
53 try:
---> 54 _lib = cdll.LoadLibrary('libopenslide-0.dll')
55 except FileNotFoundError:
56 import os

C:\ProgramData\Anaconda3\lib\ctypes\__init__.py in LoadLibrary(self, name)
457
458 def LoadLibrary(self, name):
--> 459 return self._dlltype(name)
460
461 cdll = LibraryLoader(CDLL)

C:\ProgramData\Anaconda3\lib\ctypes\__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error, winmode)
379
380 if handle is None:
--> 381 self._handle = _dlopen(self._name, mode)
382 else:
383 self._handle = handle

OSError: [WinError 127] The specified procedure could not be found

And it alerted “Entry point not found”:

Entry point not found

I was stucked in this problem and has tried just every solution I found with no success.

Until I found a solution in Stackoverflow, It may seems that I was trapped in “DLL Hell”.

There is a Windows DLL file that is taking precedence over the DLL file python needs in this source code. You need to prepend the PATH variable in your Python binding module before calling the C openslide library with the full path of the bin folder where the C openslide library DLL files reside. This will override the Windows “zlib1.dll” file by using the OpenSlide “zlib1.dll” file. -author: MacGyver

So, I tried to prepend openslide bin path in the PATH environment. It did work! The whole import code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# The path can also be read from a config file, etc.
OPENSLIDE_PATH = r'c:\path\to\openslide-win64\bin'

import os
# solve dll hell
os.environ['PATH'] = OPENSLIDE_PATH + ";" + os.environ['PATH']

# import openslide
if hasattr(os, 'add_dll_directory'):
# Python >= 3.8 on Windows
with os.add_dll_directory(OPENSLIDE_PATH):
import openslide
else:
import openslide

Ubuntu install

If you have root permission, you can install openslide directly by apt:

1
2
3
4
5
6

## OpenSlide
apt-get install openslide-tools

## OpenSlide Python
apt-get install python3-openslide

Just follow the openslide document, https://openslide.org/download/#distribution-packages

But, if you are in a restricted environment where you don’t have the permission to install with apt, conda is an altenative method.

Here, I will use miniconda which is a minimal installer for conda (https://docs.conda.io/en/latest/miniconda.html).

1
2
3
4
5
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p miniconda3 -s
rm Miniconda3-latest-Linux-x86_64.sh
conda=miniconda3/bin/conda
$conda create -y -n openslide

The commands above will download the latest miniconda and setup a $conda local variable for the convinent. Then create an environment called ‘openslide’. If you want to add other packages or specific python version, visit https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#viewing-a-list-of-your-environments

Until now, it works smoothly. But reached out an error when activated the environment.

Command Not Found Error

Follow the instruction, I closed and reconnected to the shell, the base environment was activated successfully. It doesn’t matter because I can install openslide with conda.

Run one of the following, https://anaconda.org/conda-forge/openslide:

1
2
conda install -c conda-forge openslide
conda install -c conda-forge/label/cf202003 openslide

Then, let’s install openslide-python:

1
pip install openslide-python

Check it:

list the packages

And import openslide:

import openslide

WSI operation

Now, I can read the Whole-Slide-Images with OpenSlide.

read slide and close

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
slide = openslide.OpenSlide(r'F17-011490.ndpi')
print(dir(slide))
slide.close()

# output
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__enter__', '__eq__', '__exit__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_filename', '_osr', 'associated_images', 'close', 'detect_format',
'dimensions', 'get_best_level_for_downsample', 'get_thumbnail',
'level_count', 'level_dimensions', 'level_downsamples', 'properties',
'read_region', 'set_cache']

If there is no error and get the same result, congratulations that it works!

The slide object has some useful functions to use, such as level_count return total number of level, level_dimensions return the dimension for thar target level of the slide.

In my task, I need to read a small part in the WSI at the target level, OpenSlide provides read_region(location, level, size) that can simplify my work.

1
2
3
4
5
6
7
8
9
10
slide = openslide.OpenSlide(r'F17-011490.ndpi')
# first parameter location is a tuple that contains the left top point
# of the tissue tile, it is the original pixel in source image.
# third parameter size is also a tuple that contains the width and
# height of the tissue tile, it is the reduced size!
patch = slide.read_region((1407 * 32, 1156 * 32), 5, (240, 160))
# matplotlib read the image
plt.imshow(patch)
plt.show()
slide.close()
WSI tissue tile

For the full usage, please visit https://openslide.org/api/python/#basic-usage

Happy coding.