There are two main Python libraries to interface with microscopes through Micro-Manager:
- Pycro-manager is a multi-purpose python package for the control of microscope hardware and the acquisition of data. It is capable of performing in demanding, data-intensive applications where large datasets at mutiple GB/s for hours at a time, while also providing a concise yet flexible API that can be adapted to many different modailities of microscopy. It can be used:
- Alongside the Micro-manager GUI to support additional automation and customization
- As a standalone library for acquiring data from a Python environment
- As a backend data acquisition system with Napari as an image viewer, or a custom image viewer
- With no GUI at all in a server environment (on a single computer or across a network)
- Pycro-manager contains a translation layer that dynamically translates Java code into Python, which allows for any Micro-Manager APIs/plugins written in Java to be controlled as if they had been writtin in Python
provides a Python bindings of the underlying C++ library
Micro-Manager uses. This option does not require you to launch Micro-Manager, or
even to have Java installed. However, it does not come with a GUI. If you want a GUI
that integrates with pymmcore you can use the community developed
- pymmcore-plus is a thin wrapper
pymmcorethat extends the core object, adding additional methods, docstrings, type hints, as well as better support for integration into a GUI event loop.
- pymmcore is the successor of
MMCorePywhich was formerly included in Micro-Manager and supported only Python 2.x.
- pymmcore-plus is a thin wrapper of
The instructions below are for an alternative mechanism in which you compile the micro-manager core yourself with python bindings.
Micromanager’s main parts:
- CMMCore - basic module, written in C++.
- Device adapters - various libraries that allow support for various hardware. If you want to built one and extend MM devise support, follow this guide.
- MMCoreJ - java wrapper
- MMStudio - Micromanager GUI (technically it is ImageJ plugin).
You must install python and numpy. An easy way to do this is through the
package manager. The easiest way to install
conda (or the faster
mamba) is by
the downloads here.
conda create -n micro -c conda-forge python matplotlib pymmcore conda activate micro
alternatively you can install using pip:
pip install pymmcore #or pip install pymmcore-plus
Other python distributions
Other python distributions you may find useful in place of
- Scipy - scientific algorithms, multidimensional image processing toolbox.
- Matplotlib - fastest way to show your image data.
- Opencv - computer vision and image processing library. Sometimes faster than scipy.
- Pillow - very basic image processing. Scipy uses it for image loading and writing.
- Scikit-image - “pythonic” scientific-oriented image processing algorithms collection.
- IPython - improved interactive python environment
Getting Device Adapters
To use these Python options you minimally need to have installed the Device Adapters. The easiest way to get these is to install Micro-Manager, however you can also install only the Core and Adapters by following the instructions in the mmCoreAndDevices README (this will be the best option for Linux users).
If you are using Pycro-Manager then just
mmCoreAndDevices is insufficient, you will need a complete Micro-Manager installation.
Using Python API
The primary API you will interact with is the
MMCore object. You can read it’s
API documentation here.
Other useful pages to read are:
- Micro-Manager Configuration Guide to help understand how properties work.
- The general Micro-Manager Programming Guide
pip install pymmcore # or pip install pymmcore-plus
Start python interactive session. Import `pymmcore` and make sure everything is working properly.
import pymmcore mmc = pymmcore.CMMCore() # Instance micromanager core mmc.getVersionInfo() # gives: 'MMCore version 2.3.2' mmc.getAPIVersionInfo() # gives: 'Device API version 59, Module API version 10'
For this tutorial you may also use
pymmcore-plus. To do this replace the first two lines with:
import pymmcore_plus mmc = pymmcore_plus.CMMCore.instance() # Instance micromanager core
We just get some basic information about current Micromanager
installation. If there an
ImportError, check your PYTHONPATH
variable. If output is too verbose, run
There are two approaches to loading devices: loading a
.cfg file and manually loading the devices one by one.
For this example we will use the Demo Devices distributed with the Device Adapters.
For both of these examples you will need to point
pymmcore to the folder with the device adapters. You can do this with
setDeviceAdapterSearchPaths function. The standard folder is the
micro-manager folder which is installed into
these folders by default:
System Configuration The recommended way to load devices is to use a Micro-Manager config file. For example to load the Demo Config on windows you would run:
and then see the loaded devices with:
Individual Devices If you want more fine grained control over device loading then you can manually do so:
mmc.loadDevice('Camera', 'DemoCamera', 'DCam') mmc.initializeAllDevices() mmc.setCameraDevice('Camera')
Every device has properties settings that let you control the device more precisely. Default values should be fine, but if you need something sophisticated, this example help you figure out how to explore it.
Snapping single image
Images returned as numpy array by calls to an instance of the pythonized Micro-Manager CMMCore class. The array dtype depends on property named PixelType (see below).
>>> mmc.snapImage() >>> img = mmc.getImage() # img - it's just numpy array >>> img array([[12, 12, 13, ..., 11, 12, 12], [12, 12, 13, ..., 11, 12, 12], [12, 13, 13, ..., 12, 12, 12], ..., [22, 22, 22, ..., 22, 22, 22], [22, 22, 22, ..., 22, 22, 22], [22, 22, 22, ..., 22, 22, 22]], dtype=uint8)
DemoCamera snaps grayscale 8-bit image, by default. It presented as two-dimensional numpy array. Let’s show image data with matplotlib.
>>> import matplotlib.pyplot as plt >>> plt.imshow(img, cmap='gray') >>> plt.show() # And window will appear
Of course, color image is more suitable for optical microscopy purposes. So take one, if your camera support it:
>>> mmc.setProperty('Camera', 'PixelType', '32bitRGB') # Change pixel type >>> rgb32 = mmc.getImage() >>> rgb32 array([[1250067, 1250067, 1315860, ..., 1250067, 1250067, 1250067], [1250067, 1315603, 1315860, ..., 1250067, 1250067, 1250067], [1250067, 1315859, 1315860, ..., 1250067, 1250067, 1250067], ..., [1246483, 1246483, 1246483, ..., 1181204, 1246740, 1246484], [1246483, 1246483, 1246483, ..., 1246740, 1246740, 1246483], [1246483, 1246483, 1312019, ..., 1246740, 1246740, 1246483]], dtype=uint32)
Interesting output isn’t it? We expect something like 3-dimensional RGB array, but get bunch of 32-bit uints in 2-D shape.
Now we should look at RGB32 pixel data structure. Every pixel has 32-bit depth and contain 4 values for blue, green, red and blank channel. Blank channel is more technical peculiarity, than necessity.
low memory address ----> high memory address | pixel | pixel | pixel | pixel | pixel | pixel |... |-------|-------|-------|-------|-------|-------|... |B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|...
Let’s numpy handle that.
>>> import numpy as np >>> rgb32.shape (512, 512) >>> rgb = rgb32.view(dtype=np.uint8).reshape( rgb32.shape, rgb32.shape, 4)[...,2::-1] >>> rgb.shape (512, 512, 3) >>> rgb.dtype dtype('uint8')
It is a fastest way to get pixel data as RGB array without copying.
There is no conversion - just creating new view to same data. Now you
can process image with scipy or scikits-image. Note, that opencv uses
BGR order (replace slice to
[..., :3] for that).
mmc.startContinuousSequenceAcquisition(1) while True: if mmc.getRemainingImageCount() > 0: frame = mmc.getLastImage() # or frame = mmc.popNextImage()
A longer example script, MMCoreWrapDemo.py, is available in the Micro-Manager root directory.
Also check out micromanager-samples repo (live video acquisition, property discovery etc).
- Image manipulation and processing using Numpy and Scipy by Python Scientific Lecture Notes.
- Scikits-image gallery
- Lectures on scientific computing with Python
- OpenCV-Python Tutorials
Written by Eugene Dvoretsky – Radioxoma 09:19, 14 June 2014 (PDT)