Use ImageJ in Python¶
This section shows how to use ImageJ as a Python library to analyze data in OMERO.
Using the Python API allows us to easily load the 2D-plane we need to see or analyze. This is much easier than using the Java API and Bio-Formats plugin.
We will show in the examples:
How to start ImageJ in Python.
How to load data from OMERO.
How to run ImageJ macro from Python.
For using the Python examples and notebooks of this guide we recommend using Conda (Option 1). Conda manages programming environments in a manner similar to virtualenv.
Alternatively you can use
repo2docker to build and run a Docker image locally (Option 2).
This Docker image will provide the Conda environment and Jupyter notebooks with some image
Install omero-py and pyimagej via Conda:
Install Miniconda if necessary.
Create a programming environment using Conda and activate it:
$ conda create -n imagej_python python=3.6 $ conda activate imagej_python
Install omero-py and pyimagej:
$ conda install -c conda-forge pyimagej $ conda install -c ome omero-py
Note: we have noticed problems using the Option 1 approach when running the scripts on some operating systems due to issues with the ImageJ1-ImageJ2 bridge.
Create a local Docker Image using
$ pip install jupyter-repo2docker $ git clone https://github.com/ome/omero-guide-fiji.git $ cd omero-guide-fiji $ repo2docker .
When the Image is ready:
Copy the URL displayed in the terminal in your favorite browser
Newbutton on the right-hand side of the window
A Terminal will open in a new Tab
A Conda environment has already been created when the Docker Image was built
To list all the Conda environments, run:
$ conda env list
The environment with the OMERO Python bindings and a few other libraries is named
notebook, activate it:
$ conda activate notebook
The script used in this document is
One of the advantages of this approach is that we can load only the 2D-planes we wish to analyze.
The script used in this document contains an ImageJ1 macro that needs graphical user interface (GUI) elements, and thus it requires using ImageJ in GUI mode. In this GUI mode, the resulting windows content is handled.
If you are running the example in the Docker container,
you will also need to start UI environment if it is not already up.
If you have used the Option 2 above, select
desktop to start the UI environment.
If you are using the Option 1 above, you will first need to update the script to point to your local installation of Fiji or use one of the options described in ImageJ Tutorials.
You can now run the script. To run the script, go to the folder
scripts/python and run:
$ python run_macro_python.py
If you do not use any ImageJ1 features e.g. macro, you do not need the UI environment.
Below we explain the various methods in the scripts: how to start Fiji, how to load the planes to analyze and how to run an ImageJ1 macro.
In this example, Fiji has been installed locally.
Import modules needed:
import imagej from omero.gateway import BlitzGateway
Load Fiji. If you run the script locally, point to your local installation of Fiji or load Fiji “on the fly”. Note that the parameter headless has been set to False since we need the graphical user interface to run the ImageJ1 macro:
def start_fiji(): ij = imagej.init('/srv/conda/vnc/Fiji.app', headless=False) ij.getVersion() return ij
Connect to the server. It is also important to close the connection again
to clear up potential resources held on the server. This is done in the
def connect(hostname, username, password): """ Connect to an OMERO server :param hostname: Host name :param username: User :param password: Password :return: Connected BlitzGateway """ conn = BlitzGateway(username, password, host=hostname, secure=True) conn.connect() conn.c.enableKeepAlive(60) return conn def disconnect(conn): """ Disconnect from an OMERO server :param conn: The BlitzGateway """ conn.close()
Load an image from IDR:
image = conn.getObject("Image", image_id)
Load the binary plane as numpy array:
def load_plane(image): """ Load a 2D-plane as a numpy array :param image: The image """ pixels = image.getPrimaryPixels() return pixels.getPlane(0, 0, 0)
To be used in ImageJ, the numpy array will be converted into ImageJ types using the to_java() method.
In order the use the methods implemented above in a proper standalone script:
Wrap it all up in an
analyse method and call it from
def analyse(ij, conn, image_id): # Step 3 - Load image image = conn.getObject("Image", image_id) # - plane = load_plane(image) from jnius import autoclass autoclass('ij.WindowManager') ij.ui().show('Image', ij.py.to_java(plane)) macro = """run("8-bit")""" ij.py.run_macro(macro) def main(): try: hostname = input("Host [wss://idr.openmicroscopy.org/omero-ws]: \ ") or "wss://idr.openmicroscopy.org/omero-ws" username = "public" password = "public" image_id = int(input("Image ID : ") or 1884807) print("initializing fiji...") ij = start_fiji() print("connecting to IDR...") conn = connect(hostname, username, password) print("running the macro...") analyse(ij, conn, image_id) finally: if conn: disconnect(conn) if __name__ == "__main__": main()