Skip to content, Skip to search

Changes

Jython Scripting

6,589 bytes added, 04:03, 11 December 2018
m
Links: Add aditional link
{{GitHubEmbed|org=imagej|repo=imagej-scripting|path=src/main/resources/script_templates/Tutorials/Wiki_Jython_Tutorial_3.py}}
 
== Importing Java module and classes ==
Another great feature of Jython is the possibility to use functions from Java jar package that resides in the jar folder of imageJ.
 
=== ImageJ and Fiji API ===
 
The following API documentation lists all available module and functions :
* [http://javadoc.scijava.org/ImageJ1/ ImageJ]
* [http://javadoc.scijava.org/Fiji/ Fiji]
 
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.
 
Let's show one example with the ImageJ package and the class [http://javadoc.scijava.org/ImageJ1/ij/plugin/frame/RoiManager.html RoiManager]. According to the javadoc the RoiManager class resides in <code>ij.plugin.frame</code>. Therefore the code will look like :
 
<source lang="python">
from ij.plugin.frame import RoiManager
RM = RoiManager() # we create an instance of the RoiManager class
rm = RM.getRoiManager() # "activate" the RoiManager otherwise it can behave strangely
</source>
 
=== Using openCV in Jython ===
It is even possible to use most of opencv functionalities within Jython/Fiji. There are several options (see the [https://imagej.net/OpenCV wiki page about opencv]), 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.
 
A manual installation is also possible by putting the jar packages in the jar folder of imageJ. They are avalaible on the [https://github.com/joheras/IJ-OpenCV IJopenCV github], which even provides a maven option.
 
==== Matrices ====
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 :
 
<source lang="python">
#@ ImagePlus ImP
from ijopencv.ij import ImagePlusMatConverter
from ijopencv.opencv import MatImagePlusConverter
from ij import ImagePlus
 
# Convert ImagePlus (actually the contained ImageProcessor) to Matrix object
imp2mat = ImagePlusMatConverter()
ImMat = imp2mat.toMat(imp.getProcessor())
print ImMat
 
# Convert Matrix object to ImageProcessor
mat2ip = MatImagePlusConverter()
NewIP = mat2ip.toImageProcessor(ImMat)
NewImp = ImagePlus("Matrix converted back to ImagePlus", NewIP)
print NewImP
</source>
 
Such kind of converter is also available for PointRoi to opencv keypoints...
 
Now to use opencv function, we use the [http://bytedeco.org/javacpp-presets/opencv/apidocs/ JavaCPP API] that contains almost all functions of opencv.
<source lang="python">
from org.bytedeco.javacpp.opencv_core import Mat, CvMat, vconcat
 
## Typical matrices ##
 
# Identity Matrix of size (3x3) and type 8-bit
Id = Mat().eye(3,3,0).asMat()
print Id
print CvMat(Id) # handy to visualise the matrix
 
# Matrix of ones (3x3)
One = Mat().ones(3,3,0).asMat()
 
# Matrix of zeros (3x3)
Zero = Mat().zeros(3,3,0).asMat()
 
# Custom Matrices
# 1D-Matrix can be initialize from a list
# For 2D (or more) we have to concatenate 1D-Matrices
 
Row1 = Mat([1,2,3,4,5]) # 1D matrix
Row2 = Mat([6,7,8,9,10])
 
TwoColumn = Mat() # initialise output
vconcat(Col1, Col2, TwoColumn) # output stored in TwoColumn
print CvMat(TwoColumn)
</source>
 
{{Warning | The <code>org.bytedeco.javacpp.opencv_core.Mat</code> object is different than the <code>org.opencv.core.Mat</code> !! They don't have exactly the same attributes and functions. In Fiji you should always use the objects from <code>org.bytedeco.javacpp</code>.}}
 
 
Similarly there is some apparent redudancy for the function in the javacpp API.
 
ex : Transform exists in 3 different places :
* <code>org.opencv.core.Core.transform</code>
This one takes <code>org.opencv.core.Mat</code> as input. It is currently challenging to have such object in Fiji.
 
* <code>org.bytedeco.javacpp.opencv_core.cvTransform</code>
using <code>CvArr</code> as input, but even if you manage to convert your input as a <code>CvArr</code> it crashes Fiji. Apparently it is a deprecated version.
 
* <code>org.bytedeco.javacpp.opencv_core.transform</code>
That's the one to use ! It takes only <code>org.bytedeco.javacpp.opencv_core.Mat</code> as input, which is the most approriate in Fiji/Jython
 
 
==== Scalar ====
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.
 
<source lang="python">
from org.bytedeco.javacpp.opencv_core import Scalar
 
# Real scalar can be initiated with a float parameters
Number = Scalar(5.0)
Number = Scalar(float(5))
print Number
 
# Using an integer as parameter has a different meaning
Empty = Scalar(5) # This initiate an empty Scalar object of size 5
print Empty
 
# Alternatively one can set the other values of the Scalar
Complex = Scalar(1,2,3,4)
print Complex
</source>
 
 
==== Operations ====
It is possible to perform some operations between matrices, or between Scalar and matrices.
 
<source lang="python">
from org.bytedeco.javacpp.opencv_core import Scalar, Mat, subtract
 
A = Mat([1,2,3,4,5])
B = Mat([1,2,-3,-4,0])
 
Number = Scalar(10.0)
 
## Number - B ( B-Number is also possible)
Expr = subtract(Number,B)
print CvMat(Expr.asMat())
 
## A - B
Out = Mat()
subtract(A,B,Out)
print CvMat(Out)
</source>
== Self written Jython modules for ImageJ ==
<source lang='python'>
['/home/michael/Software/ImageJ.app/jars/Lib', '/home/michael/Software/ImageJ.app/jars/jython-shaded-2.57.30.jar/Lib', '__classpath__', '__pyclasspath__/']
</source>
</source>
The advantage of this approach is that you can share your packages easily. For example you can upload the JAR file to an [[Update_Sites|update site]]. 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.  '''NB''' : Script implementing "ImageJ menu macro" and "utilitary scripts" that are used as imported modules in other macros '''should be packed in separate jar files''' ! Indeed, if not explicitly mentioned, the jython interpreter only looks in the Jars/Lib folder to import module, so the .jar containing the "utilitary scripts" should be put there, while the jar containing the "ImageJ menu macro" can be put either in the Plugin or script/Plugin folder in order to appear in the ImageJ menu.
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.
This is the reason why a given project is rather distributed in 2 different jar files as explained [http://forum.imagej.net/t/using-self-written-jython-modules-in-imagej/2280 here].
=== Using maven to build packages ===
* [[Jython_Scripting_Examples|Jython Scripting Examples]]
* [[ImageJ2_Python_Scripts|ImageJ2 Python Scripts]]
* [https://www.ini.uzh.ch/~acardona/fiji-tutorial/ A Fiji Scripting Tutorial by Albert Cardona]
* [http://wiki.cmci.info/documents/120206pyip_cooking/python_imagej_cookbook Jython scripting cookbook]
== References ==
<references />
Emailconfirmed
88
edits