Working with MATLAB
There are two main approaches to use QuPath and MATLAB together interactively, each with pros and cons:
-
Launch QuPath from within MATLAB
-
Advantages:
- Full access to QuPath's Java classes from within MATLAB
- Possible to run commands from MATLAB's Command Window rather than QuPath's (rather more limited) Script Editor
-
Disadvantages:
- Setup can be awkward
- Differences in required native libraries can cause conflicts (e.g. the version of libtiff used with OpenSlide and MATLAB are incompatible)
-
Advantages:
-
Control MATLAB from inside QuPath (> MATLAB R2016b only)
-
Advantages:
- Clean separation between QuPath and MATLAB - both can be run as normal, and data sent from QuPath to MATLAB and variables pulled back
- Groovy scripting can make this fast and interactive.
-
Disadvantages:
- Not possible to control QuPath from within MATLAB, so necessary to switch back and forth between applications.
- No direct access to Java classes from within MATLAB - need to convert on the QuPath side before sending.
-
Advantages:
This section explains how to get started with both methods, and describes some of the tools already available to help.
Here we focus on interactive use of QuPath and MATLAB together. The MATLAB Compiler SDK offers another way (untested with QuPath!) to combine MATLAB and Java code.
To begin using either method:
- Download and install the QuPath MATLAB extension.
- From within QuPath, run Extensions → MATLAB → Export MATLAB scripts and select a directory into which the MATLAB
.m
files should be exported
These instructions have so far only been tested on macOS!
Please report it on the user group, or raise an Issue, if they don't work on other platforms.
This section describes how to launch QuPath from inside MATLAB, effectively using QuPath as a whole slide viewer for MATLAB.
First, MATLAB needs to set the Java classpath so that it knows where all QuPath's requirements lie.
This can be done by opening a MATLAB command prompt, navigating to the location of the scripts downloaded previously, and running the following:
setup_qupath
This will prompt you to identify the path to where QuPath is installed, and set the (static) Java classpath within MATLAB accordingly.
Classpaths in MATLAB are described here.
When running the setup script, you may have seen a warning about the Java version used by MATLAB. This is because MATLAB (currently) uses an older version of Java than QuPath requires by default.
You can confirm the version of Java used within MATLAB by running the following command at the MATLAB command prompt:
version -java
QuPath requires Java 8 (often written as Java 1.8.something). If MATLAB is using anything earlier than this, then it won't work with QuPath.
The fix is reasonable straightforward, but requires two steps:
If you don't already have it, Java 8 can be downloaded from www.oracle.com; you likely want the Java Development Kit (JDK).
MATLAB needs to be started up in a different way to make sure that it uses the newer Java version. The easiest way to do this is to create a new launcher (shortcut) to click on to open MATLAB. This can be created by following the instructions for the appropriate operating system below:
Note: Each link above also includes a script that can be run from MATLAB to automate the process.
When using QuPath from within MATLAB, you will almost certainly want to have more memory available for Java than MATLAB's defaults. To ensure this, you should increase the Java Heap Memory Preferences in MATLAB, as described here.
Having performed all the above steps, you will need to restart MATLAB - using the new launcher created above! - for them to take effect.
Then you can start QuPath using the helper class stored in QuPath.m
, which was downloaded above.
To use it, type the following at the MATLAB command prompt:
qupath = QuPath.getInstance()
This should lead to an instance of QuPath being started up from inside MATLAB.
Open an image within QuPath, and try to control it from within MATLAB using the qupath
object.
Two demo scripts are provided in the directory that you downloaded to show what is involved: qupath_superpixels_script.m
and qupath_tma_script.m
.
Both require an image to be opened. The second script also requires a TMA image, which has already been dearrayed within QuPath.
Warning! There may be some native library issues setting up MATLAB and OpenSlide, which prevents using OpenSlide for whole slide image reading with MATLAB.
See the Extensions for any alternative image readers that may be added to QuPath. In particular, check out the QuPath Bio-Formats Extension for a Java-based image reader that supports many different file formats.
Starting with 2016b, MATLAB comes with a MATLAB Engine API for Java. This makes it possible to send variables from within QuPath to a running MATLAB session, manipulate them within MATLAB if necessary, and pull back the results if required.
This section describes how to get started with this method of connecting QuPath and MATLAB. It is written to provide QuPath-specific help to complete the general setup steps described on the MATLAB website.
To enable QuPath to find MATLAB's required native libraries, it is essential to ensure that the java.library.path
is set appropriately when QuPath is started.
The easiest - albeit somewhat hackish - way to do this is to modify the QuPath.cfg
file to include this under JVMOptions
.
On macOS QuPath.cfg
is found under QuPath.app/Contents/Java/QuPath.cfg
.
Remember, to 'see inside' a
QuPath.app
(or any similar.app
file) on macOS, right-click on it and choose Show Package Contents.
An example of a (i.e. my) modified QuPath.cfg
file is shown below:
[Application]
app.name=QuPath
app.mainjar=QuPathApp.jar
app.version=0.0.3
app.preferences.id=QuPathAppID
app.mainclass=qupath/QuPath
app.classpath=qupath/qupath-core-0.0.3.jar:qupath/qupath-core-awt-0.0.3.jar:qupath/qupath-core-processing-0.0.3.jar:qupath/qupath-core-processing-awt-0.0.3.jar:qupath/qupath-extension-ij-0.0.3.jar:qupath/qupath-extension-input-0.0.3.jar:qupath/qupath-extension-opencv-0.0.3.jar:qupath/qupath-extension-openslide-0.0.3.jar:qupath/qupath-extension-pen-0.0.3.jar:qupath/qupath-extension-script-editor-0.0.3.jar:qupath/qupath-gui-fx-0.0.3.jar:qupath/qupath-processing-ij-0.0.3.jar:qupath/qupath-processing-opencv-0.0.3.jar:jars/commons-math3-3.6.1.jar:jars/controlsfx-8.40.12.jar:jars/flowless-0.4.5.jar:jars/groovy-2.4.7.jar:jars/groovy-jsr223-2.4.7.jar:jars/gson-2.7.jar:jars/ij-1.51g.jar:jars/jfxtras-common-8.0-r5.jar:jars/jfxtras-menu-8.0-r5.jar:jars/jinput-2.0.6.jar:jars/jpen-2-150301.jar:jars/jutils-1.0.0.jar:jars/logback-classic-1.1.7.jar:jars/logback-core-1.1.7.jar:jars/opencv-3.1.0.jar:jars/openslide-3.4.1.jar:jars/packager.jar:jars/reactfx-2.0-M4u1.jar:jars/richtextfx-0.6.10.jar:jars/slf4j-api-1.7.20.jar:jars/undofx-1.2.jar:jars/wellbehavedfx-0.1.1.jar
app.runtime=$APPDIR/PlugIns/Java.runtime
app.identifier=QuPathAppID
[JVMOptions]
-Djava.library.path=/Applications/MATLAB_R2016b.app/bin/maci64:.:../MacOS
[JVMUserOptions]
[ArgOptions]
The only line that has been added is
-Djava.library.path=/Applications/MATLAB_R2016b.app/bin/maci64:.:../MacOS
/Applications/MATLAB_R2016b.app/bin/maci64
is the path to the MATLAB libraries, while the :.:../MacOS
added at the end is to ensure that the original contents of QuPath's library path are retained. This is essential to ensure QuPath can find its own native libraries!
Note: On Windows, try replacing the colon
:
with a semi-colon;
.
The contents of the library path (either before or after modifying it) can also be seen under Help → System info - however it cannot be changed here.
The next step is comparatively straightforward, and can be done from within QuPath.
Start up QuPath, and run Extensions → MATLAB → Set path to MATLAB engine.
A file chooser dialog should open up, from which you can select the MATLAB engine path (a file called engine.jar
), as described here.
On my computer, this is found under
/Applications/MATLAB_R2016b.app/extern/engines/java/jar/engine.jar
Now start up a MATLAB session, and run the following command at the command prompt:
matlab.engine.shareEngine
This isn't strictly necessary, but it means that QuPath will start interacting with the MATLAB session that you started - and you will be able to query which variables it sent there etc.
If you omit this line, QuPath can use the MATLAB engine to start up its own instance each time it is needed - but this will be considerably slower, and harder to see quite what is happening.
Finally, you should now be able to write Groovy scripts to send data to MATLAB, and also to pull back the results.
The first example to try is shown below, and also found within Extensions → MATLAB → Groovy MATLAB samples → MATLAB Hello
/**
* Demo script to check QuPath can talk to MATLAB in a friendly way.
*
* This requires the MATLAB Engine, available with MATLAB R2016b,
* and setup as described at https://github.com/qupath/qupath/wiki/Working-with-MATLAB
*
* @author Pete Bankhead
*/
// Import the helper class
import qupath.extension.matlab.QuPathMATLABExtension;
QuPathMATLAB = this.class.classLoader.parseClass(QuPathMATLABExtension.getQuPathMATLABScript())
// Get the MATLAB engine
// Currently, it's essential to make sure close() is called -
// so the try/finally is important.
// Without it, there's a risk of an error that will prevent reconnection...
QuPathMATLAB.getEngine(this)
try {
QuPathMATLAB.putVariable('a', 'Hello from QuPath!')
QuPathMATLAB.eval('disp(a);')
} finally {
QuPathMATLAB.close()
}
Running this script from within QuPath's script editor should result both in a friendly message being printing, and also a variable a
appearing within the running MATLAB session.
Other - arguably more interesting - example scripts, which require images to be open, are provided within the Extensions → MATLAB → Groovy MATLAB samples menu.
The screenshot above shows an example of calling MATLAB's k-means clustering applied to features calculated using QuPath's cell detection and (smoothed) feature computations.
These docs are for QuPath ≤ v0.1.2.
For more up-to-date information, see https://qupath.readthedocs.io
- Video tutorials
- First steps
- Viewing images
- Drawing regions
- Counting cells
- Projects
- Multiple images
- Preferences
- Getting help
- Object-oriented analysis
- Types of object
- Object measurements
- Object classifications
- Object hierarchies
- Working with objects
- Workflows
- From workflows to scripts
- Writing custom scripts
- Advanced scripting with IntelliJ
- Scripting examples