Skip to content

Latest commit

 

History

History
185 lines (155 loc) · 6.42 KB

README.md

File metadata and controls

185 lines (155 loc) · 6.42 KB

Join the chat at https://gitter.im/imglib2-imglyb

imglib2-imglyb

imglib2-imglyb aims at connecting two worlds that have been seperated for too long:

imglib2-imglyb uses PyJNIus to access numpy arrays and expose them to ImgLib2. This means shared memory between numpy and ImgLib2, i.e. any ImgLib2 algorithm can run on numpy arrays without creating copies of the data! For example, Python users can now make use of the BigDataViewer to visualize dense volumetric data. If you are interested in using imglib2-imglyb, have a look at the imglyb-examples repository and extend the examples as needed!

Installation

If you are running Linux or, with limitations, OSX, you can get imglib2-imlgyb from conda:

conda install -c hanslovsky imglib2-imglyb

Re-activate the environment after installation to correctly set the environment variables. If this does not work for you, please follow the build instructions below.

Requirements

  • Python 2 or 3
  • Java 8
  • Apache Maven
  • Apache Ant
  • imglib2-unsafe
  • Currently: imglib2-unsafe-0.0.1-SNAPSHOT.jar in local maven repository (see instructions below)
  • pyjnius.jar (see instructions below)
  • Cython

Build

Clone (or download) the PyJNIus repository:

# get PyJNIus
git clone https://github.com/kivy/pyjnius
cd pyjnius

In order to build pyjnius.jar and install the pyjnius python package, run on Linux or OSX:

make # creates build/pyjnius.jar
export JAVA_HOME=/path/to/jdk  # optional
make tests # optional
python setup.py install

On Windows:

ant all
python setup.py build_ext --inplace -f
python setup.py install

All other instructions should work independent of the operating system.

# get imglib2-unsafe-0.0.1-SNAPSHOT
git clone https://github.com/imglib/imglib2-unsafe
cd imglib2-unsafe
mvn clean install
cd /path/to/imglib2-imglyb
mvn clean package
python setup.py install

Run

Requirements

  • PyJNIus
  • Java 8
  • numpy

Run

If you do not use conda you need to set your environment before using imglib2-imglyb:

export JAVA_HOME=/path/to/JAVA_HOME # not necessary if using conda
export PYJNIUS_JAR=/path/to/pyjnius/build/pyjnius.jar # not necessary if using conda
export IMGLYB_JAR=/path/to/imglib2-imglyb/target/imglib2-imglyb-<VERSION>.jar # not necessary if using conda

Note that, in your python files, the line

import imglyb

needs to come before any of

from imglyb import util
import jnius
from jnius import *

It is best to follow and extend the imglyb-examples according to your needs.

Known Issues

AWT through PyJNIus on OSX

Currently, AWT, PyJNIus and cocoa do not get along very well In general, the cocoa event loop needs to be started before the jvm or awt is loaded (see example below). This requires PyObjC which is not available through conda currently. (Thanks to @tpietzsch for figuring out!) AWT frames (JFrame) are not visible or BigDataViewer crashes on user input. BigDataViewer functionality is thus not available or very limited on OSX. This is the working example for debugging and trying to figure out a way to fix the OSX issues:

from __future__ import print_function

def main():
    import imglyb
    from imglyb import util
    from jnius import autoclass, cast
    import multiprocessing
    import numpy as np
    from skimage import io
    import time
    import vigra
    import argparse
    default_url = 'https://github.com/hanslovsky/imglyb-examples/raw/master/resources/butterfly_small.jpg'

    parser = argparse.ArgumentParser()
    parser.add_argument( '--url', '-u', default=default_url )

    args = parser.parse_args()

    RealARGBConverter = autoclass( 'net.imglib2.converter.RealARGBConverter')
    Converters = autoclass( 'net.imglib2.converter.Converters' )
    ARGBType = autoclass ( 'net.imglib2.type.numeric.ARGBType' )
    RealType = autoclass ( 'net.imglib2.type.numeric.real.DoubleType' )
    DistanceTransform = autoclass( 'net.imglib2.algorithm.morphology.distance.DistanceTransform' )
    DISTANCE_TYPE = autoclass( 'net.imglib2.algorithm.morphology.distance.DistanceTransform$DISTANCE_TYPE' )
    Views = autoclass( 'net.imglib2.view.Views' )
    Executors = autoclass( 'java.util.concurrent.Executors' )
    t = ARGBType()

    img = io.imread( args.url )
    argb = (
        np.left_shift(img[...,0], np.zeros(img.shape[:-1],dtype=np.uint32) + 16) + \
        np.left_shift(img[...,1], np.zeros(img.shape[:-1],dtype=np.uint32) + 8)  + \
        np.left_shift(img[...,2], np.zeros(img.shape[:-1],dtype=np.uint32) + 0) ) \
        .astype( np.int32 )

    print( "Creating color class..." )
    Color = autoclass( 'java.awt.Color' )
    print( Color.BLACK.toString() )
    JFrame = autoclass( 'javax.swing.JFrame' )
    print( "Before constructor" )
    jFrame = JFrame( "Test frame" )
    print( "After constructor" )
    jFrame.setPreferredSize( autoclass( 'java.awt.Dimension' )( 400, 300 ) )
    jFrame.pack()
    jFrame.setVisible( True )
    jFrame.show()
    print( "JFrame should be showing now" )

    print( "Showing first bdv" )
    bdv = util.BdvFunctions.show( util.to_imglib_argb( argb ), "argb", util.options2D().frameTitle( "b-fly" ) )
    print( "Showing second bdv" )

if __name__ == "__main__":
    import objc
    from Foundation import *
    from AppKit import *
    from PyObjCTools import AppHelper
    import sys

    class AppDelegate( NSObject ):

        def init( self ):
            self = objc.super( AppDelegate, self ).init()
            if self is None:
                return None
            return self

        def runjava_( self, arg ):
                        main()

        def applicationDidFinishLaunching_( self, aNotification ):
            self.performSelectorInBackground_withObject_( "runjava:", 0 )

    app = NSApplication.sharedApplication()
    delegate = AppDelegate.alloc().init()
    app.setDelegate_( delegate )
    AppHelper.runEventLoop()
    ```