Use openCV within Jython macro

python
opencv
Tags: #<Tag:0x00007fa307d2e978> #<Tag:0x00007fa307d2e630>

#1

Hello,
I would like to use openCV in my Jython macros, just like I use it in Python scripts.
I have seen some java implementation of the library (JavaCV) and some ImageJ packages (CVForge, IJ-OpenCV) so I have kind of understood that I could use it by writting java plugin, but as I am not really familiar with Java I would prefer a Jython binding.
Still I have tried putting those jar file in my jython path and import them, but I always ran into some issue.
A detailled procedure would be highly appreciated.
Thank you very much !


Value from DoublePointer openCV/Jython
Does ImageJ Utilize the GPU?
#2

With the IJ-OpenCV-plugins update site enabled, you can convert your ImagePlus to an OpenCV Mat object as follows:

#@ ImagePlus imp

from ijopencv import ImageConverter

converter = ImageConverter()
m = converter.convertTo(imp)

print m

which will print something like:

org.bytedeco.javacpp.opencv_core$Mat[width=256,height=254,depth=8,channels=1]

When trying this, I noticed that the version of IJOpenCV.jar served by the update site seems to be different from the current master branch of https://github.com/joheras/IJ-OpenCV. Maybe @joheras can shed some light on this…


With the current version from the master branch, I’d expect something along these lines to work:

from ijopencv.ij import ImagePlusMatConverter
from ijopencv.opencv import MatImagePlusConverter
from org.bytedeco.javacpp.opencv_core import Mat

imp2mat = ImagePlusMatConverter()
mat2imp = MatImagePlusConverter()

m = imp2mat.convertTo(imp, Mat.class)

(taking Adaptive_ThresholdJ as an example)


Value from DoublePointer openCV/Jython
#3

Did it work in the end @imagejan or was there an issue?? Since this plugin is based on javacpp I’m curious whether it distributes it’s own version of javacpp or is compatible with the old version of javacpp that is distributed with Fiji.


#4

I only tried the script above with the current version served by the update site, and that worked fine (i.e. the conversion; I didn’t test anything else).

Good point. AFAICT, the update site ships its own version of javacpp:

Again, I didn’t test anything else yet, sorry. But I agree it would be nice to avoid that update sites serve artifcacts shading older versions from the ImageJ and Java-8 update sites…


#5

Thanks very much again Jan for your answer.
I was confused by the import statements, and by where to put the jar files.
So any jar in the plugin folder is accessible by Jython then ?

Still a bit puzzling I succesfully used the following line of import
from org.bytedeco.javacpp.opencv_imgproc import matchTemplate
Although when I browse the javacpp.jar I do find the folder structure org>bytedeco>javacpp but then where does the opencv_imgproc comes from ? same for opencv_core

Especially I am used to the dir() command to find out what is available in the module, but there this is not working, the only ouptut is the attribute _name_
import org.bytedeco.javacpp as javacpp
print dir(javacpp)
So I am wondering how to find the function I need… Is there an API reference ?


#6

dir() is a python-specific command, OpenCV is written in C++, and javacpp bridged this to Java. I don’t know the details of how all this works, but I don’t find it that surprising that dir() doesn’t work when using C++ libraries from Java… Maybe others have experience with this and/or can suggest alternatives??

AFAICT, these are defined in the javacpp-presets project:

You might want to have a look at the javacpp-presets API here:

http://bytedeco.org/javacpp-presets/opencv/apidocs/

I’m not sure which version Fiji and/or the IJ-OpenCV update site are using though. @bnorthan might know.


#7

Currently Fiji is shipping with javacpp-0.11, which seems to be a pretty old version. More info here


#8

Now that the coding part is functional, I am coming back to discuss about how to deal with the dependencies and version issues. I am using Maven to generate my Jar, and it is apparently quite good to declare dependencies.
On one hand, in the case of IJ-openCV it is shipped with a nice dependency declaration to add in the pom.xml

  <dependency>
    <groupId>io.github.joheras</groupId>
    <artifactId>IJ-OpenCV</artifactId>
    <version>1.0</version>
  </dependency>

On the other hand, I read on the wiki that the updater is capable of handling dependencies as well.

So I have a few question about that :

  1. If I declare the dependencies within the pom, does the resulting jar will directly contain the dependencies ?
    I guess not since all imageJ plugin declare the ij dependency, and if two plugin share the same dependency it will be duplicating the information for nothing.

  2. So does the updater actually determine the dependencies by reading the pom.xml ?
    That would make sense to me, as the pom is part of the jar…

  3. I need to ship 2 jar files as describe here. One that goes to the Jars/Lib and another one to scripts/Plugins.
    My question is how do I tell the updater to put them in the correct folders ? There is a reference to multiple Jars distribution but it is not really clear to me where this pom should go, and if I still compile them independently.


#9

No. As you figured yourself, including the dependencies in a single jar file (a so-called Uber-JAR or fat jar) would quickly lead to duplicate classes on the class path, and other related problems. That’s why we try to avoid Uber-JARs in the SciJava/ImageJ universe.

Yes. If you built your jar with Maven, the updater will be able to inspect the artifact and know about the dependencies of your plugin.

You should distinguish two things:

  • The build process, where Maven can ensure to copy all dependencies into the correct place of your local ImageJ installation (via the maven-imagej-plugin, see below).
  • The update/upload process, where the ImageJ Updater uploads jar files (and their dependencies, if required) onto an update site, keeping the relative locations the same as in your local installation.

In order to get the dependencies into the correct place, it should be sufficient to run:

mvn -Dimagej.app.directory=/path/to/your/Fiji.app

or, if you need to override artifacts (that are already served by the ImageJ or Java-8 update sites) with newer versions:

mvn -Dimagej.app.directory=/path/to/your/Fiji.app -Dimagej.deleteOtherVersions=older

See also:


#10

Calling the following command
mvn -Dimagej.app.directory=C:\Users\Laurent Thomas\Desktop\FIJI_Blank\Fiji.app
Return the following error :

[ERROR] No plugin found for prefix '.app.directory=C' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (C:\Users\Laurent Thomas\.m2\repository), central (https://repo.maven.apache.org/maven2)] -> [Help 1]

I also tried to do the compilation in Eclipse directly, setting the 2 arguments as stated in the previous link. The compilation succeed but I can’t see any new jar in the JARS folder. I used a fresh installation of Fiji so if the dependencies were properly copied I should find ij-opencv.jar and javacv.jar or similar names I guess…


#11

Do you point to your source code on github already? I couldn’t find it, but it would certainly help troubleshooting, and in particular help answering these questions:

  • What version of pom-scijava do you use as parent? It should be 19.4.0 19.2.0 to match with current Fiji, or 21.0.0 if you want to use other components at their latest release state.
  • Can you also try putting the path in quotes ("") to account for the space in your path?

#12

I use the template pom.xml from Building a pom. So it was 12.0.0.
With 19.4.0, I have
[ERROR] Non-resolvable parent POM...

The quotes do not help neither…
I have put the source code in a small repository which mimicks this imagej-jython-package repository


#13

Sorry, my mistake. I meant 19.2.0. Please see the available versions here, or on maven.imagej.net.


#14

Well neither 19.2.0 nor 21.0.0 worked :disappointed_relieved:
Could it be related to this post ?


#15

I just cloned your github repo, and after changing this line:

to:

<version>19.2.0</version>

running mvn works just fine for me.


What versions of Maven and Java does your system report?

mvn -version

#16

Apache Maven 3.5.3
Java 1.8.0_162

Yes, the compilation works but I was trying to have the dependencies automatically put into the Fiji application folder, which still returns the
[ERROR] No plugin found for prefix '.app.directory=C'
Maybe I am missing something in my maven configuration ?

I just realised that in the release tab, the compiled jar is the same than the one of the fiji updater. I was worried that declaring dependencies in the pom might point to the version of the master branch.
That’s why I was trying to have my dependencies being copied into FIJI by maven so that I could test it properly.
Currently installing IJ-openCV via the updater is enough to fullfill my dependency requirements, so I guess this should do the job :

  <dependency>
    <groupId>io.github.joheras</groupId>
    <artifactId>IJ-OpenCV</artifactId>
    <version>1.0</version>
  </dependency>

I will just not use
from ijopencv.opencv import MatImagePlusConverter

but instead something like:

from ijopencv import ImageConverter

converter = ImageConverter()
m = converter.convertFrom(Mat) # returning an Image Plus 

Thanks for the help, I think I am good with this openCV workaround now :crazy_face:


#17

That’s strange, because the following worked for me just fine, and the dependencies were copied:

  • From Command Prompt in Windows:

    mvn -Dimagej.app.directory=C:\Utilities\Fiji-test.app
    
  • From Git Bash in Windows:

    mvn -Dimagej.app.directory=C:\\Utilities\\Fiji-test.app
    

I didn’t test with a path that contains spaces though… would you be able to test if it works for you with a different Fiji path, to confirm that the issue is related to spaces in the path?


#18

Removing did not help but I finally try to run it from a different command line interface : the basic command prompt and not windows powershell and it worked ! :star_struck:
I have tried slash and back slashes, double slashes… no way with the powershell…
For some reason, my mouse shortcut to open a command prompt here opens the windows powershell by default.

And well, the IJ-open-CV that is actually shipped is the one from the master branch of the IJ-OpenCV repository and not the one from the updater >< (driving me crazy!!!)

I also see some downgrading liike :

[INFO] Copying ij-1.51s.jar to C:\FIJI_Blank\Fiji.app\jars
[INFO] Deleted overridden ij-1.52a.jar

Is it just about changing the pom-scijava ? (here it was 19.2.0)


#19

Oh, the PowerShell :smiley: I didn’t try that one…

Using -Ddelete.other.versions=older should help (although I’m not sure if it works with the versioning scheme of ij.jar).

Ideally (i.e. when hopefully everything is more automated in the near future, thanks to the huge efforts of @ctrueden and others) the pom-scijava version used in the fiji/fiji repository should define all the versions present on the update site as well.

Currently, there are quite a few artifacts that have been uploaded manually though, and are not in sync with the versions defined in that POM.

If you update to pom-scijava 21.0.0, you’ll see a lot of newer dependencies being copied, which is also not ideal. You can work around this by specifying <scope>provided</scope> for all the dependencies that you know are provided by Fiji.


#20

Did you try to run Fiji after that ? I tested on 2 different windows machines with fresh fiji installations.
Compiling with dependencies copied to the Fiji.app works, but then Fiji crashes shortly after opening.
Actually copying the IJ-OpenCV-1.0.jar to the jars folder had the same effect !

If you can reproduce the bug then it might be useful to raise an issue.

My workaround will be to declare no dependency and just to tell the user to enable the IJ-openCV update site first :stuck_out_tongue: