CINXE.COM
Jython Scripting
<!DOCTYPE html> <html> <head> <title>Jython Scripting</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3" /> <meta content="ImageJ Wiki" property="og:site_name"> <meta content="Jython Scripting" property="og:title"> <meta content="article" property="og:type"> <meta content="The ImageJ wiki is a community-edited knowledge base on topics relating to ImageJ, a public domain program for processing and analyzing scientific images, and its ecosystem of derivatives and variants, including ImageJ2, Fiji, and others." property="og:description"> <meta content="https://imagej.github.io/scripting/jython/index" property="og:url"> <meta content="https://imagej.github.io/media/icons/imagej2.png" property="og:image"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> <meta name="msapplication-TileColor" content="#da532c"> <meta name="theme-color" content="#ffffff"> <link rel="stylesheet" href="/assets/css/lightbox.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"/> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.css" /> <link rel="stylesheet" href="/assets/css/main.css" /> <link rel="stylesheet" href="/assets/css/layout.css"/> <link rel="stylesheet" href="/assets/css/includes.css" /> <link rel="stylesheet" href="/assets/css/dock.css"/> <noscript><link rel="stylesheet" href="/assets/css/noscript.css" /></noscript> <link rel="stylesheet" href="/assets/css/page.css" /> </head> <body class="is-preload"> <!-- Top bar --> <section id="top-bar"> <a href="/"><img id="site-logo" src="/media/icons/imagej2.png"></a> <div id="search-panel"> <div id="search-box"></div> </div> </section> <!-- Page-info --> <div class="page-info"> <a href="https://github.com/imagej/imagej.github.io/commits/main/_pages/scripting/jython/index.md">Page history</a> <a href="https://github.com/imagej/imagej.github.io/edit/main/_pages/scripting/jython/index.md">Edit this page</a> <a href="/editing">How do I edit this website?</a><br><a href="https://imagej.net/imagej-wiki-static/Jython_Scripting">Original MediaWiki page</a></div> <section id="left-column" class="sidebar dock"> <!-- Menu --> <div class="menu dockable"> <div class="drag-handle"></div><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details open><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details open><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a href="/scripting/clojure">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a class="current-page">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a href="/develop/tips">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </section> <section id="right-column" class="sidebar dock"> <!-- Vital stats --> <!-- Table of contents --> <div id="toc" class="toc menu dockable"> <div class="drag-handle"></div> <h3>Page contents</h3> <ul data-toc="#content" data-toc-headings="h1,h2,h3,h4,h5,h6"></ul> </div> </section> <!-- Page title --> <div class="container"> <header class="major special"> <a class="project-icon shadowed-box" href="/software/imagej2"><span class="tooltip"><img src="/media/icons/imagej2.png"><span class="tooltiptext" style="top: 80%; left: 25%; width: 20em">This page describes content relating to the ImageJ2 platform. Click the logo for details.</span></span></a> <h1>Jython Scripting</h1> <span class="project-counterweight"> </span> </header> </div> <!-- Nav bar --> <!-- Main content --> <section id="page" class="main style1"> <div class="container"> <div class="box alt"></div> <div id="content" class="page-content"> <div class="notice" style="font-size: 2; background: #ebf2f8; border-left: 10px solid #67a1fe"><div class="notice-icon"><img src="/media/icons/info.svg" width="32"></div><div class="notice-content"><p>The content of this page has not been vetted since shifting away from MediaWiki. If you’d like to help, check out the <a href="/events/wiki-grand-opening/how-to-help">how to help guide</a>!</p> </div> </div> <div class="notice" style="font-size: 1; background: #e6e6e6; border-left: 10px solid gold"><div class="notice-content"><p>This page describes how to write scripts in <strong>Jython</strong>, the JVM-based flavor of Python. To call ImageJ functions from Python programs, see <a href="/scripting/pyimagej">PyImageJ</a>.</p> </div> </div> <h2 id="introduction">Introduction</h2> <p>Jython is an implementation of the Python programming language designed to run on the Java platform. <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> In ImageJ, Jython is one of several <a href="/scripting#supported-languages">supported languages</a>.</p> <h2 id="when-to-use-jython">When to use Jython</h2> <p>All scripting language supported by ImageJ can be used to access the <a href="https://javadoc.scijava.org/">ImageJ API</a>. There are only differences in how the imports are handled and in the syntax of the selected language. Jython has a syntax that differs from most other language as indentations instead of brackets are used to group code blocks.</p> <p>The following list will help you to decide if Jython is the right choice to create scripts for ImageJ:</p> <ul> <li>If you have experience with Python, you can easily use Jython for ImageJ scripting. But you have to keep in mind that tools commonly used in many Python projects (e.g. Numpy) are not available in Jython. By building your <a href="/scripting/jython#self-written-jython-modules-for-imagej">own modules</a> you can create complex scripts that otherwise are only possible by writing ImageJ plugins in Java.</li> <li>If don’t have any experience in programming, the Python language is a good choice to start with. If your only aim is to write scripts for ImageJ, there are other languages you should try first (e.g. <a href="/scripting/groovy">Groovy</a>).</li> <li>In Python, many problems can be solved with less code than in other languages. Nonetheless, the code is easy to read. Have a look at the examples on this page and decide if you want to start using Python for ImageJ scripting.</li> </ul> <h3 id="explanation">Explanation</h3> <p>The Java implementation of Python is limited to the <a href="https://docs.python.org/2/library/index.html">standard library</a> of Python 2.<br /> It is not possible to use external python modules (like Numpy…) however, <a href="/scripting/jython#importing-java-module-and-classes">any Java class residing in the Fiji installation can be used</a>.<br /> Even with the given limitations, Jython is a powerful language for ImageJ scripting. Hopefully the examples on this page can convince you of that.</p> <h2 id="jython-basics-for-imagej">Jython basics for ImageJ</h2> <div class="notice" style="font-size: 2; background: #ebf2f8; border-left: 10px solid #67a1fe"><div class="notice-icon"><img src="/media/icons/info.svg" width="32" /></div><div class="notice-content"><p>For an introduction in ImageJ scripting visit the page <a href="/scripting/basics">Scripting basics</a>.</p> </div> </div> <h3 id="introduction-1">Introduction</h3> <p>The aim of this page is not to teach how to program in Python. This purpose is much better fulfilled by the <a href="https://docs.python.org/2/library/index.html">documentation of Python 2</a>. The focus of this page is to show how features of the Python language can be useful for ImageJ scripting.</p> <p>That is why more complex examples are used that are fully functional. Just copy the code to the <a href="/scripting/script-editor">Script Editor</a> and try them by yourself. Extensive in-line documentation is used to explain the implementation.</p> <h3 id="hello-world">Hello World</h3> <h4 id="--with-print">- With print</h4> <p>There are 2 ways to print some information back to the user.<br /> The first one is a classical python print statement, that will print some information to the console.<br /> <code class="language-plaintext highlighter-rouge">print "Hello world"</code><br /> You can print any kind of variable and objects.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span> <span class="s">"This is a string followed by an int"</span><span class="p">,</span> <span class="mi">10</span> </code></pre></div></div> <p>NB1 : If used in a plugin, and no console window is open then the printed information will not be visible to the user (contrary to the <code class="language-plaintext highlighter-rouge">log</code> function below)</p> <p>NB2 : Using numerous print statements might slow down the execution time when used in a plugin (not observed when executing from the script interpreter).</p> <h4 id="--with-ijlog">- With IJ.log()</h4> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ij</span> <span class="kn">import</span> <span class="n">IJ</span> <span class="n">IJ</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="s">"Hello world"</span><span class="p">)</span> <span class="n">IJ</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="s">"This is a string followed by an int "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span> </code></pre></div></div> <p>Contrary to the print statement the log function display some output into a log window (newly open if not already open), and accept only a string as argument.</p> <h3 id="image-selection-using-the-genericdialog-class">Image selection using the GenericDialog class</h3> <p>This example script will create up to 10 new images and create a GenericDialog to select 3 of them. Finally the names of the selected images are printed to the Log window. It is recommended to copy the code to the <a href="/scripting/script-editor">Script Editor</a> and run it by yourself.</p> <p>The following list links to documentation of the used Python features:</p> <ul> <li><a href="https://docs.python.org/2/library/__future__.html">Future statement definitions</a></li> <li><a href="https://docs.python.org/2/library/functions.html">Built-in Functions</a></li> <li><a href="https://docs.python.org/2/library/stdtypes.html#str.join">str.join()-method</a></li> <li><a href="https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions">List Comprehensions</a></li> <li><a href="https://www.python.org/dev/peps/pep-0289/">Generator Expressions</a></li> <li><a href="http://stackoverflow.com/questions/36901/what-does-double-star-and-star-do-for-python-parameters"><code class="language-plaintext highlighter-rouge">**</code> (double star) and <code class="language-plaintext highlighter-rouge">*</code> (star) parameters</a></li> <li><a href="https://docs.python.org/2/library/%5F%5Fmain%5F%5F.html">Top-level script environment (<code class="language-plaintext highlighter-rouge">__main__</code>)</a></li> <li><a href="http://stackoverflow.com/questions/5893163/what-is-the-purpose-of-the-single-underscore-variable-in-python">Purpose of the single underscore <code class="language-plaintext highlighter-rouge">_</code> variable</a></li> </ul> <script src="https://emgithub.com/embed.js?target=https%3A%2F%2Fgithub.com%2Fimagej%2Fimagej-scripting%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fresources%2Fscript_templates%2FTutorials%2FWiki_Jython_Tutorial_1.py%23L1-99999&style=github&showBorder=on&showLineNumbers=on&showFileMeta=on&showCopy=on"></script> <h3 id="using-scripting-parameters">Using Scripting Parameters</h3> <p>The second example is inspired by atomic resolution images recorded with an Transmission Electron Microscope (TEM). Such images show a regular structure (a crystal), but the images are noisy because of the low signal. By using a Fourier filter the contrast can be enhanced.</p> <p>The script will create a periodic structure and add some random noise. The user can control the parameters of the created image. This is realized using <a href="/scripting/parameters">Script parameters</a>. The Fourier filtering has been created by using the <a href="/scripting/macro#the-recorder">Recorder</a>. Finally a simple image calculator is used to show that functions can be passed as parameters.</p> <p>This list links to the documentation of Python features that are introduced with this example:</p> <ul> <li><a href="https://docs.python.org/2/library/functions.html#zip">The zip() function</a></li> <li><a href="http://stackoverflow.com/questions/8421337/rotating-a-two-dimensional-array-in-python">Rotating a two-dimensional array</a></li> <li><a href="https://docs.python.org/2/reference/expressions.html#lambda">Lambda expressions</a></li> </ul> <script src="https://emgithub.com/embed.js?target=https%3A%2F%2Fgithub.com%2Fimagej%2Fimagej-scripting%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fresources%2Fscript_templates%2FTutorials%2FWiki_Jython_Tutorial_2.py%23L1-99999&style=github&showBorder=on&showLineNumbers=on&showFileMeta=on&showCopy=on"></script> <h3 id="a-batch-opener-using-oswalk">A batch opener using <code class="language-plaintext highlighter-rouge">os.walk()</code></h3> <p>We have yet introduced some powerful functions build into Python. Another one is <code class="language-plaintext highlighter-rouge">walk()</code> from the <code class="language-plaintext highlighter-rouge">os</code> module. It can be used to go through a directory structure and process the contained files. In this example <code class="language-plaintext highlighter-rouge">walk()</code> is used to batch open images with ImageJ’s function <code class="language-plaintext highlighter-rouge">openImage()</code>.</p> <p>To read more about the used features, the following list provides links to additional information:</p> <ul> <li><a href="https://docs.python.org/2/library/os.html#os.walk">The walk() function</a></li> <li><a href="https://docs.python.org/2/library/os.path.html">The documentation of os.path</a></li> <li><a href="https://docs.python.org/2/library/os.html#os.listdir">The listdir() function</a></li> <li><a href="http://javadoc.imagej.net/ImageJ1/">Javadoc on IJ.openImage()</a></li> <li><a href="https://docs.python.org/2/library/functions.html#isinstance">Testing the type of an object using isinstance()</a></li> <li><a href="https://docs.python.org/2/library/functions.html#type">Identifying the type of an object using type()</a></li> <li><a href="https://docs.python.org/2/reference/simple_stmts.html#continue">Using continue to control a loop</a></li> <li><a href="https://docs.python.org/2/library/stdtypes.html#truth-value-testing">Truth Value Testing</a></li> </ul> <script src="https://emgithub.com/embed.js?target=https%3A%2F%2Fgithub.com%2Fimagej%2Fimagej-scripting%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fresources%2Fscript_templates%2FTutorials%2FWiki_Jython_Tutorial_3.py%23L1-99999&style=github&showBorder=on&showLineNumbers=on&showFileMeta=on&showCopy=on"></script> <h2 id="importing-java-module-and-classes">Importing Java module and classes</h2> <p>Another great feature of Jython is the possibility to use functions from Java jar package that resides in the jar folder of imageJ.</p> <h3 id="imagej-and-fiji-api">ImageJ and Fiji API</h3> <p>The following API documentation lists all available modules and functions :</p> <ul> <li><a href="http://javadoc.scijava.org/ImageJ1/">ImageJ</a></li> <li><a href="http://javadoc.scijava.org/Fiji/">Fiji</a></li> </ul> <p>Those package are built-in with Fiji, but any package that resides in the jars folder can be imported provided you know the path to the class.</p> <p>For example, one of the main built-in ImageJ packages is called <code class="language-plaintext highlighter-rouge">ij</code>, and often Jython scripts will write something like this at the top:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ij</span> <span class="kn">import</span> <span class="n">IJ</span> <span class="c1"># do stuff below.... </span></code></pre></div></div> <p>Doing this allows you to access the <code class="language-plaintext highlighter-rouge">IJ</code> <em>class</em> which resides in the <code class="language-plaintext highlighter-rouge">ij</code> <em>package</em>. You can find a description of the <code class="language-plaintext highlighter-rouge">ij</code> package <a href="https://javadoc.scijava.org/ImageJ1/ij/package-summary.html">here</a>. What can we do with the <code class="language-plaintext highlighter-rouge">IJ</code> class? Clicking on the <code class="language-plaintext highlighter-rouge">IJ</code> link brings you to the <a href="https://javadoc.scijava.org/ImageJ1/ij/IJ.html">class documentation</a> page for <code class="language-plaintext highlighter-rouge">IJ</code>. This class contains “static utility methods” which means you can call them with without instantiating (calling the constructor) the <code class="language-plaintext highlighter-rouge">IJ</code> class. We will cover constructors later. Looking through the documentation for <code class="language-plaintext highlighter-rouge">IJ</code>, lets focus on the method <code class="language-plaintext highlighter-rouge">createImage</code> (<a href="https://javadoc.scijava.org/ImageJ1/ij/IJ.html#createImage-java.lang.String-int-int-int-int-">docs here</a>). This method can be called just like you would call a method on a python class. The documentation shows you need to provide the following parameters (types in parenthesis):</p> <ol> <li>title (string)</li> <li>width (int)</li> <li>height (int)</li> <li>depth (int)</li> <li>bitdepth (int)</li> </ol> <p>and it returns an <code class="language-plaintext highlighter-rouge">ImagePlus</code> object. <code class="language-plaintext highlighter-rouge">ImagePlus</code> objects are very important in ImageJ, and you will the documentation for them <a href="https://imagej.net/ij/developer/api/ij/ImagePlus.html">here</a>. Below is an example of how to import and use the static methods on the <code class="language-plaintext highlighter-rouge">IJ</code> class to create an image.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ij</span> <span class="kn">import</span> <span class="n">IJ</span> <span class="c1"># read this as: "from the ij package import the IJ class" </span><span class="n">test_img</span> <span class="o">=</span> <span class="n">IJ</span><span class="p">.</span><span class="n">createImage</span><span class="p">(</span><span class="s">"Test image"</span><span class="p">,</span> <span class="mi">512</span><span class="p">,</span> <span class="mi">512</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="c1"># now check the type of test_img </span><span class="k">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">test_img</span><span class="p">))</span> <span class="c1"># <type 'ij.ImagePlus'> </span></code></pre></div></div> <p>This code shows that we have successfully created an <code class="language-plaintext highlighter-rouge">ImagePlus</code> object. Looking at the documentation for the <a href="https://javadoc.scijava.org/ImageJ1/ij/ImagePlus.html">ImagePlus class</a>, let’s use a few of the methods to make sure the image was created correctly.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ij</span> <span class="kn">import</span> <span class="n">IJ</span> <span class="n">test_img</span> <span class="o">=</span> <span class="n">IJ</span><span class="p">.</span><span class="n">createImage</span><span class="p">(</span><span class="s">"Test image"</span><span class="p">,</span> <span class="mi">512</span><span class="p">,</span> <span class="mi">512</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="c1"># check the type: </span><span class="k">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">test_img</span><span class="p">))</span> <span class="c1"># <type 'ij.ImagePlus'> </span><span class="n">title</span> <span class="o">=</span> <span class="n">test_img</span><span class="p">.</span><span class="n">getTitle</span><span class="p">()</span> <span class="n">width</span> <span class="o">=</span> <span class="n">test_img</span><span class="p">.</span><span class="n">width</span> <span class="n">height</span> <span class="o">=</span> <span class="n">test_img</span><span class="p">.</span><span class="n">height</span> <span class="k">print</span><span class="p">(</span><span class="s">"{} is {} wide and {} tall."</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">))</span> <span class="n">test_img</span><span class="p">.</span><span class="n">show</span><span class="p">()</span> </code></pre></div></div> <p>We accessed the title using the <code class="language-plaintext highlighter-rouge">getTitle()</code> <a href="https://javadoc.scijava.org/ImageJ1https://imagej.net/ij/ImagePlus.html#getTitle--">method</a>, which takes no arguments and returns the image name. We accessed the image width and height by accessing <code class="language-plaintext highlighter-rouge">test_img</code>’s <strong>fields</strong>. These are not methods, but contain information about the class. We could have also used the <code class="language-plaintext highlighter-rouge">getWidth()</code> and <code class="language-plaintext highlighter-rouge">getHeight()</code> methods as well. We then called the <code class="language-plaintext highlighter-rouge">show()</code> method on our test image and a (very boring) 512X512 8 bit image should have popped up.</p> <p>Here is another example where we use the ImageJ package and the <a href="http://javadoc.scijava.org/ImageJ1https://imagej.net/ij/plugin/frame/RoiManager.html">RoiManager</a> class. According to the javadoc, the RoiManager class resides in <code class="language-plaintext highlighter-rouge">ij.plugin.frame</code>. Therefore the code will look like :</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ij.plugin.frame</span> <span class="kn">import</span> <span class="n">RoiManager</span> <span class="n">RM</span> <span class="o">=</span> <span class="n">RoiManager</span><span class="p">()</span> <span class="c1"># we create an instance of the RoiManager class </span><span class="n">rm</span> <span class="o">=</span> <span class="n">RM</span><span class="p">.</span><span class="n">getRoiManager</span><span class="p">()</span> <span class="c1"># "activate" the RoiManager otherwise it can behave strangely </span></code></pre></div></div> <h3 id="using-opencv-in-jython">Using openCV in Jython</h3> <p>It is even possible to use most of opencv functionalities within Jython/Fiji. There are several options (see the <a href="/software/opencv">wiki page about opencv</a>), yet the most straight forward is probably IJ-OpenCV which is available via the update sites. It will automatically download the necessary packages and dependencies in your Fiji installation.</p> <p>A manual installation is also possible by putting the jar packages in the jar folder of imageJ. They are available on the <a href="https://github.com/joheras/IJ-OpenCV">IJopenCV github</a>, which even provides a maven option.</p> <h4 id="matrices">Matrices</h4> <p>The first thing to know about OpenCV is that most functions work with an OpenCV matrix object. Fortunately, the IJ-OpenCV project provides some converters :</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#@ ImagePlus ImP </span><span class="kn">from</span> <span class="nn">ijopencv.ij</span> <span class="kn">import</span> <span class="n">ImagePlusMatConverter</span> <span class="kn">from</span> <span class="nn">ijopencv.opencv</span> <span class="kn">import</span> <span class="n">MatImagePlusConverter</span> <span class="kn">from</span> <span class="nn">ij</span> <span class="kn">import</span> <span class="n">ImagePlus</span> <span class="c1"># Convert ImagePlus (actually the contained ImageProcessor) to Matrix object </span><span class="n">imp2mat</span> <span class="o">=</span> <span class="n">ImagePlusMatConverter</span><span class="p">()</span> <span class="n">ImMat</span> <span class="o">=</span> <span class="n">imp2mat</span><span class="p">.</span><span class="n">toMat</span><span class="p">(</span><span class="n">imp</span><span class="p">.</span><span class="n">getProcessor</span><span class="p">())</span> <span class="k">print</span> <span class="n">ImMat</span> <span class="c1"># Convert Matrix object to ImageProcessor </span><span class="n">mat2ip</span> <span class="o">=</span> <span class="n">MatImagePlusConverter</span><span class="p">()</span> <span class="n">NewIP</span> <span class="o">=</span> <span class="n">mat2ip</span><span class="p">.</span><span class="n">toImageProcessor</span><span class="p">(</span><span class="n">ImMat</span><span class="p">)</span> <span class="n">NewImp</span> <span class="o">=</span> <span class="n">ImagePlus</span><span class="p">(</span><span class="s">"Matrix converted back to ImagePlus"</span><span class="p">,</span> <span class="n">NewIP</span><span class="p">)</span> <span class="k">print</span> <span class="n">NewImP</span> </code></pre></div></div> <p>Such kind of converter is also available for PointRoi to opencv keypoints…</p> <p>Now to use opencv function, we use the <a href="http://bytedeco.org/javacpp-presets/opencv/apidocs/">JavaCPP API</a> that contains almost all functions of opencv.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">org.bytedeco.javacpp.opencv_core</span> <span class="kn">import</span> <span class="n">Mat</span><span class="p">,</span> <span class="n">CvMat</span><span class="p">,</span> <span class="n">vconcat</span> <span class="c1">## Typical matrices ## </span> <span class="c1"># Identity Matrix of size (3x3) and type 8-bit </span><span class="n">Id</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">().</span><span class="n">eye</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">).</span><span class="n">asMat</span><span class="p">()</span> <span class="k">print</span> <span class="n">Id</span> <span class="k">print</span> <span class="n">CvMat</span><span class="p">(</span><span class="n">Id</span><span class="p">)</span> <span class="c1"># handy to visualise the matrix </span> <span class="c1"># Matrix of ones (3x3) </span><span class="n">One</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">().</span><span class="n">ones</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">).</span><span class="n">asMat</span><span class="p">()</span> <span class="c1"># Matrix of zeros (3x3) </span><span class="n">Zero</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">().</span><span class="n">zeros</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">).</span><span class="n">asMat</span><span class="p">()</span> <span class="c1"># Custom Matrices # 1D-Matrix can be initialize from a list # For 2D (or more) we have to concatenate 1D-Matrices </span> <span class="n">Row1</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">])</span> <span class="c1"># 1D matrix </span><span class="n">Row2</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">([</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">])</span> <span class="n">TwoColumn</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">()</span> <span class="c1"># initialise output </span><span class="n">vconcat</span><span class="p">(</span><span class="n">Col1</span><span class="p">,</span> <span class="n">Col2</span><span class="p">,</span> <span class="n">TwoColumn</span><span class="p">)</span> <span class="c1"># output stored in TwoColumn </span><span class="k">print</span> <span class="n">CvMat</span><span class="p">(</span><span class="n">TwoColumn</span><span class="p">)</span> <span class="o"><</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s">"notice"</span> <span class="n">style</span><span class="o">=</span><span class="s">"font-size: 2; background: #ffcccb; border-left: 10px solid #f57900"</span><span class="o">><</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s">"notice-icon"</span><span class="o">><</span><span class="n">img</span> <span class="n">src</span><span class="o">=</span><span class="s">"/media/icons/warning.png"</span><span class="o">></</span><span class="n">div</span><span class="o">><</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s">"notice-content"</span><span class="o">><</span><span class="n">p</span><span class="o">></span><span class="n">The</span> <span class="o"><</span><span class="n">code</span> <span class="n">class</span><span class="o">=</span><span class="s">"language-plaintext highlighter-rouge"</span><span class="o">></span><span class="n">org</span><span class="p">.</span><span class="n">bytedeco</span><span class="p">.</span><span class="n">javacpp</span><span class="p">.</span><span class="n">opencv_core</span><span class="p">.</span><span class="n">Mat</span><span class="o"></</span><span class="n">code</span><span class="o">></span> <span class="nb">object</span> <span class="ow">is</span> <span class="n">different</span> <span class="n">than</span> <span class="n">the</span> <span class="o"><</span><span class="n">code</span> <span class="n">class</span><span class="o">=</span><span class="s">"language-plaintext highlighter-rouge"</span><span class="o">></span><span class="n">org</span><span class="p">.</span><span class="n">opencv</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">Mat</span><span class="o"></</span><span class="n">code</span><span class="o">></span> <span class="err">!!</span> <span class="n">They</span> <span class="n">don</span><span class="err">’</span><span class="n">t</span> <span class="n">have</span> <span class="n">exactly</span> <span class="n">the</span> <span class="n">same</span> <span class="n">attributes</span> <span class="ow">and</span> <span class="n">functions</span><span class="p">.</span> <span class="n">In</span> <span class="n">Fiji</span> <span class="n">you</span> <span class="n">should</span> <span class="n">always</span> <span class="n">use</span> <span class="n">the</span> <span class="n">objects</span> <span class="k">from</span> <span class="o"><</span><span class="n">code</span> <span class="n">class</span><span class="o">=</span><span class="s">"language-plaintext highlighter-rouge"</span><span class="o">></span><span class="n">org</span><span class="p">.</span><span class="n">bytedeco</span><span class="p">.</span><span class="n">javacpp</span><span class="o"></</span><span class="n">code</span><span class="o">></span><span class="p">.</span><span class="o"></</span><span class="n">p</span><span class="o">></span> <span class="o"></</span><span class="n">div</span><span class="o">></span> <span class="o"></</span><span class="n">div</span><span class="o">></span> </code></pre></div></div> <p>Similarly there is some apparent redudancy for the function in the javacpp API.</p> <p>ex : Transform exists in 3 different places :</p> <ul> <li><code class="language-plaintext highlighter-rouge">org.opencv.core.Core.transform</code></li> </ul> <p>This one takes <code class="language-plaintext highlighter-rouge">org.opencv.core.Mat</code> as input. It is currently challenging to have such object in Fiji.</p> <ul> <li><code class="language-plaintext highlighter-rouge">org.bytedeco.javacpp.opencv_core.cvTransform</code></li> </ul> <p>using <code class="language-plaintext highlighter-rouge">CvArr</code> as input, but even if you manage to convert your input as a <code class="language-plaintext highlighter-rouge">CvArr</code> it crashes Fiji. Apparently it is a deprecated version.</p> <ul> <li><code class="language-plaintext highlighter-rouge">org.bytedeco.javacpp.opencv_core.transform</code></li> </ul> <p>That’s the one to use ! It takes only <code class="language-plaintext highlighter-rouge">org.bytedeco.javacpp.opencv_core.Mat</code> as input, which is the most appropriate in Fiji/Jython</p> <h4 id="scalar">Scalar</h4> <p>In addition to Matrices, opencv allows to use Scalar objects A scalar is a 4 item element (v0, v1, v2, v3). If v1=v2=v3=0 then the Scalar is real.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">org.bytedeco.javacpp.opencv_core</span> <span class="kn">import</span> <span class="n">Scalar</span> <span class="c1"># Real scalar can be initiated with a float parameters </span><span class="n">Number</span> <span class="o">=</span> <span class="n">Scalar</span><span class="p">(</span><span class="mf">5.0</span><span class="p">)</span> <span class="n">Number</span> <span class="o">=</span> <span class="n">Scalar</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span> <span class="k">print</span> <span class="n">Number</span> <span class="c1"># Using an integer as parameter has a different meaning </span><span class="n">Empty</span> <span class="o">=</span> <span class="n">Scalar</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># This initiate an empty Scalar object of size 5 </span><span class="k">print</span> <span class="n">Empty</span> <span class="c1"># Alternatively one can set the other values of the Scalar </span><span class="n">Complex</span> <span class="o">=</span> <span class="n">Scalar</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span> <span class="k">print</span> <span class="n">Complex</span> </code></pre></div></div> <h4 id="operations">Operations</h4> <p>It is possible to perform some operations between matrices, or between Scalar and matrices.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">org.bytedeco.javacpp.opencv_core</span> <span class="kn">import</span> <span class="n">Scalar</span><span class="p">,</span> <span class="n">Mat</span><span class="p">,</span> <span class="n">subtract</span> <span class="n">A</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">])</span> <span class="n">B</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">3</span><span class="p">,</span><span class="o">-</span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="p">])</span> <span class="n">Number</span> <span class="o">=</span> <span class="n">Scalar</span><span class="p">(</span><span class="mf">10.0</span><span class="p">)</span> <span class="c1">## Number - B ( B-Number is also possible) </span><span class="n">Expr</span> <span class="o">=</span> <span class="n">subtract</span><span class="p">(</span><span class="n">Number</span><span class="p">,</span><span class="n">B</span><span class="p">)</span> <span class="k">print</span> <span class="n">CvMat</span><span class="p">(</span><span class="n">Expr</span><span class="p">.</span><span class="n">asMat</span><span class="p">())</span> <span class="c1">## A - B </span><span class="n">Out</span> <span class="o">=</span> <span class="n">Mat</span><span class="p">()</span> <span class="n">subtract</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">B</span><span class="p">,</span><span class="n">Out</span><span class="p">)</span> <span class="k">print</span> <span class="n">CvMat</span><span class="p">(</span><span class="n">Out</span><span class="p">)</span> </code></pre></div></div> <h2 id="self-written-jython-modules-for-imagej">Self written Jython modules for ImageJ</h2> <p>In Jython you can write all commands line by line in a single file and execute it. To create a neat program, <a href="https://docs.python.org/2/tutorial/controlflow.html#defining-functions">functions</a> and <a href="https://docs.python.org/2/tutorial/classes.html">classes</a> can be used to structure code. To prevent using copy&past for regularly used functions and classes, <a href="https://docs.python.org/2/tutorial/modules.html">modules</a> are the way to choose. Modules are files that contain functions and classes to import into other files.</p> <p>To load modules, one has to save them to a directory where Jython will find them. Two lines of code will reveal these directories to you:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">path</span> <span class="k">print</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> </code></pre></div></div> <p>When running this code the result is an output like</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>['/home/michael/Software/ImageJ.app/jars/Lib', '/home/michael/Software/ImageJ.app/jars/jython-shaded-2.7.0.jar/Lib', '__classpath__', '__pyclasspath__/'] </code></pre></div></div> <p>This tells us that the folder <code class="language-plaintext highlighter-rouge">jars/Lib/</code> inside our ImageJ/Fiji directory is the right place to save modules. As <code class="language-plaintext highlighter-rouge">Lib/</code> does not exist by default, we have to create it.</p> <p>When a module is imported for the first time, Jython will compile it to Java code. If there is a module named <code class="language-plaintext highlighter-rouge">myModule.py</code>, Jython will create a file called <code class="language-plaintext highlighter-rouge">myModule$py.class</code>. The next time the module is imported, the jython interpreter uses the <code class="language-plaintext highlighter-rouge">.class</code> file instead of the <code class="language-plaintext highlighter-rouge">.py</code> file, even if this <code class="language-plaintext highlighter-rouge">.py</code> file was modified.</p> <p>To force the interpreter to use the last version of the py script there are 2 possibilities :</p> <ul> <li>Close Fiji, delete the <code class="language-plaintext highlighter-rouge">myModule$py.class</code> file and restart Fiji</li> <li>Use the following lines of code (found at <a href="http://stackoverflow.com/questions/10531920/jython-import-or-reload-dynamically">stackoverflow</a>) that will force Jython to recompile all modules</li> </ul> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Use this to recompile Jython modules to class files. </span><span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">modules</span> <span class="n">modules</span><span class="p">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># Imports of Jython modules are placed below: </span><span class="kn">import</span> <span class="nn">myModule</span> </code></pre></div></div> <h3 id="adding-a-custom-directory">Adding a custom directory</h3> <p>If you don’t want to use <code class="language-plaintext highlighter-rouge">jars/Lib/</code> to save your modules, you have to extend the array <code class="language-plaintext highlighter-rouge">sys.path</code>:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">path</span> <span class="kn">from</span> <span class="nn">java.lang.System</span> <span class="kn">import</span> <span class="n">getProperty</span> <span class="c1"># extend the search path by $FIJI_ROOT/bin/ # 'fiji.dir' works for plain ImageJ, too. </span><span class="n">path</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">getProperty</span><span class="p">(</span><span class="s">'fiji.dir'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'/bin'</span><span class="p">)</span> <span class="c1"># an alternative can be the users home directory # path.append(getProperty('user.home') + '/JythonModules') </span> <span class="c1"># Now you can import $FIJI_ROOT/bin/myModule.py </span><span class="kn">import</span> <span class="nn">myModule</span> </code></pre></div></div> <p>The function <code class="language-plaintext highlighter-rouge">getProperty()</code> accepts many more strings. A list can be found at <a href="https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html">The Java Tutorials</a>.</p> <h2 id="self-written-jython-packages-for-imagej">Self written Jython packages for ImageJ</h2> <p>On the way to perfectly organize Jython code, <a href="https://docs.python.org/2/tutorial/modules.html#packages">packages</a> are the next step. A Jython package is a folder that contain a set of modules scripts together with a <code class="language-plaintext highlighter-rouge">__init__.py</code> file. This file can be empty. Below is a typical structure for the <code class="language-plaintext highlighter-rouge">ImageJ.app/jars/Lib</code> folder:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ImageJ.app/jars/Lib/ -- myModule.py -- myPackage/ -- __init__.py -- mathTools.py -- customFilters.py -- fftTools.py -- myPackage2/ -- __init__.py -- mathTools.py -- stackProcessing.py </code></pre></div></div> <p>There are two packages and one module. The first package contains three modules and the second package contains two modules. We can import the modules on different ways:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Import the single module using the default name: </span><span class="kn">import</span> <span class="nn">myModule</span> <span class="c1"># Import mathTools from the first package </span><span class="kn">import</span> <span class="nn">myPackage.mathTools</span> <span class="c1"># Use a function from the imported module </span><span class="n">myPackage</span><span class="p">.</span><span class="n">mathTools</span><span class="p">.</span><span class="n">aFunction</span><span class="p">()</span> <span class="c1"># Import mathTools from the second package </span><span class="kn">from</span> <span class="nn">myPackage2</span> <span class="kn">import</span> <span class="n">mathTools</span> <span class="c1"># Use a function from the imported module without prefixing the package </span><span class="n">mathTools</span><span class="p">.</span><span class="n">aFunction</span><span class="p">()</span> <span class="c1"># Import customFilters from the first package and rename it </span><span class="kn">from</span> <span class="nn">myPackage</span> <span class="kn">import</span> <span class="n">customFilters</span> <span class="k">as</span> <span class="n">filters</span> <span class="c1"># Use a function from customFilters.py </span><span class="n">filters</span><span class="p">.</span><span class="n">aFunction</span><span class="p">()</span> <span class="c1"># Importing all module from a package </span><span class="kn">from</span> <span class="nn">myPackage2</span> <span class="kn">import</span> <span class="o">*</span> <span class="c1"># The next line will fail </span><span class="n">stackProcessing</span><span class="p">.</span><span class="n">aFunction</span><span class="p">()</span> </code></pre></div></div> <p>The reason for the last import to fail is the empty <code class="language-plaintext highlighter-rouge">__init__.py</code>. We have to define which modules of the package are imported when using <code class="language-plaintext highlighter-rouge">import *</code>. This is done by setting the variable <code class="language-plaintext highlighter-rouge">__all__</code> in the <code class="language-plaintext highlighter-rouge">__init__.py</code>. For <code class="language-plaintext highlighter-rouge">myPackage2</code> this line of code is needed:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">"mathTools"</span><span class="p">,</span> <span class="s">"stackProcessing"</span><span class="p">]</span> </code></pre></div></div> <p>Besides setting this variable, the <code class="language-plaintext highlighter-rouge">__init__.py</code> file can contain normal Jython code that is executed upon import of the package.</p> <h2 id="bundle-packages-in-a-jar-file">Bundle packages in a JAR file</h2> <p>An interesting feature of Jython is to search for packages and modules inside of <a href="https://en.wikipedia.org/wiki/JAR_(file_format)">JAR (file format)</a>. The folder structure from the last section can be modified by packing everything into a single <code class="language-plaintext highlighter-rouge">myPackages.jar</code>. The name of the JAR file doesn’t matter. All imports work the same as explained before.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ImageJ.app/jars/Lib/ -- myPackages.jar -- myModule.py -- myPackage/ -- __init__.py -- mathTools.py -- customFilters.py -- fftTools.py -- myPackage2/ -- __init__.py -- mathTools.py -- stackProcessing.py </code></pre></div></div> <p>The advantage of this approach is that you can share your packages easily. For example you can upload the JAR file to an <a href="/update-sites">update site</a>. It is possible to upload .py scripts to update sites too, without packaging into a jar. The advantage of jar are that they allow to define dependencies more systematically.</p> <div class="notice" style="font-size: 2; background: #e6e6e6; border-left: 10px solid #901913"><div class="notice-icon"><img src="/media/icons/note.svg" width="32" /></div><div class="notice-content"> </div> </div> <p>Contrary to the scripts in Jars/Lib, the menu macro scripts are not compiled, and as explained above they can not be imported in other scripts since the Plugin folder do not reside in the Jython search path by default.</p> <p>This is the reason why a given project is rather distributed in 2 different jar files as explained <a href="http://forum.imagej.net/t/using-self-written-jython-modules-in-imagej/2280">here</a>.</p> <h3 id="using-maven-to-build-packages">Using maven to build packages</h3> <p>Using maven you can automate the packaging of Jython code into JAR files. This approach is only recommended if you already use maven, as installing and learning how to use maven is not worth the time saving of automated packaging.</p> <p>At GitHub you will find an <a href="https://github.com/m-entrup/imagej-jython-package">example project</a> that you can use as a template. Just run <code class="language-plaintext highlighter-rouge">mvn package</code> and maven will generate a JAR file at the <code class="language-plaintext highlighter-rouge">target</code> directory.</p> <h2 id="links">Links</h2> <ul> <li><a href="/scripting/jython/examples">Jython Scripting Examples</a></li> <li><a href="/tutorials/imagej2-python">ImageJ2 Python Scripts</a></li> <li><a href="https://syn.mrc-lmb.cam.ac.uk/acardona/fiji-tutorial/">A Fiji Scripting Tutorial by Albert Cardona</a></li> <li><a href="https://wiki.cmci.info/documents/120206pyip_cooking/python_imagej_cookbook">Jython scripting cookbook</a></li> <li><a href="https://github.com/imagej/tutorials/tree/-/howtos/src/main/java/howto">ImageJ2 tutorials repository</a></li> </ul> <h2 id="references">References</h2> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:1" role="doc-endnote"> <p><a href="https://imagej.net/ij/plugins/index.html">Wikipedia entry on Jython</a>. Accessed: 2016-08-30 <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p> </li> </ol> </div> </div> </div> </section> <!-- Footer --> <section id="footer"> <ul class="icons"> <li><a href="https://forum.image.sc/tag/imagej" class="icon alt"><img src="/media/icons/image-sc.png" width="24" style="vertical-align: middle; margin-top: -10px"><span class="label">Forum</span></a></li> <li><a href="https://twitter.com/hashtag/ImageJ" class="icon brands alt fa-twitter"><span class="label">Twitter</span></a></li> <li><a href="https://github.com/imagej" class="icon brands alt fa-github"><span class="label">GitHub</span></a></li> </ul> <ul class="copyright"> <li>Design: <a href="http://html5up.net">HTML5 UP</a></li> </ul> </section> <!-- Hamburger menu --> <nav role="navigation"> <div id="ham-toggle"> <input type="checkbox" /> <span></span> <!-- top bun --> <span></span> <!-- hamburger --> <span></span> <!-- bottom bun --> <ul id="ham-menu"> <div class="menu"><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details open><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details open><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a href="/scripting/clojure">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a class="current-page">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a href="/develop/tips">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </ul> </div> </nav> <div id="dock-overlay-left" class="dock-overlay" data-dock-target="left-column"></div> <div id="dock-overlay-right" class="dock-overlay" data-dock-target="right-column"></div> <!-- Search results --> <div id="search-results"> <div id="search-hits"></div> <div id="pagination"></div> </div> <!-- Scripts --> <!-- Libraries --> <script src="/assets/js/jquery.min.js"></script> <script src="/assets/js/jquery.scrolly.min.js"></script> <script src="/assets/js/browser.min.js"></script> <script src="/assets/js/breakpoints.min.js"></script> <script src="/assets/js/util.js"></script> <script src="/assets/js/jquery.toc.js"></script> <script src="/assets/js/lightbox.min.js"></script> <!-- Extensions --> <!-- Site code --> <script src="/assets/js/main.js"></script> <script src="/assets/js/dock.js"></script> <script src="/assets/js/code.js"></script> <!-- Anchors --> <script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script> <script>anchors.add('#page h1, #page h2, #page h3, #page h4, #page h5, #page h6');</script> <!-- Citations --> <script src="https://cdn.jsdelivr.net/npm/citation-js@0.4.0-9"></script> <script src="/assets/js/cite.js"></script> <!-- Search --> <script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.13.0/dist/algoliasearch-lite.umd.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.40.3/dist/instantsearch.production.min.js"></script> <script src="/assets/js/search.js"></script> <script src="/assets/js/search-tweaks.js"></script> </body> </html>