├── .gitignore ├── README.md ├── _config.yml ├── api_design_priciples.md ├── api_intro.md ├── clij_cheatsheet.pdf ├── clij_imagej_ops_java.md ├── clij_imagej_ops_scripteditor.md ├── dependingViaMaven.md ├── development.md ├── faq.md ├── images ├── autocompletion.png ├── clij_bridge.gif ├── clij_logo.png ├── clij_macro_recorder.mp4 ├── clij_macro_recorder2.gif ├── clijx_interactive_cbg_csbd_cut2.mp4 ├── device_dialog.png ├── dialogs.gif ├── example.png ├── image20.png ├── image21.png ├── macro_recorder.png ├── mean_filter_comparison_r1.png ├── mean_filter_comparison_r3.png ├── menu.gif ├── teaser.png ├── updatesite.png ├── visual_CPU_GPU_comparison.png └── workflow_intermediate_results.png ├── installationInFiji.md ├── installationInMicroManager.md ├── installation_linux.md ├── license.txt ├── macro_intro.md ├── pom.xml ├── quickTour.md ├── reference.md ├── referenceGroovy.md ├── referenceJava.md ├── referenceJython.md ├── release_cycle.md ├── src ├── main │ ├── beanshell │ │ ├── automaticThreshold.bsh │ │ ├── clij_micromanager.bsh │ │ └── maximumProjection.bsh │ ├── groovy │ │ ├── automaticThreshold.groovy │ │ └── maximumProjection.groovy │ ├── java │ │ └── net │ │ │ └── haesleinhuepf │ │ │ └── clij │ │ │ └── examples │ │ │ ├── AffineTransformDemo.java │ │ │ ├── ApplyVectorFieldDemo.java │ │ │ ├── AutoThresholdDemo.java │ │ │ ├── BackgroundSubtractionandThresholdingDemo.java │ │ │ ├── BenchmarkingWorkflowDemo.java │ │ │ ├── BinaryProcessingDemo.java │ │ │ ├── BlurDemo.java │ │ │ ├── CLIJImageJOpsCombinationDemo.java │ │ │ ├── ClinfoDemo.java │ │ │ ├── CreateObjectOutlinesDemo.java │ │ │ ├── LocalThresholdDemo.java │ │ │ ├── MaximumProjectionDemo.java │ │ │ ├── MotionCorrectionDemo.java │ │ │ ├── MultipleGPUDemo.java │ │ │ └── advanced │ │ │ ├── CLIJMacroPluginServiceDemo.java │ │ │ ├── CustomOpenCLDemo.java │ │ │ ├── DifferenceOfGaussianCLDemo.java │ │ │ ├── FlipCustomOpenCLDemo.java │ │ │ └── flip.cl │ ├── javascript │ │ ├── automaticThreshold.js │ │ └── maximumProjection.js │ ├── jython │ │ ├── addImages.py │ │ ├── affineTransform.py │ │ ├── applyVectorField.py │ │ ├── automaticThreshold.py │ │ ├── backgroundSubtraction.py │ │ ├── binaryProcessing.py │ │ ├── blur.py │ │ ├── blurg.py │ │ ├── clinfo.py │ │ ├── crop.py │ │ ├── differenceOfGaussian │ │ │ ├── differenceOfGaussian.cl │ │ │ └── differenceOfGaussian.py │ │ ├── interactiveSpotDetection.py │ │ ├── maximumProjection.py │ │ ├── multi_GPU_demo.py │ │ ├── reslicing.py │ │ ├── rgbReplaceBlackAndWhite.cl │ │ ├── rgbReplaceBlackAndWhite.py │ │ ├── rotateFree.py │ │ ├── rotateOverwriteOiginal.py │ │ ├── spotDetectionpy.py │ │ └── statistics.py │ ├── macro │ │ ├── addImages.ijm │ │ ├── affineTransform.ijm │ │ ├── allocateBigImages.ijm │ │ ├── applyVectorField.ijm │ │ ├── autoThreshold.ijm │ │ ├── backgroundSubtraction.ijm │ │ ├── benchmarking.ijm │ │ ├── bigImageTransfer.ijm │ │ ├── binaryProcessing.ijm │ │ ├── bitdepthConversion.ijm │ │ ├── blur.ijm │ │ ├── blur_batch.ijm │ │ ├── clInfo.ijm │ │ ├── convert.ijm │ │ ├── create_object_outlines.ijm │ │ ├── crop.ijm │ │ ├── flip.ijm │ │ ├── help.ijm │ │ ├── localMaximum.ijm │ │ ├── maximumProjection.ijm │ │ ├── mean.ijm │ │ ├── mean2d.ijm │ │ ├── mean_detailed_comparison_IJ_CLIJ.ijm │ │ ├── mean_detailed_comparison_IJ_CLIJ_radius.ijm │ │ ├── memory_reuse_versus_reallocation.ijm │ │ ├── minimum.ijm │ │ ├── motionCorrection.ijm │ │ ├── motionCorrection_compare_stackreg.ijm │ │ ├── orthogonalMaximumProjections.ijm │ │ ├── project3D.ijm │ │ ├── push.ijm │ │ ├── pushCurrentZStack.ijm │ │ ├── pushSlice.ijm │ │ ├── reslicing.ijm │ │ ├── rgb_invert_black_white.ijm │ │ ├── rotate.ijm │ │ ├── rotateFree.ijm │ │ ├── rotateOverwriteOriginal.ijm │ │ ├── rotate_comparison_IJ_CLIJ.ijm │ │ ├── scaleFree.ijm │ │ ├── statistics.ijm │ │ ├── thresholding.ijm │ │ ├── topHat.ijm │ │ ├── translate.ijm │ │ ├── turn_stack.ijm │ │ ├── warpCat.ijm │ │ └── warpCat_RGB.ijm │ └── resources │ │ ├── blobs.tif │ │ ├── droso_crop.tif │ │ ├── flybrain.tif │ │ ├── motion_correction_Drosophila_DSmanila1.tif │ │ ├── pixel_cat.tif │ │ └── pixel_cat_rgb.jpg └── test │ └── java │ └── net │ └── haesleinhuepf │ └── clij │ └── macro │ └── documentation │ ├── AbstractDocumentationGenerator.java │ ├── MarkdownGroovyOpDocumentationGenerator.java │ ├── MarkdownIJMacroDocumentationGenerator.java │ ├── MarkdownJavaOpDocumentationGenerator.java │ ├── MarkdownJythonOpDocumentationGenerator.java │ └── RunAll.java ├── testedsystems.md ├── testprotocols ├── 20190803_clij-core_ux38.txt ├── 20190803_clij_ux38.txt ├── 20190804_clij-core_einstein.txt ├── 20190804_clij-core_einstein2.txt ├── 20190804_clij-core_ulice.txt ├── 20190804_clij_einstein.txt ├── 20190804_clij_einstein2.txt ├── 20190804_clij_ulice.txt ├── 20191101_clij-core_finley.txt └── 20191101_clij_finley.txt └── troubleshooting.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /target/ 3 | *.iml 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CLIJ: GPU-accelerated image processing for everyone 2 | ## Introduction 3 | CLIJ is an OpenCL - ImageJ bridge and a [Fiji](https://fiji.sc/) plugin allowing users with entry-level skills in programming 4 | to build GPU-accelerated workflows to speed up their image processing. Increased efforts were put on documentation, code examples, interoperability, and extensibility. 5 | CLIJ is based on 6 | [ClearCL](http://github.com/ClearControl/ClearCL), 7 | [JOCL](http://github.com/gpu/JOCL), 8 | [Imglib2](https://github.com/imglib), 9 | [ImageJ](http://imagej.net) and 10 | [SciJava](https://github.com/SciJava). 11 | 12 | **If you use CLIJ, please cite it:** 13 | 14 | Robert Haase, Loic Alain Royer, Peter Steinbach, Deborah Schmidt, 15 | Alexandr Dibrov, Uwe Schmidt, Martin Weigert, Nicola Maghelli, Pavel Tomancak, 16 | Florian Jug, Eugene W Myers. 17 | *CLIJ: GPU-accelerated image processing for everyone*. [Nat Methods 17, 5–6 (2020) doi:10.1038/s41592-019-0650-1](https://doi.org/10.1038/s41592-019-0650-1) 18 | 19 | [Older version in BioRxiv](https://doi.org/10.1101/660704) 20 | 21 | If you search for support, please open a thread on the [image.sc](https://image.sc) forum. 22 | 23 | [![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fclij.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tags/clij) 24 | 25 | 26 | 27 | ## Overview 28 | 29 | * [CLIJ - a quick tour](https://clij.github.io/clij-docs/quickTour) 30 | * Installation 31 | * [Fiji update site](https://clij.github.io/clij-docs/installationInFiji) 32 | * [Depending on CLIJ via maven](https://clij.github.io/clij-docs/dependingViaMaven) 33 | * Introduction to CLIJ programming 34 | * [CLIJ for ImageJ Macro programmers](https://clij.github.io/clij-docs/macro_intro) 35 | * [CLIJ for Java programmers](https://clij.github.io/clij-docs/api_intro) 36 | * [ImageJ Jupyter notebooks in Groovy](https://github.com/clij/clij-notebooks/blob/master/clij-intro.ipynb) 37 | * [Execution from the command line](https://github.com/clij/clij-executable-example) 38 | * [CLIJ ImageJ Ops in Java](https://clij.github.io/clij-docs/clij_imagej_ops_java) 39 | * [CLIJ ImageJ Ops in the Script Editor](https://clij.github.io/clij-docs/clij_imagej_ops_scripteditor) 40 | * [Release notes](https://github.com/clij/clij/releases) 41 | * [Release cycle](https://clij.github.io/clij-docs/release_cycle) 42 | * Application programming interface (API) 43 | * [ImageJ Macro](https://clij.github.io/clij-docs/reference) 44 | * [ImageJ Macro cheat sheet](https://github.com/clij/clij-docs/blob/master/clij_cheatsheet.pdf) 45 | * [Jython](https://clij.github.io/clij-docs/referenceJython) 46 | * [Java](https://clij.github.io/clij-docs/referenceJava) 47 | * [Groovy](https://clij.github.io/clij-docs/referenceGroovy) 48 | * Code examples 49 | * [ImageJ Macro](https://github.com/clij/clij-docs/tree/master/src/main/macro) 50 | * [BeanShell](https://github.com/clij/clij-docs/tree/master/src/main/beanshell) 51 | * [Jython](https://github.com/clij/clij-docs/tree/master/src/main/jython) 52 | * [JavaScript](https://github.com/clij/clij-docs/tree/master/src/main/javascript) 53 | * [Groovy](https://github.com/clij/clij-docs/tree/master/src/main/groovy) 54 | * [Java](https://github.com/clij/clij-docs/tree/master/src/main/java/net/haesleinhuepf/clij/examples) 55 | * [ImageJ Ops in Java](https://github.com/clij/clij-ops/tree/master/src/test/java/net/haesleinhuepf/clij/ops/examples) 56 | * [ImageJ Ops in Jython](https://github.com/clij/clij-ops/tree/master/src/test/resources/jython) 57 | * Slides 58 | * [NEUBIAS Symposium 2020, Bordeaux](https://git.mpi-cbg.de/rhaase/clij_neubias_2020) 59 | * [NEUBIAS Training School TS14, Bordeaux](https://git.mpi-cbg.de/rhaase/neubias_ts14) 60 | * [MTZ Image Processing Seminar, TU Dresden](https://git.mpi-cbg.de/rhaase/clij_mtz_2020) 61 | * [Quantitative BioImaging Conference 2020, Oxford](slides/2020-01-QBI_SmartMicroscopy_Haase_V2.pdf) 62 | * [NEUBIAS Training School TS13, Porto](https://git.mpi-cbg.de/rhaase/neubias_ts14) 63 | * Benchmarking 64 | * [Benchmarking CLIJ operations versus ImageJ/Fiji operations using JMH](https://clij.github.io/clij-benchmarking/benchmarking_operations_jmh) 65 | * [Benchmarking CLIJ operations versus ImageJ/Fiji operations (archived)](https://clij.github.io/clij-benchmarking/benchmarking_operations) 66 | * [Benchmarking a CLIJ workflow versus ImageJ/Fiji](https://clij.github.io/clij-benchmarking/benchmarking_workflow_spot_count) 67 | * Extending CLIJ functionality 68 | * [Plugin template](https://github.com/clij/clij-plugin-template/) 69 | * [Example plugin for convolution/deconvolution](https://github.com/clij/clij-custom-convolution-plugin/) 70 | * CLIJ2 - the upcoming successor of CLIJ 71 | * [CLIJ2](https://clij.github.io/clij2/) 72 | * [CLIJ2 Reference](https://clij.github.io/clij2-docs/reference) 73 | * [CLIJ2 development repository](https://github.com/clij/clij2) 74 | * [CLIJx experimental repository](https://github.com/clij/clijx) 75 | * [Icy](https://clij.github.io/clicy/) (experimental) 76 | * [ImageJ1](https://github.com/clij/clij-legacy/) (experimental) 77 | * [Matlab](https://clij.github.io/clatlab/) (experimental) 78 | * [MicroManager 2.0](https://clij.github.io/clij-docs/installationInMicroManager) (experimental) 79 | * [Python](https://clij.github.io/clijpy/) (experimental) 80 | * FAQ / support 81 | * [Frequently asked questions](https://clij.github.io/clij-docs/faq) 82 | * [List of tested systems](https://clij.github.io/clij-docs/testedsystems) 83 | * [Troubleshooting](https://clij.github.io/clij-docs/troubleshooting) 84 | * [Support](https://image.sc) 85 | * [Imprint](https://clij.github.io/imprint) 86 | 87 | ## Acknowledgements 88 | Development of CLIJ is a community effort. We would like to thank everybody who helped developing and testing. In particular thanks goes to 89 | Alex Herbert (University of Sussex), 90 | Bram van den Broek (Netherlands Cancer Institute), 91 | Brenton Cavanagh (RCSI), 92 | Brian Northan (True North Intelligent Algorithms), 93 | Bruno C. Vellutini (MPI CBG), 94 | Curtis Rueden (UW-Madison LOCI), 95 | Damir Krunic (DKFZ), 96 | Daniel J. White (GE), 97 | Gaby G. Martins (IGC), 98 | Guillaume Witz (Bern University), 99 | Siân Culley (LMCB MRC), 100 | Giovanni Cardone (MPI Biochem), 101 | Jan Brocher (Biovoxxel), 102 | Jean-Yves Tinevez (Institute Pasteur), 103 | Johannes Girstmair (MPI CBG), 104 | Juergen Gluch (Fraunhofer IKTS), 105 | Kota Miura, 106 | Laurent Thomas (Acquifer), 107 | Matthew Foley (University of Sydney), 108 | Matthias Arzt (MPI-CBG), 109 | Nico Stuurman (UCSF), 110 | Peter Haub, 111 | Pete Bankhead (University of Edinburgh), 112 | Pit Kludig, 113 | Pradeep Rajasekhar (Monash University), 114 | Ruth Whelan-Jeans, 115 | Tanner Fadero (UNC-Chapel Hill), 116 | Thomas Irmer (Zeiss), 117 | Tobias Pietzsch (MPI-CBG), 118 | Wilson Adams (VU Biophotonics) 119 | 120 | R.H. was supported by the German Federal Ministry of 121 | Research and Education (BMBF) under the code 031L0044 122 | (Sysbio II) and D.S. received support from the German 123 | Research Foundation (DFG) under the code JU3110/1-1. 124 | P.T. was supported by the European Regional 125 | Development Fund in the IT4Innovations national 126 | supercomputing center-path to exascale project, 127 | project number CZ.02.1.01/0.0/0.0/16_013/0001791 128 | within the Operational Programme Research, Development 129 | and Education. 130 | 131 | [Imprint](https://clij.github.io/imprint) 132 | 133 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | title: CLIJ 2 | logo: /images/clij_logo.png 3 | description: GPU-accelerated image processing in ImageJ using CLIJ 4 | show_downloads: false 5 | google_analytics: 6 | theme: jekyll-theme-minimal 7 | plugins: 8 | - jekyll-redirect-from 9 | -------------------------------------------------------------------------------- /api_design_priciples.md: -------------------------------------------------------------------------------- 1 | # API design principles 2 | 3 | In order to simplify image processing using CLIJ from an application programming interface (API) as well as usability point of view, some general rules have been established: 4 | 5 | * All numeric spatial parameters in CLIJ such as radius and sigma are always entered in pixels. There is no operation in CLIJ which makes use of any physical units. 6 | * Pixel coordinates in X, Y and Z are zero-based indiced. 7 | * Only two- and three-dimensional images are supported. 8 | * There are no in-place operations supported in CLIJ. No operation overwrites its input images. 9 | * The currently active image window in ImageJ plays no role in CLIJ. Input and output images must be specified in macros by name explicitly. 10 | * If a specified output image does not exist in GPU memory, it will be generated automatically with a size defined by the executed operation with respect to input image and given parameters. 11 | * If a specified output image exists already in GPU memory, it will be overwritten. 12 | * CLIJ operations called from ImageJ macro have no return values. They either process pixels and save results to images or they save their results to ImageJs results table. 13 | * Binary output images are filled with pixel values 0 and 1. Any input image can serve as binary image and will be interpreted by differentiating 0 and non-zero values. 14 | 15 | [Back to CLIJ documentation](https://clij.github.io/) 16 | 17 | [Imprint](https://clij.github.io/imprint) 18 | 19 | 20 | -------------------------------------------------------------------------------- /api_intro.md: -------------------------------------------------------------------------------- 1 | 2 | # CLIJ - GPU-accelerated image processing with ImageJ and Java 3 | 4 | CLIJ is a Java library and a ImageJ/Fiji plugin allowing you to run OpenCL GPU accelerated code from Java. 5 | 6 | ## High level API 7 | The high level API of CLIJ becomes accessible from your Java project by [linking its maven dependency](dependingViaMaven). Furthermore, it can be used from ImageJs scripting languages such as Groovy and Jython from Fijis script editor. Therefore, the [CLIJ update site needs to be activated](installationInFiji). 8 | 9 | To get started, you need a `clij` variable containing the CLIJ instance to access the GPU. The following example shows how to do this from ImageJ Jython: 10 | ```python 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | clij = CLIJ.getInstance(); 14 | ``` 15 | 16 | Afterwards, you can convert `ImagePlus` objects to ClearCL objects which makes them accessible on the OpenCL device: 17 | 18 | ```python 19 | imageInput = clij.push(imp); 20 | ``` 21 | 22 | Furthermore, you can create images, for example with the same size as a given one: 23 | ```python 24 | imageOutput = clij.create(imageOutput); 25 | ``` 26 | 27 | Alternatively, create an image with a given size and a given type: 28 | 29 | ```python 30 | imageOutput = clij.create([imageInput.getWidth(), imageInput.getHeight()], imageInput.getNativeType()); 31 | ``` 32 | 33 | Inplace operations are not well supported by OpenCL 1.2. Thus, after creating two images, you can call a kernel taking the first image and filling the pixels of second image with data: 34 | 35 | ```python 36 | 37 | clij.op().maximumZProjection(clij, imageInput, imageOutput); 38 | ``` 39 | 40 | Then, use the `show()` method of `CLIJ` to get the image out of the GPU back to view in ImageJ: 41 | 42 | ```python 43 | clij.show(imageOutput, "output"); 44 | ``` 45 | 46 | You can also get the result image as ImagePlus: 47 | 48 | ```python 49 | result = clij.pull(imageOutput); 50 | ``` 51 | 52 | A list of all `clij.op()....` methods with example code is available for [ImageJ Jython](https://clij.github.io/clij-docs/referenceJython), [ImageJ/Java](https://clij.github.io/clij-docs/referenceJava) and [ImageJ Groovy](https://clij.github.io/clij-docs/referenceGroovy). 53 | 54 | ## Low level API 55 | 56 | In order to call your own `kernel.cl` files, use the `clij.execute()` method. Example code (Jython): 57 | 58 | ```python 59 | # initialize the GPU 60 | clij = CLIJ.getInstance(); 61 | 62 | # convert ImageJ image to CL images (ready for the GPU) 63 | inputCLBuffer = clij.push(imp); 64 | outputCLBuffer = clij.create(inputCLBuffer); # allocate memory for result image 65 | 66 | # downsample the image stack using ClearCL / OpenCL 67 | clij.execute(DownsampleXYbyHalfTask, "kernels/downsampling.cl", "downsample_xy_by_half_nearest", {"src":inputCLBuffer, "dst":outputCLBuffer}); 68 | 69 | # convert the result back to imglib2 and show it 70 | result = clij.pull(outputCLBuffer); 71 | result.show(); 72 | 73 | # free memory on the GPU - needs to be done explicitly 74 | inputCLBuffer.close(); 75 | outputCLBuffer.close(); 76 | ``` 77 | More examples can be found in the [src/main/jython](https://github.com/clij/clij-docs/blob/master/src/main/jython/) and [src/main/java](https://github.com/clij/clij-docs/blob/master/src/main/java/) directories. 78 | 79 | ## OpenCL Kernel calls with CLIJ.execute() 80 | The execute function asks for three or four parameters 81 | ``` 82 | clij.execute(, "filename_open.cl", "kernelfunction", {"src":image, "dst":image, "more":5, "evenmore":image}) 83 | 84 | clij.execute("absolute/or/relative/path/filename_open.cl", "kernelfunction", {"src":image, "dst":image, "more":5, "evenmore":image}) 85 | ``` 86 | * An optional class file as an anchor to have a point for where to start 87 | searching for the program file (second parameter). 88 | * The open.cl program file will be searched for in the same folder where the 89 | class (first parameter) is defined. In the first example above, this class 90 | comes with the dependency FastFuse. Alternatively, an absolute path can be 91 | proveded if there is no class given as first parameter. In case a relative 92 | path is given, it must be relative from the current dir of Fiji. 93 | * The name of the kernel function defined in the program file 94 | * A dictionary with all the parameters of the kernel function, such as 95 | "src" and "dst". It is recommended to have at least a "src" and a "dst" 96 | parameter, because CLIJ derives image data types and global space from 97 | these parameters. 98 | 99 | ## Type agnostic OpenCL 100 | As jython is a type-agnostic programming language, CLIJ targets bringing the same convenience to OpenCL as well. However, in order to make the executed OpenCL programs image pixel type agnostic, some conventions must be introduced. The conventions are all optional. OpenCL programmers who know how to pass images of a defined type to OpenCL programs using the correct access functions can skip this section. 101 | 102 | * Instead of using functions like `read_imagef()`, `write_imagef()`, `write_imageui()` etc., 103 | it is recommended to use `WRITE_IMAGE_2D()`, `WRITE_IMAGE_3D()`, `READ_IMAGE_2D()` and `READ_IMAGE_3D()` function calls. These function 104 | calls will be replaced during runtime with the function accessing the correct image data 105 | type. However, in order to allow CLIJ to detect the right image data type, there must 106 | be at least two image type parameters containing "src", "dst", "input", or "output" in their 107 | parameter names. CLIJ will then for example detect the type of an image parameter called 108 | "src_image" and replace all calls to `READ_IMAGE_2D()` with the respective call to 109 | `image_readui()` or `image_readf()` calls. 110 | * Variables inside OpenCL programs can be typed with `DTYPE_IN` and `DTYPE_OUT` 111 | instead of `float` or `int4` in order to make the OpenCL code type agnostic. 112 | 113 | 114 | [Back to CLIJ documentation](https://clij.github.io/) 115 | 116 | [Imprint](https://clij.github.io/imprint) 117 | -------------------------------------------------------------------------------- /clij_cheatsheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/clij_cheatsheet.pdf -------------------------------------------------------------------------------- /clij_imagej_ops_java.md: -------------------------------------------------------------------------------- 1 | 2 | # CLIJ and Imagej Ops in Java 3 | 4 | Many of CLIJ's Kernels are also available as ImageJ Ops. There is also an extensive list of [examples](https://github.com/clij/clij-ops/tree/master/src/test/java/net/haesleinhuepf/clij/ops/examples). 5 | 6 | ## Installation 7 | 8 | To use the CLIJ ImageJ Ops in your own project, link it as a maven dependency: 9 | 10 | ```xml 11 | 12 | net.haesleinhuepf 13 | clij-ops 14 | 1.6.0 15 | 16 | ``` 17 | 18 | To allow maven finding this artifact, add a repository to your pom.xml file: 19 | 20 | ```xml 21 | 22 | clij 23 | http://dl.bintray.com/haesleinhuepf/clij 24 | 25 | ``` 26 | 27 | ## Initializing CLIJ 28 | 29 | When calling an Op, a `CLIJService` will automatically initialize CLIJ if this did not already happen. In case you want to initialize CLIJ with a custom GPU, this is the way to go: 30 | 31 | ```java 32 | import net.imagej.ImageJ; 33 | import net.haesleinhuepf.clij.CLIJService; 34 | 35 | ImageJ ij = new ImageJ(); 36 | ij.get(CLIJService.class).get("Intel(R) HD Graphics Kabylake Desktop GT1.5"); 37 | ``` 38 | 39 | ## Using Ops 40 | 41 | Afterwards, you can convert `RandomAccessibleInterval` or `Img` objects to `ClearCLBuffer` objects which makes them accessible on the OpenCL device: 42 | 43 | ```Java 44 | Object input = ij.io().open("PATH_TO_IMAGE"); 45 | Object inputGPU = ij.op().run(CLIJ_push.class, input); 46 | ``` 47 | 48 | In this example, `inputGPU` is of type `ClearCLBuffer`, but while staying in the Ops domain `Object` works fine and reduces casting. Which you can still do if you want to access it's methods. 49 | ```Java 50 | ClearCLBuffer buffer = (ClearCLBuffer) inputGPU; 51 | ``` 52 | 53 | Furthermore, you can create images, for example with the same size as a given one: 54 | ```Java 55 | Object targetGPU = ij.op().run(CLIJ_create.class, inputGPU); 56 | ``` 57 | 58 | Alternatively, create an image with a given size and a given type: 59 | 60 | ```Java 61 | Object targetGPU = ij.op().run(CLIJ_create.class, new long[] { buffer.getWidth(), buffer.getHeight() }, buffer.getNativeType()); 62 | ``` 63 | 64 | Most CLIJ Ops are hybrid, meaning they can act both as a computer and a function (see the [SpecialOps JavaDoc](https://javadoc.scijava.org/ImageJ/net/imagej/ops/special/SpecialOp.html) for further details). There are no inplace operations in CLIJ. 65 | 66 | In this example the output object will be automatically generated and returned by the Op (function): 67 | ```Java 68 | 69 | targetGPU = ij.op().run(CLIJ_maximumZProjection.class, inputGPU); 70 | ``` 71 | 72 | In the next example both the input and the output are created beforehand and handed to the Op (computer): 73 | ```Java 74 | 75 | ij.op().run(CLIJ_maximumZProjection.class, targetGPU, inputGPU); 76 | ``` 77 | **CAUTION** 78 | Be aware that in this case the output is the first and the input is the second parameter, in contrast to other CLIJ APIs where the order is the other way around. 79 | The next ImageJ Op generation will revert this order, meaning that the order might change in a future version of CLIJ as well. 80 | 81 | 82 | To get the image back into `imglib2` format, call the `CLIJ_pull` op: 83 | 84 | ```Java 85 | Object target = ij.op().run(CLIJ_pull.class, targetGPU); 86 | ij.ui().show(target); 87 | ``` 88 | More examples can be found [here](https://github.com/clij/clij-ops/tree/master/src/test/java/net/haesleinhuepf/clij/ops/examples). 89 | 90 | [Back to CLIJ documentation](https://clij.github.io/) 91 | 92 | [Imprint](https://clij.github.io/imprint) 93 | 94 | -------------------------------------------------------------------------------- /clij_imagej_ops_scripteditor.md: -------------------------------------------------------------------------------- 1 | 2 | # CLIJ and Imagej Ops in the Script Editor 3 | 4 | Many of CLIJ's Kernels are integrated into ImageJ Ops. [Examples in Jython](https://github.com/clij/clij-ops/tree/master/src/test/resources/jython) are provided. 5 | 6 | ## Installation 7 | 8 | The Ops are available in ImageJ's script editor after installing the [CLIJ update site](installationInFiji.md). 9 | 10 | ## Initializing CLIJ 11 | 12 | When calling an Op, a `CLIJService` will automatically initialize CLIJ if this did not already happen. In case you want to initialize CLIJ with a custom GPU, this is the way to go: 13 | 14 | ```python 15 | #@CLIJService clijService 16 | 17 | clijService.get("Intel(R) HD Graphics Kabylake Desktop GT1.5"); 18 | ``` 19 | 20 | ## Using Ops 21 | 22 | Afterwards, you can convert images to `ClearCLBuffer` objects which makes them accessible on the OpenCL device: 23 | 24 | ```python 25 | #@IOService io 26 | #@OpService ops 27 | 28 | input = io.open("PATH_TO_IMAGE") 29 | inputGPU = ops.run("CLIJ_push", input) 30 | ``` 31 | 32 | Furthermore, you can create images, for example with the same size as a given one: 33 | ```python 34 | targetGPU = ops.run("CLIJ_create", inputGPU) 35 | ``` 36 | 37 | Alternatively, create an image with a given size and a given type: 38 | 39 | ```python 40 | targetGPU = ops.run("CLIJ_create", [input.dimension(0), input.dimension(1), 5], inputGPU.getNativeType()) 41 | ``` 42 | 43 | Most CLIJ Ops are hybrid, meaning they can act both as a computer and a function (see the [SpecialOps JavaDoc](https://javadoc.scijava.org/ImageJ/net/imagej/ops/special/SpecialOp.html) for further details). There are no inplace operations in CLIJ. 44 | 45 | In this example the output object will be automatically generated and returned by the Op (function): 46 | ```python 47 | imageOutput = ops.run("CLIJ_maximumZProjection", imageInput) 48 | ``` 49 | 50 | In the next example both the input and the output are created beforehand and handed to the Op (computer): 51 | ```python 52 | ops.run("CLIJ_maximumZProjection", imageOutput, imageInput) 53 | ``` 54 | **CAUTION** 55 | Be aware that in this case the output is the first and the input is the second parameter, in contrast to other CLIJ APIs where the order is the other way around. 56 | The next ImageJ Op generation will revert this order, meaning that the order might change in a future version of CLIJ as well. 57 | 58 | 59 | To get the image back into `imglib2` format, call the `CLIJ_pull` op: 60 | 61 | ```python 62 | #@UIService ui 63 | 64 | target = ops.run("CLIJ_pull", targetGPU) 65 | ui.show(target) 66 | 67 | ``` 68 | 69 | After finishing imag processing, memory on GPU needs to be released explicitly: 70 | ```python 71 | imageInput.close(); 72 | imageOutput.close(); 73 | targetGPU.close(); 74 | ``` 75 | 76 | 77 | More examples can be found [here](https://github.com/clij/clij-ops/tree/master/src/test/resources/jython). 78 | 79 | 80 | [Back to CLIJ documentation](https://clij.github.io/) 81 | 82 | [Imprint](https://clij.github.io/imprint) 83 | 84 | -------------------------------------------------------------------------------- /dependingViaMaven.md: -------------------------------------------------------------------------------- 1 | 2 | ### Depending on CLIJ 3 | 4 | If you want to access CLIJ from your Java code, it is recommended to depend on CLIJ via Maven dependencies. Add this dependency to the pom.xml file of your project: 5 | 6 | ```xml 7 | 8 | net.haesleinhuepf 9 | clij_ 10 | 1.6.0 11 | 12 | ``` 13 | 14 | To allow maven finding this artifact, add a repository to your pom.xml file: 15 | 16 | ```xml 17 | 18 | clij 19 | http://dl.bintray.com/haesleinhuepf/clij 20 | 21 | ``` 22 | 23 | [Back to CLIJ documentation](https://clij.github.io/) 24 | 25 | [Imprint](https://clij.github.io/imprint) 26 | 27 | -------------------------------------------------------------------------------- /development.md: -------------------------------------------------------------------------------- 1 | ## Developing using maven 2 | CLIJ uses the maven build system. In order to develop CLIJ, use git to get the recent version and maven to build it: 3 | 4 | Clone the clij repository 5 | ``` 6 | git clone https://github.com/clij/clij 7 | ``` 8 | 9 | Open pom.xml and enter the path of your Fiji installation in the line containing 10 | 11 | ``` 12 | C:/path/to/Fiji.app 13 | ``` 14 | 15 | Go to the source dir and install it to your Fiji.app 16 | 17 | ``` 18 | cd clij 19 | install.bat 20 | ``` 21 | 22 | For development it is recommended to use an integrated development environment such as IntelliJ or Eclipse. 23 | 24 | [Back to CLIJ documentation](https://clij.github.io/) 25 | 26 | [Imprint](https://clij.github.io/imprint) 27 | 28 | -------------------------------------------------------------------------------- /images/autocompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/autocompletion.png -------------------------------------------------------------------------------- /images/clij_bridge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/clij_bridge.gif -------------------------------------------------------------------------------- /images/clij_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/clij_logo.png -------------------------------------------------------------------------------- /images/clij_macro_recorder.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/clij_macro_recorder.mp4 -------------------------------------------------------------------------------- /images/clij_macro_recorder2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/clij_macro_recorder2.gif -------------------------------------------------------------------------------- /images/clijx_interactive_cbg_csbd_cut2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/clijx_interactive_cbg_csbd_cut2.mp4 -------------------------------------------------------------------------------- /images/device_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/device_dialog.png -------------------------------------------------------------------------------- /images/dialogs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/dialogs.gif -------------------------------------------------------------------------------- /images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/example.png -------------------------------------------------------------------------------- /images/image20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/image20.png -------------------------------------------------------------------------------- /images/image21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/image21.png -------------------------------------------------------------------------------- /images/macro_recorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/macro_recorder.png -------------------------------------------------------------------------------- /images/mean_filter_comparison_r1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/mean_filter_comparison_r1.png -------------------------------------------------------------------------------- /images/mean_filter_comparison_r3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/mean_filter_comparison_r3.png -------------------------------------------------------------------------------- /images/menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/menu.gif -------------------------------------------------------------------------------- /images/teaser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/teaser.png -------------------------------------------------------------------------------- /images/updatesite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/updatesite.png -------------------------------------------------------------------------------- /images/visual_CPU_GPU_comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/visual_CPU_GPU_comparison.png -------------------------------------------------------------------------------- /images/workflow_intermediate_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/images/workflow_intermediate_results.png -------------------------------------------------------------------------------- /installationInFiji.md: -------------------------------------------------------------------------------- 1 | 2 | ## Installation 3 | [Download and install Fiji](https://fiji.sc/Downloads). Afterwards, click the menu `Help > Update...` and activate the [CLIJ update site](installationInFiji. 4 | 5 | ![Image](images/updatesite.png) 6 | 7 | After restarting Fiji, CLIJ is successfully installed, if you find a menu entry _Plugins > ImageJ on GPU (CLIJ)_. 8 | 9 | ## Testing the installation 10 | You can execute [this macro](https://github.com/clij/clij-docs/blob/master/src/main/macro/benchmarking.ijm) to see if CLIJ and graphics card drivers are installed correctly. In case of issues, consult the [troubleshooting section](https://clij.github.io/clij-docs/troubleshooting) or contact us via [image.sc](https://image.sc). 11 | 12 | ## Windows and MacOS 13 | On Windows and MacOS the installation should work right away in case the computer has a built-in Intel HD or AMD Ryzen GPU. In case dedicated AMD or NVidia GPUs are used, special drivers might have to be installed. Search for more information about drivers on the websites of the GPU vendors. 14 | 15 | ## Windows: AMD and NVidia graphics cards 16 | In case of processing large images and/or working with large kernels, errors may pop up when using NVidia or AMD graphics cards on Windows. The issue is related to a timeout of the operating system interrupting processing on the GPU. Add the following entries keys to the windows registry and restart the computer: 17 | ``` 18 | [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers] 19 | "TdrDelay"=dword:0000003c 20 | "TdrDdiDelay"=dword:0000003c 21 | ``` 22 | Be really careful when doing this. Don't do it, if you're not aware what that means. Ask you IT department for support. [Read the BSD3 license file](license.txt) for details on why we're not responsible for your actions on your computer. More technical background information: 23 | 24 | [https://docs.microsoft.com/en-us/windows-hardware/drivers/display/tdr-registry-keys](https://docs.microsoft.com/en-us/windows-hardware/drivers/display/tdr-registry-keys) 25 | 26 | [https://community.amd.com/thread/180166](https://community.amd.com/thread/180166) 27 | 28 | [https://support.microsoft.com/en-us/help/2665946/display-driver-stopped-responding-and-has-recovered-error-in-windows-7](https://support.microsoft.com/en-us/help/2665946/display-driver-stopped-responding-and-has-recovered-error-in-windows-7) 29 | 30 | ## Linux 31 | Linux users need to install drivers for OpenCL, even on Intel HD GPUs. It is recommended to install the packages [beignet](https://github.com/intel/beignet) and [ocl-icd-devel](https://github.com/OCL-dev/ocl-icd). 32 | 33 | [Back to CLIJ documentation](https://clij.github.io/) 34 | 35 | [Imprint](https://clij.github.io/imprint) 36 | 37 | -------------------------------------------------------------------------------- /installationInMicroManager.md: -------------------------------------------------------------------------------- 1 | ## Installation in MicroManger 2 | 3 | In order to get CLIJ accessible from [MicroManager 2.0 gamma](https://valelab4.ucsf.edu/~MM/nightlyBuilds/2.0.0-gamma/Windows/) scripting interface, please copy these files from the recent [CLIJ release](https://github.com/clij/clij/releases) into the `/plugins/` directory of MicroManager: 4 | * [clij_1.4.5.jar](https://github.com/clij/clij/releases/download/1.4.5/clij_-1.4.5.jar) 5 | * [clij-clearcl-0.10.4.jar](https://github.com/clij/clij/releases/download/1.4.5/clij-clearcl-0.10.4.jar) 6 | * [clij-core-1.4.5.jar](https://github.com/clij/clij/releases/download/1.4.5/clij-core-1.4.5.jar) 7 | * [clij-coremem-0.6.0.jar](https://github.com/clij/clij/releases/download/1.4.5/clij-coremem-0.6.0.jar) 8 | * [imagej-common-0.28.2.jar](https://sites.imagej.net/Java-8/jars/imagej-common-0.28.2.jar-20190516211613) 9 | * [imglib2-realtransform-2.1.0.jar](https://sites.imagej.net/Java-8/jars/imglib2-realtransform-2.1.0.jar-20181204141527) 10 | * [imglib2-ij-2.0.0-beta-44.jar](https://sites.imagej.net/Java-8/jars/imglib2-ij-2.0.0-beta-44.jar-20181204141527) 11 | * [clij-advanced-filters_-0.21.3.jar](https://github.com/clij/clij-advanced-filters/releases/download/0.21.3/clij-advanced-filters_-0.21.3.jar) 12 | * [fiji-lib-2.1.2.jar](https://sites.imagej.net/Java-8/jars/fiji-lib-2.1.2.jar-20170530201750) 13 | 14 | While copying these files, please make sure to remove older verrsions of the same dependencies, such as clij-clearcl-0.10.1.jar, imagej-common-0.26.1.jar and imglib2-realtransform-2.0.0.jar. 15 | 16 | Afterwards, restart MicroManager. You can try if it works by running [this beanshell script](https://github.com/clij/clij-docs/blob/master/src/main/beanshell/clij_micromanager.bsh) to see if it works. 17 | 18 | [Back to CLIJ documentation](https://clij.github.io/) 19 | 20 | [Imprint](https://clij.github.io/imprint) 21 | -------------------------------------------------------------------------------- /installation_linux.md: -------------------------------------------------------------------------------- 1 | # Installation on linux 2 | 3 | * Ubuntu 4 | * Fedora 5 | 6 | ## Installation Ubuntu 18.04 LTS 7 | 8 | Fresh OS: 9 | 10 | ``` 11 | (Fiji Is Just) ImageJ 2.0.0-rc-69/1.52p; Java 1.8.0_172 [64-bit]; Linux 5.0.0-23-generic; 93MB of 10833MB (<1%) 12 | java.lang.NoClassDefFoundError: Could not initialize class net.haesleinhuepf.clij.clearcl.backend.jocl.ClearCLBackendJOCL 13 | at net.haesleinhuepf.clij.clearcl.backend.ClearCLBackends.getBestBackend(ClearCLBackends.java:126) 14 | at net.haesleinhuepf.clij.CLIJ.getAvailableDeviceNames(CLIJ.java:199) 15 | at net.haesleinhuepf.clij.macro.AbstractCLIJPlugin.run(AbstractCLIJPlugin.java:218) 16 | at ij.plugin.filter.PlugInFilterRunner.processOneImage(PlugInFilterRunner.java:266) 17 | at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:114) 18 | at ij.IJ.runUserPlugIn(IJ.java:232) 19 | at ij.IJ.runPlugIn(IJ.java:193) 20 | at ij.Executer.runCommand(Executer.java:137) 21 | at ij.Executer.run(Executer.java:66) 22 | at java.lang.Thread.run(Thread.java:748 23 | ``` 24 | 25 | ``` 26 | sudo apt-get update 27 | sudo apt-get install ocl-icd-opencl-dev 28 | ``` 29 | 30 | Restart Fiji 31 | 32 | ``` 33 | (Fiji Is Just) ImageJ 2.0.0-rc-69/1.52p; Java 1.8.0_172 [64-bit]; Linux 5.0.0-23-generic; 63MB of 10763MB (<1%) 34 | 35 | net.haesleinhuepf.clij.clearcl.exceptions.OpenCLException: OpenCL error: -1001 -> Unknown OpenCL error:-1001 36 | at net.haesleinhuepf.clij.clearcl.backend.BackendUtils.checkOpenCLError(BackendUtils.java:346) 37 | at net.haesleinhuepf.clij.clearcl.backend.jocl.ClearCLBackendJOCL.lambda$getNumberOfPlatforms$0(ClearCLBackendJOCL.java:83) 38 | at net.haesleinhuepf.clij.clearcl.backend.BackendUtils.checkExceptions(BackendUtils.java:156) 39 | at net.haesleinhuepf.clij.clearcl.backend.jocl.ClearCLBackendJOCL.getNumberOfPlatforms(ClearCLBackendJOCL.java:81) 40 | at net.haesleinhuepf.clij.clearcl.ClearCL.getNumberOfPlatforms(ClearCL.java:44) 41 | at net.haesleinhuepf.clij.clearcl.ClearCL.getAllDevices(ClearCL.java:232) 42 | at net.haesleinhuepf.clij.CLIJ.getAvailableDeviceNames(CLIJ.java:201) 43 | at net.haesleinhuepf.clij.macro.AbstractCLIJPlugin.run(AbstractCLIJPlugin.java:218) 44 | at ij.plugin.filter.PlugInFilterRunner.processOneImage(PlugInFilterRunner.java:266) 45 | at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:114) 46 | at ij.IJ.runUserPlugIn(IJ.java:232) 47 | at ij.IJ.runPlugIn(IJ.java:193) 48 | at ij.Executer.runCommand(Executer.java:137) 49 | at ij.Executer.run(Executer.java:66) 50 | at java.lang.Thread.run(Thread.java:748) 51 | ``` 52 | 53 | ``` 54 | sudo apt-get install beignet clinfo 55 | ``` 56 | 57 | Error on command line output: 58 | ``` 59 | ASSERTION FAILED: Not implemented 60 | at file /build/beignet-Bevceu/beignet-1.3.2/backend/src/llvm/llvm_scalarize.cpp, function bool gbe::Scalarize::scalarizeInsert(llvm::InsertElementInst*), line 838 61 | ``` 62 | 63 | ``` 64 | sudo apt-get install build-essential 65 | sudo apt-get install cmake 66 | sudo apt-get install llvm 67 | sudo apt-get install llvm-dev 68 | sudo apt-get install pkg-config 69 | sudo apt-get install libclang-dev 70 | sudo apt-get install lib32z1-dev 71 | 72 | git clone https://github.com/intel/beignet.git 73 | cd beignet/ 74 | mkdir build 75 | cd build 76 | 77 | cmake ../ 78 | sudo make install 79 | 80 | 81 | ``` 82 | 83 | [Back to CLIJ documentation](https://clij.github.io/) 84 | 85 | [Imprint](https://clij.github.io/imprint) 86 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 Robert Haase, Deborah Schmidt, 2 | Max Planck Institute for Molecular Cell Biology 3 | and Genetics, Dresden 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /macro_intro.md: -------------------------------------------------------------------------------- 1 | # CLIJ - GPU-accelerated image processing in ImageJ macro 2 | Image processing in modern GPUs allows for accelerating processing speeds massively. 3 | This page introduces how to do image processing in the graphics processing unit (GPU) using [OpenCL](https://www.khronos.org/opencl/) from ImageJ macro inside [Fiji](http://fiji.sc) using the [CLIJ](https://clij.github.io/) library. 4 | It is not necessary to learn OpenCL itself. 5 | Preprogrammed routines are supposed to do GPU image processing for you with given ImageJ macro programming experience. 6 | The list of preprogrammed routines might be extended depending on the communities needs. 7 | 8 | This is how your code might look like if you do GPU based image processing in ImageJ macro: 9 | 10 | ![Image](images/example.png) 11 | 12 | ## Installation 13 | Follow the [installation instructions](installationInFiji); 14 | 15 | ## Activating CLIJs macro extensions 16 | 17 | To get started, all ImageJ macros using CLIJ have a line like this at the beginning: 18 | 19 | ```java 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | ``` 22 | 23 | Note: This line may contain the specific name for a GPU. 24 | You can - but you don't have to - specify one. 25 | If none is specified, the system will take the first one found. 26 | If you don't have the named GPU in your computer, another one will be chosen. 27 | You don't have to enter the full name, you can also just specify a part of the name. 28 | In order to run on any `HD` named GPU, change the macro like this: 29 | 30 | ```java 31 | run("CLIJ Macro Extensions", "cl_device=HD"); 32 | ``` 33 | 34 | ## Transferring images between ImageJ and the GPU 35 | In order to allow images to be processed by the GPU, you need to transfer them into the memory of the GPU. 36 | In order to view images which were processed by the GPU, you need to transfer them back to ImageJ. 37 | The two methods for doing this are called `push(image)` and `pull(image)`. 38 | You can remove a single image from the GPUs memory by using the `release(image)` method. 39 | Finally, you can remove all images from the GPU with the `clear()` method. 40 | In case the destination image doesn't exist, it will be created automatically in the GPU. 41 | Just push an image _A_ to the GPU, process it with destination _B_ and afterwards, you can pull _B_ back from the GPU to ImageJ in order to show it. 42 | 43 | Let's have a look at an example which loads an image and blurs it using the push-pull mechanism. 44 | 45 | ```java 46 | // Get test data 47 | run("T1 Head (2.4M, 16-bits)"); 48 | input = getTitle(); 49 | getDimensions(width, height, channels, slices, frames); 50 | 51 | // define under which name the result should be saved 52 | blurred = "Blurred"; 53 | 54 | // Init GPU 55 | run("CLIJ Macro Extensions", "cl_device="); 56 | Ext.CLIJ_clear(); 57 | 58 | // push images to GPU 59 | Ext.CLIJ_push(input); 60 | 61 | // cleanup ImageJ 62 | run("Close All"); 63 | 64 | // Blur in GPU 65 | Ext.CLIJ_blur3D(input, blurred, 10, 10, 1); 66 | 67 | // Get results back from GPU 68 | Ext.CLIJ_pull(blurred); 69 | 70 | // Cleanup by the end 71 | Ext.CLIJ_clear(); 72 | ``` 73 | 74 | To find out, which images are currently stored in the GPU, run the `Ext.CLIJ_reportMemory();` method. 75 | 76 | ## Sparing time with GPU based image processing 77 | The overall goal for processing images in the GPU is sparing time. 78 | GPUs can process images faster because they can calculate pixel values of many pixels in parallel. 79 | Furthermore, images in memory of modern GPUs can be accessed faster than in ImageJ. 80 | However, there is a drawback: pushing/pulling the images to/from the GPU takes time. 81 | Thus, overall efficiency can only be achieved if whole pipelines are processed in the GPU. 82 | Furthermore, repeatedly using the same operations on a GPU pays off because operations are cached. Reusing them is faster than using other methods. 83 | 84 | Let's compare the `Mean 3D` filter of ImageJ with it's counterpart in CLIJ. 85 | The example macro is [benchmarking.ijm](https://github.com/clij/clij-docs/tree/master/src/main/macro/benchmarking.ijm). 86 | It executes both operations ten times and measures the time each operation takes. 87 | This is just an excerpt of the macro: 88 | 89 | ```java 90 | // Local mean filter in CPU 91 | for (i = 1; i <= 10; i++) { 92 | time = getTime(); 93 | run("Mean 3D...", "x=3 y=3 z=3"); 94 | print("CPU mean filter no " + i + " took " + (getTime() - time)); 95 | } 96 | ``` 97 | 98 | ```java 99 | // push images to GPU 100 | time = getTime(); 101 | Ext.CLIJ_push(input); 102 | Ext.CLIJ_push(blurred); 103 | print("Pushing two images to the GPU took " + (getTime() - time) + " msec"); 104 | 105 | // Local mean filter in GPU 106 | for (i = 1; i <= 10; i++) { 107 | time = getTime(); 108 | Ext.CLIJ_mean3DBox(input, blurred, 3, 3, 3); 109 | print("GPU mean filter no " + i + " took " + (getTime() - time)); 110 | } 111 | 112 | // Get results back from GPU 113 | time = getTime(); 114 | Ext.CLIJ_pull(blurred); 115 | print("Pullning one image from the GPU took " + (getTime() - time) + " msec"); 116 | ``` 117 | 118 | When executing the macro on an Intel Core i7-8565U CPU with a built-in Intel UHD Graphics 620 GPU (Windows 10, 64 bit), the output is: 119 | 120 | ```java 121 | CPU mean filter no 1 took 3907 msec 122 | CPU mean filter no 2 took 3664 msec 123 | CPU mean filter no 3 took 3569 msec 124 | CPU mean filter no 4 took 3414 msec 125 | CPU mean filter no 5 took 2325 msec 126 | CPU mean filter no 6 took 2752 msec 127 | CPU mean filter no 7 took 2395 msec 128 | CPU mean filter no 8 took 2633 msec 129 | CPU mean filter no 9 took 2543 msec 130 | CPU mean filter no 10 took 2610 msec 131 | Pushing one image to the GPU took 11 msec 132 | GPU mean filter no 1 took 489 msec 133 | GPU mean filter no 2 took 27 msec 134 | GPU mean filter no 3 took 27 msec 135 | GPU mean filter no 4 took 28 msec 136 | GPU mean filter no 5 took 29 msec 137 | GPU mean filter no 6 took 39 msec 138 | GPU mean filter no 7 took 34 msec 139 | GPU mean filter no 8 took 29 msec 140 | GPU mean filter no 9 took 30 msec 141 | GPU mean filter no 10 took 31 msec 142 | Pulling one image from the GPU took 47 msec 143 | ``` 144 | 145 | Thus, on the **CPU it takes 30 seconds**, while using the **GPU it just takes 0.8 seconds**. Let's execute it again. 146 | 147 | ```java 148 | CPU mean filter no 1 took 2254 msec 149 | CPU mean filter no 2 took 2187 msec 150 | CPU mean filter no 3 took 2264 msec 151 | CPU mean filter no 4 took 2491 msec 152 | CPU mean filter no 5 took 2915 msec 153 | CPU mean filter no 6 took 2299 msec 154 | CPU mean filter no 7 took 2401 msec 155 | CPU mean filter no 8 took 2441 msec 156 | CPU mean filter no 9 took 2493 msec 157 | CPU mean filter no 10 took 2588 msec 158 | Pushing one image to the GPU took 9 msec 159 | GPU mean filter no 1 took 30 msec 160 | GPU mean filter no 2 took 28 msec 161 | GPU mean filter no 3 took 30 msec 162 | GPU mean filter no 4 took 39 msec 163 | GPU mean filter no 5 took 34 msec 164 | GPU mean filter no 6 took 34 msec 165 | GPU mean filter no 7 took 34 msec 166 | GPU mean filter no 8 took 32 msec 167 | GPU mean filter no 9 took 40 msec 168 | GPU mean filter no 10 took 32 msec 169 | Pulling one image from the GPU took 43 msec 170 | ``` 171 | 172 | On the **CPU it still takes 24 seconds**, while using the **GPU it goes down to 0.4 seconds**. 173 | The additional speedup comes from the caching mechanism mentioned above. 174 | 175 | **Heureka, we can spare 90% of the time by executing the operation on the GPU!** 176 | And this works on a small laptop without dedicated GPU. This example should just motivate you to test your workflow on a GPU and guide you how to evaluate its performance. 177 | 178 | Side note: ImageJs mean filter runs _inplace_. That means the result is stored in the same memory as the input image. 179 | With every iteration in the for loop, the image becomes more and more blurry. 180 | The OpenCL operation in the GPU always starts from the _input_ image and puts its result in the _blurred_ image. 181 | Thus, the resulting images will look different. 182 | Be a sceptical scietist when processing images in the GPU. 183 | Check that the workflow is indeed doing the right thing. 184 | This is especially important when working with experimental software. 185 | 186 | This is the view on results from the mean filter on CPU and GPU together with the difference image of both: 187 | 188 | ![Image](images/visual_CPU_GPU_comparison.png) 189 | 190 | In presented case, have a look at [mean.ijm](https://github.com/clij/clij-docs/blob/master/src/main/macro/mean.ijm) to see how different the results from CPU and GPU actually are. 191 | In some of the filters, I observed small differences between ImageJ and OpenCL especially at the borders of the images. This is related to the fact that CLIJ contains new implementations of operations in ImageJ. There is a large number of [unit tests in the library](https://github.com/clij/clij/tree/master/src/test/java/net/haesleinhuepf/clij/macro/modules), 192 | ensuring these differences are small and in case they appear, they mostly influence image borders. 193 | 194 | [Back to CLIJ documentation](https://clij.github.io/) 195 | 196 | [Imprint](https://clij.github.io/imprint) 197 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | net.haesleinhuepf 10 | clij-parent-pom 11 | 1.6.0 12 | 13 | 14 | 15 | net.haesleinhuepf 16 | clij-docs 17 | 1.6.0 18 | 19 | clij-docs 20 | clij-docs contains CLIJ documentation and documentation generators. 21 | https://github.com/clij/clij-docs 22 | 2018 23 | 24 | MPI CBG 25 | http://www.mpi-cbg.de 26 | 27 | 28 | 29 | Simplified BSD License 30 | repo 31 | 32 | 33 | 34 | 35 | 36 | haesleinhuepf 37 | Robert Haase 38 | https://haesleinhuepf.net 39 | MPI CBG 40 | 41 | founder 42 | lead 43 | developer 44 | debugger 45 | reviewer 46 | support 47 | maintainer 48 | 49 | 50 | 51 | 52 | 53 | none 54 | 55 | 56 | 57 | 58 | 59 | ImageSc Forum 60 | http://image.sc/ 61 | 62 | 63 | 64 | 65 | scm:git:git://github.com/clij/clij-docs 66 | scm:git:git@github.com/clij/clij-docs 67 | HEAD 68 | https://github.com/clij/clij-docs 69 | 70 | 71 | GitHub Issues 72 | https://github.com/clij/clij-docs/issues 73 | 74 | 75 | None 76 | 77 | 78 | 79 | net.haesleinhuepf 80 | bsd_3 81 | Robert Haase, MPI CBG 82 | C:/programs/fiji-win64/Fiji.app/ 83 | 84 | 85 | 86 | 87 | 88 | net.clearcontrol 89 | clij-coremem 90 | 91 | 92 | net.clearcontrol 93 | clij-clearcl 94 | 95 | 96 | net.haesleinhuepf 97 | clij_ 98 | 99 | 100 | org.scijava 101 | scijava-common 102 | 103 | 104 | net.imglib2 105 | imglib2 106 | 107 | 108 | net.imagej 109 | imagej 110 | 111 | 112 | net.imagej 113 | imagej-legacy 114 | 115 | 116 | 117 | 118 | 119 | clij 120 | http://dl.bintray.com/haesleinhuepf/clij 121 | 122 | 123 | 124 | 125 | 126 | 127 | bintray-haesleinhuepf-snapshots 128 | bintray-clij 129 | https://api.bintray.com/maven/haesleinhuepf/clij/clij-docs/;publish=1 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /quickTour.md: -------------------------------------------------------------------------------- 1 | # CLIJ - a quick tour 2 | CLIJ is a [Fiji](https://fiji.sc) plugin for GPU-accelerated image processing based on [OpenCL](https://opencl.org). However, it is not necessary to learn OpenCL. CLIJ has about 100 predefined functions allowing you to process your images on the GPU. 3 | 4 | It is recommended to use it from Fiji script editor using the ImageJ macro language. For the ease of use, auto-completion is enabled for editing CLIJ workflows. 5 | ![Image](images/autocompletion.png) 6 | 7 | Furthermore, CLIJ has its own menu: `Plugins > ImageJ on GPU (CLIJ)` with sub menus offering all CLIJ functionality. 8 | ![Image](images/menu.gif) 9 | 10 | When clicking on the menu, you see a dialog asking for the parameters of the specific CLIJ operation. Furthermore, user documentation and parameter exlanation is given in the same dialog. 11 | ![Image](images/dialogs.gif) 12 | 13 | CLIJ is fully macro-recordable. After recording your workflow, it can be executed right away. 14 | ![Image](images/clij_macro_recorder2.gif) 15 | [Download video](images/clij_macro_recorder.mp4) 16 | 17 | For exploring CLIJ further, it is recommended to read the [introduction for macro programmers](macro_intro) and have a look at the [code examples](https://clij.github.io/clij-docs/src/main/macro); 18 | 19 | [Back to CLIJ documentation](https://clij.github.io/) 20 | 21 | [Imprint](https://clij.github.io/imprint) 22 | 23 | -------------------------------------------------------------------------------- /release_cycle.md: -------------------------------------------------------------------------------- 1 | # CLIJ Release cycle 2 | tldr: In order to establish CLIJ as a reliable platform for workflow developers, an annual release cycle is aspired. 3 | Core functionality of CLIJ will not change between major releases (except hot fixes). 4 | CLIJ operations may be marked as deprecated in any major release. 5 | Deprecated operations may be removed with any subsequent major release. 6 | Thus, developers have at least one year time to make the transition. 7 | 8 | The following rules are listed to ease the life of downstream / workflow developers. 9 | Ultimate goal is to allow development of long-term running, reliable CLIJ based workflows. 10 | However, to be safe on our side, these rules are not legally binding and may be changed at any point in time. 11 | 12 | ## Releases 13 | CLIJ is released and distributed via two online resources: 14 | * ImageJ update site: http://sites.imagej.net/clij/ 15 | * Bintray maven repository: http://bintray.com/haesleinhuepf/clij/ 16 | 17 | Workflow developers are recommended to base their tools on the current [major release as stated here](https://clij.github.io/clij-docs/dependingViaMaven). 18 | 19 | ## CLIJ core libraries 20 | The release cycle includes CLIJs main libraries: 21 | * https://github.com/clij/clij 22 | * https://github.com/clij/clij-core 23 | * https://github.com/clij/clij-ops 24 | 25 | ## Major releases 26 | * Major releases aim to be published annually on June 13th, starting in 2019. 27 | * Major releases aim being backwards compatible. 28 | * Major releases may mark CLIJ operations as deprecated. 29 | * Major releases may not contain operations which were marked as deprecated in any earlier major release. 30 | 31 | ## Hot fixes 32 | * Bugfixes and corrections may appear at any point in time. 33 | * Code changes releated to hot fixes will be available on the master branch of CLIJs repositories. 34 | * Hot fixes appear in the list of [release notes](https://github.com/clij/clij/releases). 35 | 36 | ## Nightly builds and BETA releases 37 | * Development of CLIJ will be done on the development branch. 38 | Developers who want to test nightly-build like versions of CLIJ are suggested to compile the development branch and ship the binaries to their Fiji installation. 39 | This can be done by running `mvn install` from the respective root directory. 40 | * By mid of May annually, a BETA release is published to allow workflow developers to test their workflows for compatibility with the new release. 41 | 42 | ## Further reading 43 | * [Disclaimer / BSD3 license](https://github.com/clij/clij/blob/master/license.txt) 44 | 45 | 46 | [Back to CLIJ documentation](https://clij.github.io/) 47 | 48 | [Imprint](https://clij.github.io/imprint) 49 | -------------------------------------------------------------------------------- /src/main/beanshell/automaticThreshold.bsh: -------------------------------------------------------------------------------- 1 | // automaticThreshold.bsh 2 | // ====================== 3 | // 4 | // Apply an automatic threshold method to an image on the GPU 5 | // 6 | // Author: Robert Haase, rhaase@mpi-cbg.de 7 | // April 2019 8 | ////////////////////////////////////////// 9 | 10 | import ij.IJ; 11 | import net.haesleinhuepf.clij.CLIJ; 12 | 13 | 14 | IJ.run("Close All"); 15 | 16 | // load example image 17 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 18 | imp.show(); 19 | 20 | // init GPU 21 | clij = CLIJ.getInstance(); 22 | 23 | // push image to GPU 24 | input = clij.push(imp); 25 | 26 | // reserve memory for output, same size and type as input 27 | output = clij.create(input); 28 | 29 | // apply threshold method on GPU 30 | clij.op().automaticThreshold(input, output, "Otsu"); 31 | 32 | // show result 33 | clij.pullBinary(output).show(); 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/beanshell/clij_micromanager.bsh: -------------------------------------------------------------------------------- 1 | // This example script shows how to run CLIJ from MicroManager 2 | // In order to get it run, copy the CLIJ jar-files from the release 3 | // (https://github.com/clij/clij/releases) in the 4 | // plugins directory of MicroManager. 5 | // Tested with MMSetup_64bit_2.0.0-gamma1_20190611 6 | // 7 | // Author: Robert Haase 8 | // June 2019 9 | ///////////////////////////////////////////////////////////////////// 10 | 11 | import net.haesleinhuepf.clij.CLIJ; 12 | import ij.IJ; 13 | import net.haesleinhuepf.clij.converters.implementations.ClearCLBufferToImagePlusConverter; 14 | import net.haesleinhuepf.clij.converters.implementations.ImagePlusToClearCLBufferConverter; 15 | 16 | // initialize CLIJ 17 | clij = CLIJ.getInstance(); 18 | IJ.log(clij.clinfo()); 19 | 20 | // get some test data 21 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 22 | imp.show(); 23 | 24 | // send image to GPU and allocate some memory for result image 25 | gpu_input = clij.push(imp); 26 | gpu_output = clij.create(gpu_input); 27 | 28 | // blur the image 29 | clij.op().blur(gpu_input, gpu_output, 10, 10); 30 | 31 | // get the result back from the GPU and show it 32 | imp = clij.pull(gpu_output); 33 | imp.show(); 34 | 35 | // clean up memory on the GPU 36 | gpu_input.close(); 37 | gpu_output.close(); 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/beanshell/maximumProjection.bsh: -------------------------------------------------------------------------------- 1 | // This script shows how generate a maximum Z projection using CLIJ and BeanShell. 2 | // 3 | // Author: Robert Haase (@haesleinhuepf) 4 | // April 2019 5 | // 6 | //////////////////////////////////////// 7 | 8 | import ij.IJ; 9 | import net.haesleinhuepf.clij.CLIJ; 10 | 11 | IJ.run("Close All"); 12 | 13 | // Init GPU 14 | clij = CLIJ.getInstance(); 15 | 16 | // get some example data 17 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 18 | 19 | // create and fill memory in GPU 20 | imageInput = clij.push(imp); 21 | imageOutput = clij.create(new long[]{imageInput.getWidth(), imageInput.getHeight()}, imageInput.getNativeType()); 22 | 23 | // process the image 24 | clij.op().maximumZProjection(imageInput, imageOutput); 25 | 26 | // show the result 27 | clij.show(imageOutput, "output"); 28 | 29 | // get the result back as variable 30 | result = clij.pull(imageOutput); 31 | 32 | IJ.run("Enhance Contrast", "saturated=0.35"); 33 | -------------------------------------------------------------------------------- /src/main/groovy/automaticThreshold.groovy: -------------------------------------------------------------------------------- 1 | // automaticThreshold.groovy 2 | // ========================= 3 | // 4 | // Apply an automatic threshold method to an image on the GPU 5 | // 6 | // Author: Robert Haase, rhaase@mpi-cbg.de 7 | // April 2019 8 | ////////////////////////////////////////// 9 | 10 | import ij.IJ; 11 | import net.haesleinhuepf.clij.CLIJ; 12 | 13 | 14 | IJ.run("Close All"); 15 | 16 | // load example image 17 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 18 | imp.show(); 19 | 20 | // init GPU 21 | clij = CLIJ.getInstance(); 22 | 23 | // push image to GPU 24 | input = clij.push(imp); 25 | 26 | // reserve memory for output, same size and type as input 27 | output = clij.create(input); 28 | 29 | // apply threshold method on GPU 30 | clij.op().automaticThreshold(input, output, "Otsu"); 31 | 32 | // show result 33 | clij.pullBinary(output).show(); 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/groovy/maximumProjection.groovy: -------------------------------------------------------------------------------- 1 | // This script shows how generate a maximum Z projection using CLIJ and Groovy. 2 | // 3 | // Author: Robert Haase (@haesleinhuepf) 4 | // April 2019 5 | // 6 | //////////////////////////////////////// 7 | 8 | import ij.IJ; 9 | import net.haesleinhuepf.clij.CLIJ; 10 | 11 | IJ.run("Close All"); 12 | 13 | // Init GPU 14 | clij = CLIJ.getInstance(); 15 | 16 | // get some example data 17 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 18 | 19 | // create and fill memory in GPU 20 | imageInput = clij.push(imp); 21 | long[] dimensions = [imageInput.getWidth(), imageInput.getHeight()]; 22 | imageOutput = clij.create(dimensions, imageInput.getNativeType()); 23 | 24 | // process the image 25 | clij.op().maximumZProjection(imageInput, imageOutput); 26 | 27 | // show the result 28 | clij.show(imageOutput, "output"); 29 | 30 | // get the result back as variable 31 | result = clij.pull(imageOutput); 32 | 33 | IJ.run("Enhance Contrast", "saturated=0.35"); 34 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/AffineTransformDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | import net.imglib2.realtransform.AffineTransform3D; 9 | 10 | /** 11 | * AffineTransformDemo 12 | *

13 | *

14 | *

15 | * Author: @haesleinhuepf 16 | * 01 2019 17 | */ 18 | public class AffineTransformDemo { 19 | public static void main(String... args) { 20 | new ImageJ(); 21 | 22 | // load example image 23 | ImagePlus input = IJ.openImage("src/main/resources/flybrain.tif"); 24 | 25 | // initialize GPU 26 | CLIJ clij = CLIJ.getInstance(); 27 | 28 | // push image to GPU 29 | ClearCLBuffer inputOnGPU = clij.push(input); 30 | // create memory for target 31 | ClearCLBuffer resultOnGPU = clij.create(inputOnGPU); 32 | 33 | // define affine transform 34 | AffineTransform3D transform = new AffineTransform3D(); 35 | transform.translate(-inputOnGPU.getWidth() / 2, -inputOnGPU.getHeight() / 2, -inputOnGPU.getDepth() / 2); 36 | transform.rotate(2, 45); 37 | transform.translate(inputOnGPU.getWidth() / 2, inputOnGPU.getHeight() / 2, inputOnGPU.getDepth() / 2); 38 | 39 | // apply transform 40 | clij.op().affineTransform3D(inputOnGPU, resultOnGPU, transform); 41 | 42 | // retrieve result or show it 43 | ImagePlus result = clij.pull(resultOnGPU); 44 | clij.show(resultOnGPU, "result"); 45 | 46 | // free memory 47 | inputOnGPU.close(); 48 | resultOnGPU.close(); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/ApplyVectorFieldDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import ij.gui.NewImage; 7 | import ij.gui.OvalRoi; 8 | import net.haesleinhuepf.clij.CLIJ; 9 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 10 | import net.haesleinhuepf.clij.coremem.enums.NativeTypeEnum; 11 | import net.imglib2.realtransform.AffineTransform2D; 12 | import net.imglib2.realtransform.AffineTransform3D; 13 | 14 | /** 15 | * This script demonstrates how to apply a vector field 16 | * to an image in order to transform it non-rigidly 17 | * 18 | * Author: @haesleinhuepf 19 | * June 2019 20 | */ 21 | public class ApplyVectorFieldDemo { 22 | public static void main(String... args) { 23 | 24 | new ImageJ(); 25 | 26 | // get test image 27 | ImagePlus imp = IJ.openImage("https://samples.fiji.sc/blobs.png"); 28 | IJ.run(imp,"32-bit", ""); 29 | imp.setTitle("blobs"); 30 | 31 | // create two images describing local shift 32 | ImagePlus shiftXimp = NewImage.createFloatImage("shiftX", 256, 254, 1, NewImage.FILL_BLACK); 33 | ImagePlus shiftYimp = NewImage.createFloatImage("shiftY", 256, 254, 1, NewImage.FILL_BLACK); 34 | 35 | // shift some of the pixels in X 36 | shiftXimp.setRoi(new OvalRoi(20, 98, 72, 68)); 37 | IJ.run(shiftXimp, "Add...", "value=25"); 38 | IJ.run(shiftXimp, "Select None", ""); 39 | IJ.run(shiftXimp, "Gaussian Blur...", "sigma=15"); 40 | IJ.run(shiftXimp, "Enhance Contrast", "saturated=0.35"); 41 | 42 | // init GPU 43 | CLIJ clij = CLIJ.getInstance(); 44 | 45 | // push input to GPU 46 | ClearCLBuffer blobsGPU = clij.push(imp); 47 | ClearCLBuffer shiftXgpu = clij.push(shiftXimp); 48 | ClearCLBuffer shiftYgpu = clij.push(shiftYimp); 49 | 50 | // allocate memory for results on GPU 51 | ClearCLBuffer rotatedShiftX = clij.create(blobsGPU); 52 | ClearCLBuffer result = clij.create(blobsGPU); 53 | ClearCLBuffer resultStack = clij.create(new long[]{256, 254, 36}, NativeTypeEnum.Float); 54 | 55 | for (int i = 0; i < 36; i++) { 56 | // define affine transform 57 | AffineTransform2D at = new AffineTransform2D(); 58 | at.translate(-imp.getWidth() / 2, -imp.getHeight() / 2, 0); 59 | at.rotate((double)i * 10 / 180 * Math.PI); 60 | at.translate(imp.getWidth() / 2, imp.getHeight() / 2, 0); 61 | 62 | // rotate vector field 63 | clij.op().affineTransform2D(shiftXgpu, rotatedShiftX, at); 64 | 65 | // apply vector field / transform 66 | clij.op().applyVectorfield(blobsGPU, rotatedShiftX, shiftYgpu, result); 67 | 68 | // put resulting 2D image in the right plane 69 | clij.op().copySlice(result, resultStack, i); 70 | } 71 | 72 | 73 | // get result back from GPU 74 | ImagePlus resultImp = clij.pull(resultStack); 75 | IJ.run(resultImp , "Invert LUT", ""); 76 | resultImp.setDisplayRange(0, 256); 77 | resultImp.show(); 78 | 79 | // clean up memory 80 | blobsGPU.close(); 81 | shiftXgpu.close(); 82 | shiftYgpu.close(); 83 | rotatedShiftX.close(); 84 | result.close(); 85 | resultStack.close(); 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/AutoThresholdDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | 9 | /** 10 | * AutoThresholdDemo 11 | * 12 | * This java example shows how to apply an automatic 13 | * threshold method to an image in the GPU. 14 | * 15 | * Author: @haesleinhuepf 16 | * June 2019 17 | */ 18 | public class AutoThresholdDemo { 19 | public static void main(String[] args) { 20 | new ImageJ(); 21 | 22 | // get test image 23 | ImagePlus imp = IJ.openImage("https://samples.fiji.sc/blobs.png"); 24 | IJ.run(imp,"32-bit", ""); 25 | imp.setTitle("blobs"); 26 | 27 | 28 | // init GPU 29 | CLIJ clij = CLIJ.getInstance(); 30 | 31 | // push image to GPU and allocate memory for result 32 | ClearCLBuffer blobsGPU = clij.push(imp); 33 | ClearCLBuffer thresholded = clij.create(blobsGPU); 34 | 35 | // apply threshold 36 | clij.op().automaticThreshold(blobsGPU, thresholded, "Otsu"); 37 | 38 | // show result 39 | ImagePlus result = clij.pull(thresholded); 40 | result.show(); 41 | 42 | // cleanup 43 | blobsGPU.close(); 44 | thresholded.close(); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/BackgroundSubtractionandThresholdingDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImagePlus; 5 | import net.haesleinhuepf.clij.CLIJ; 6 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 7 | import net.haesleinhuepf.clij.kernels.Kernels; 8 | 9 | /** 10 | * * Mean filter for background determination, 11 | * * background subtractionand 12 | * * thresholding 13 | * 14 | * Author: @haesleinhuepf 15 | * May 2019 16 | */ 17 | public class BackgroundSubtractionandThresholdingDemo { 18 | public static void main(String... args) { 19 | ImagePlus imp = IJ.openImage("src/main/resources/droso_crop.tif"); 20 | 21 | CLIJ clij = CLIJ.getInstance(); 22 | 23 | // conversion 24 | ClearCLBuffer input = clij.push(imp); 25 | ClearCLBuffer output = clij.create(input); 26 | ClearCLBuffer background = clij.create(input); 27 | ClearCLBuffer backgroundSubtracted = clij.create(input); 28 | 29 | // blur 30 | clij.op().meanBox(input, background, 2, 2, 2); 31 | 32 | // background subtraction 33 | clij.op().subtract(input, background, backgroundSubtracted); 34 | 35 | // threshold 36 | clij.op().automaticThreshold(backgroundSubtracted, output, "Otsu"); 37 | 38 | // show results 39 | clij.show(input, "original"); 40 | clij.show(output, "mask"); 41 | 42 | // free memory afterwards 43 | input.close(); 44 | output.close(); 45 | background.close(); 46 | backgroundSubtracted.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/BenchmarkingWorkflowDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImagePlus; 5 | import ij.Prefs; 6 | import ij.plugin.Duplicator; 7 | import ij.plugin.ImageCalculator; 8 | import net.haesleinhuepf.clij.CLIJ; 9 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 10 | import net.imagej.ImageJ; 11 | import net.imglib2.IterableInterval; 12 | import net.imglib2.RandomAccessibleInterval; 13 | import net.imglib2.algorithm.neighborhood.DiamondShape; 14 | import net.imglib2.img.Img; 15 | import net.imglib2.img.display.imagej.ImageJFunctions; 16 | import net.imglib2.roi.Regions; 17 | import net.imglib2.type.BooleanType; 18 | import net.imglib2.type.numeric.RealType; 19 | import net.imglib2.type.numeric.integer.UnsignedByteType; 20 | import net.imglib2.util.Pair; 21 | import net.imglib2.view.Views; 22 | 23 | import java.io.IOException; 24 | 25 | /** 26 | * This class (rather its main method) applies a simple pipeline to a given image. It blurs it, creates a mask by 27 | * thresholding, does some erosion and dilatation to make the edges smoother and finally sets all background pixels in 28 | * the original image to zero. This pipeline is executed in the ImageJ1 way and in OpenCL to compare performance and 29 | * results. 30 | *

31 | * Author: Robert Haase (http://haesleinhuepf.net) at MPI CBG (http://mpi-cbg.de) 32 | * March 2018 33 | */ 34 | public class BenchmarkingWorkflowDemo { 35 | 36 | private static ImageJ ij; 37 | private static CLIJ clij; 38 | private static double sigma = 3; 39 | 40 | public static void main(String... args) throws IOException { 41 | 42 | // --------------------------------------- 43 | // Initialize ImageJ, CLIJ and test image 44 | ij = new ImageJ(); 45 | ij.ui().showUI(); 46 | clij = CLIJ.getInstance(); 47 | 48 | input = IJ.openImage("https://github.com/clij/clij-docs/raw/master/src/main/resources/flybrain.tif"); 49 | input.show(); 50 | IJ.run(input, "8-bit", ""); 51 | img = ImageJFunctions.wrapReal(input); 52 | 53 | for (int i = 0; i < 100; i++) { 54 | // --------------------------------------- 55 | // three test scenarios 56 | long timestamp = System.currentTimeMillis(); 57 | demoImageJ1(); 58 | System.out.println("The ImageJ1 way took " + (System.currentTimeMillis() - timestamp) + " msec"); 59 | 60 | timestamp = System.currentTimeMillis(); 61 | demoImageJ2(); 62 | System.out.println("The ImageJ2 way took " + (System.currentTimeMillis() - timestamp) + " msec"); 63 | 64 | timestamp = System.currentTimeMillis(); 65 | demoCLIJ(); 66 | System.out.println("The CLIJ way took " + (System.currentTimeMillis() - timestamp) + " msec"); 67 | // --------------------------------------- 68 | } 69 | } 70 | 71 | private static ImagePlus input; 72 | private static Img img; 73 | 74 | private static void demoImageJ1() { 75 | ImagePlus copy = new Duplicator().run(input, 1, input.getNSlices()); 76 | Prefs.blackBackground = false; 77 | IJ.run(copy, "Gaussian Blur 3D...", "x=" + sigma + " y=" + sigma + " z=" + sigma + ""); 78 | IJ.setRawThreshold(copy, 100, 255, null); 79 | IJ.run(copy, "Convert to Mask", "method=Default background=Dark"); 80 | IJ.run(copy, "Erode", "stack"); 81 | IJ.run(copy, "Dilate", "stack"); 82 | IJ.run(copy, "Divide...", "value=255 stack"); 83 | ImageCalculator calculator = new ImageCalculator(); 84 | 85 | ImagePlus result = calculator.run("Multiply create stack", copy, input); 86 | result.show(); 87 | } 88 | 89 | private static , B extends BooleanType> void demoImageJ2() { 90 | 91 | // Thanks to @imagejan, @tpietzsch and @Awalter from forum.imagej.net 92 | 93 | UnsignedByteType threshold = new UnsignedByteType(); 94 | threshold.setReal(100); 95 | RandomAccessibleInterval gauss = ij.op().filter().gauss(img, sigma); 96 | 97 | // Gaussian blur 98 | IterableInterval blurredIi = ij.op().threshold().apply(Views.iterable(gauss), threshold); 99 | RandomAccessibleInterval blurredImg = makeRai(blurredIi); 100 | 101 | // erode 102 | IterableInterval erodedIi = ij.op().morphology().erode(blurredImg, new DiamondShape(1)); 103 | RandomAccessibleInterval erodedImg = makeRai(erodedIi); 104 | 105 | // dilate 106 | IterableInterval dilatedIi = ij.op().morphology().dilate(erodedImg, new DiamondShape(1)); 107 | RandomAccessibleInterval dilatedImg = makeRai(dilatedIi); 108 | 109 | // mask original image 110 | Img output = ij.op().create().img(img); 111 | IterableInterval> sample = Regions.sample( 112 | Regions.iterable(dilatedImg), 113 | Views.pair(output, img) 114 | ); 115 | sample.forEach(pair -> pair.getA().set(pair.getB())); 116 | 117 | ImageJFunctions.show(output); 118 | 119 | } 120 | 121 | private static RandomAccessibleInterval makeRai(IterableInterval ii) { 122 | RandomAccessibleInterval rai; 123 | if (ii instanceof RandomAccessibleInterval) { 124 | rai = (RandomAccessibleInterval) ii; 125 | } else { 126 | rai = ij.op().create().img(ii); 127 | ij.op().copy().iterableInterval((Img) rai, ii); 128 | } 129 | return rai; 130 | } 131 | 132 | private static void demoCLIJ() throws IOException { 133 | ClearCLBuffer input = clij.push(img); 134 | ClearCLBuffer flip = clij.create(input.getDimensions(), input.getNativeType()); 135 | ClearCLBuffer flop = clij.create(input.getDimensions(), input.getNativeType()); 136 | 137 | clij.op().blur(input, flop, (float) sigma, (float) sigma, (float) sigma); 138 | 139 | clij.op().threshold(flop, flip, 100.0f); 140 | 141 | clij.op().erodeSphere(flip, flop); 142 | clij.op().dilateSphere(flop, flip); 143 | 144 | clij.op().multiplyImages(flop, input, flip); 145 | 146 | clij.pull(flip).show(); 147 | 148 | flip.close(); 149 | flop.close(); 150 | input.close(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/BinaryProcessingDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | 9 | /** 10 | * BinaryProcessingDemo 11 | * 12 | * This java example shows how to apply an automatic 13 | * threshold method to an image in the GPU. 14 | * 15 | * Author: @haesleinhuepf 16 | * June 2019 17 | */ 18 | public class BinaryProcessingDemo { 19 | public static void main(String[] args) { 20 | new ImageJ(); 21 | 22 | // get test image 23 | ImagePlus imp = IJ.openImage("https://samples.fiji.sc/blobs.png"); 24 | IJ.run(imp,"32-bit", ""); 25 | imp.setTitle("blobs"); 26 | 27 | 28 | // init GPU 29 | CLIJ clij = CLIJ.getInstance(); 30 | 31 | // push image to GPU and allocate memory for result 32 | ClearCLBuffer blobsGPU = clij.push(imp); 33 | ClearCLBuffer thresholded = clij.create(blobsGPU); 34 | ClearCLBuffer temp = clij.create(blobsGPU); 35 | 36 | // apply threshold 37 | clij.op().automaticThreshold(blobsGPU, thresholded, "Otsu"); 38 | 39 | // binary opening 40 | clij.op().erodeBox(thresholded, temp); 41 | clij.op().erodeBox(temp, thresholded); 42 | clij.op().dilateBox(thresholded, temp); 43 | clij.op().dilateBox(temp, thresholded); 44 | 45 | // show result 46 | ImagePlus result = clij.pullBinary(thresholded); 47 | result.show(); 48 | 49 | // cleanup 50 | blobsGPU.close(); 51 | thresholded.close(); 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/BlurDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImagePlus; 5 | import net.haesleinhuepf.clij.CLIJ; 6 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 7 | 8 | /** 9 | * Apply a Gaussian blur to an image on the GPU 10 | * 11 | * Author: @haesleinhuepf 12 | * June 2019 13 | */ 14 | public class BlurDemo { 15 | public static void main(String... args) { 16 | ImagePlus imp = IJ.openImage("https://samples.fiji.sc/blobs.png"); 17 | 18 | CLIJ clij = CLIJ.getInstance(); 19 | 20 | // conversion 21 | ClearCLBuffer input = clij.push(imp); 22 | ClearCLBuffer output = clij.create(input); 23 | 24 | // blur 25 | float sigma = 2; 26 | clij.op().blur(input, output, sigma, sigma); 27 | 28 | ImagePlus result = clij.pull(output); 29 | result.show(); 30 | 31 | // free memory afterwards 32 | input.close(); 33 | output.close(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/CLIJImageJOpsCombinationDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImagePlus; 5 | import net.haesleinhuepf.clij.CLIJ; 6 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 7 | import net.haesleinhuepf.clij.coremem.enums.NativeTypeEnum; 8 | import net.imagej.ImageJ; 9 | import net.imglib2.RandomAccessibleInterval; 10 | import net.imglib2.algorithm.labeling.ConnectedComponents; 11 | import net.imglib2.img.display.imagej.ImageJFunctions; 12 | import net.imglib2.roi.labeling.ImgLabeling; 13 | import net.imglib2.roi.labeling.LabelRegions; 14 | import net.imglib2.type.logic.BitType; 15 | import net.imglib2.type.numeric.IntegerType; 16 | 17 | /** 18 | * CLIJImageJOpsCombinationDemo 19 | *

20 | *

21 | *

22 | * Author: @haesleinhuepf 23 | * 02 2019 24 | */ 25 | public class CLIJImageJOpsCombinationDemo { 26 | public static void main(String... args) { 27 | // define parameters 28 | String filename = "src/main/resources/blobs.tif"; 29 | float sigma = 3; 30 | 31 | // load test data 32 | ImageJ ij = new ImageJ(); 33 | ij.ui().showUI(); 34 | ImagePlus imp = IJ.openImage(filename); 35 | imp.show(); 36 | 37 | // reserve memory on GPU / transfer images 38 | CLIJ clij = CLIJ.getInstance(); 39 | ClearCLBuffer input = clij.push(imp); 40 | ClearCLBuffer blurred = clij.create(input); 41 | ClearCLBuffer thresholded = clij.createCLBuffer(input.getDimensions(), NativeTypeEnum.Byte); 42 | 43 | // Gaussian blur 44 | clij.op().blur(input, blurred, sigma, sigma, sigma); 45 | 46 | // Apply Otsu threshold 47 | clij.op().automaticThreshold(blurred, thresholded, "Otsu"); 48 | 49 | // convert back from GPU 50 | ImagePlus result = clij.pull(thresholded); 51 | RandomAccessibleInterval binaryRai = clij.pullBinaryRAI(thresholded); 52 | 53 | // clean up 54 | input.close(); 55 | blurred.close(); 56 | thresholded.close(); 57 | 58 | // show result from GPU 59 | result.show(); 60 | 61 | //continue with Ops 62 | ImgLabeling cca = ij.op().labeling().cca(binaryRai, ConnectedComponents.StructuringElement.FOUR_CONNECTED); 63 | 64 | LabelRegions regions = new LabelRegions(cca); 65 | 66 | System.out.print("Number of objects found: " + regions.getExistingLabels().size()); 67 | 68 | // show results of labelling on CPU 69 | ImageJFunctions.show(cca.getIndexImg()); 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/ClinfoDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import net.haesleinhuepf.clij.CLIJ; 4 | 5 | /** 6 | * This demo just shows how to output all information known on available 7 | * OpenCL devices to stdout. 8 | *

9 | * Author: Robert Haase (http://haesleinhuepf.net) at MPI CBG (http://mpi-cbg.de) 10 | * February 2018 11 | */ 12 | public class ClinfoDemo { 13 | public static void main(String... args) { 14 | 15 | System.out.println(CLIJ.clinfo()); 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/CreateObjectOutlinesDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | 9 | /** 10 | * AutoThresholdDemo 11 | * 12 | * This java example shows how to apply an automatic 13 | * threshold method to an image and get the segmentations 14 | * outline as binary image in the GPU. 15 | * 16 | * Author: @haesleinhuepf 17 | * June 2019 18 | */ 19 | public class CreateObjectOutlinesDemo { 20 | public static void main(String[] args) { 21 | new ImageJ(); 22 | 23 | // get test image 24 | ImagePlus imp = IJ.openImage("https://samples.fiji.sc/blobs.png"); 25 | IJ.run(imp,"32-bit", ""); 26 | imp.setTitle("blobs"); 27 | 28 | 29 | // init GPU 30 | CLIJ clij = CLIJ.getInstance(); 31 | 32 | // push image to GPU and allocate memory for result 33 | ClearCLBuffer blobsGPU = clij.push(imp); 34 | ClearCLBuffer thresholded = clij.create(blobsGPU); 35 | ClearCLBuffer extended = clij.create(blobsGPU); 36 | ClearCLBuffer outline= clij.create(blobsGPU); 37 | 38 | 39 | // apply threshold 40 | clij.op().automaticThreshold(blobsGPU, thresholded, "Otsu"); 41 | 42 | clij.op().dilateBox(thresholded, extended); 43 | 44 | clij.op().binaryXOr(thresholded, extended, outline); 45 | 46 | 47 | 48 | // show result 49 | ImagePlus result = clij.pullBinary(outline); 50 | result.show(); 51 | 52 | // cleanup 53 | blobsGPU.close(); 54 | thresholded.close(); 55 | extended.close(); 56 | outline.close(); 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/LocalThresholdDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImagePlus; 5 | import net.haesleinhuepf.clij.CLIJ; 6 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 7 | import net.haesleinhuepf.clij.kernels.Kernels; 8 | 9 | /** 10 | * LocalThresholdDemo 11 | *

12 | *

13 | *

14 | * Author: @haesleinhuepf 15 | * 06 2018 16 | */ 17 | public class LocalThresholdDemo { 18 | public static void main(String... args) { 19 | ImagePlus imp = IJ.openImage("src/main/resources/droso_crop.tif"); 20 | 21 | CLIJ clij = CLIJ.getInstance(); 22 | 23 | // conversion 24 | ClearCLBuffer input = clij.push(imp); 25 | ClearCLBuffer output = clij.create(input); 26 | ClearCLBuffer temp = clij.create(input); 27 | 28 | // blur 29 | Kernels.blur(clij, input, temp, 2f, 2f, 2f); 30 | 31 | // local threshold 32 | Kernels.localThreshold(clij, input, output, temp); 33 | 34 | Kernels.erodeSphere(clij, output, temp); 35 | Kernels.erodeSphere(clij, temp, output); 36 | 37 | // show results 38 | clij.show(input, "original"); 39 | clij.show(output, "mask"); 40 | 41 | input.close(); 42 | output.close(); 43 | temp.close(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/MaximumProjectionDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | import net.imglib2.realtransform.AffineTransform3D; 9 | 10 | /** 11 | * MaximumProjectionDemo 12 | *

13 | *

14 | *

15 | * Author: @haesleinhuepf 16 | * 06 2019 17 | */ 18 | public class MaximumProjectionDemo { 19 | public static void main(String[] args) { 20 | new ImageJ(); 21 | 22 | // load example image 23 | ImagePlus input = IJ.openImage("https://imagej.nih.gov/ij/images/t1-head.zip"); 24 | 25 | // initialize GPU 26 | CLIJ clij = CLIJ.getInstance(); 27 | 28 | // push image to GPU 29 | ClearCLBuffer inputOnGPU = clij.push(input); 30 | // create memory for target 31 | ClearCLBuffer resultOnGPU = clij.create(new long[]{inputOnGPU.getWidth(), inputOnGPU.getHeight()}, inputOnGPU.getNativeType()); 32 | 33 | // apply transform 34 | clij.op().maximumZProjection(inputOnGPU, resultOnGPU); 35 | 36 | // retrieve result or show it 37 | ImagePlus result = clij.pull(resultOnGPU); 38 | clij.show(resultOnGPU, "result"); 39 | 40 | // free memory 41 | inputOnGPU.close(); 42 | resultOnGPU.close(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/MotionCorrectionDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | import net.haesleinhuepf.clij.macro.modules.Clear; 9 | import net.imglib2.realtransform.AffineTransform3D; 10 | 11 | /** 12 | * MotionCorrectionDemo 13 | *

14 | *

15 | *

16 | * Author: @haesleinhuepf 17 | * 06 2019 18 | */ 19 | public class MotionCorrectionDemo { 20 | public static void main(String[] args) { 21 | new ImageJ(); 22 | 23 | // define move to correct 24 | ImagePlus imp = IJ.openImage("src/main/resources/motion_correction_Drosophila_DSmanila1.tif"); 25 | IJ.run(imp, "32-bit", ""); 26 | imp.show(); 27 | 28 | // define a threshold to differentiate object and background 29 | float threshold = 50; 30 | 31 | // Init GPU 32 | CLIJ clij = CLIJ.getInstance(); 33 | 34 | // push input to GPU 35 | ClearCLBuffer input = clij.push(imp); 36 | 37 | // create some slice images on the GPU to work on 38 | ClearCLBuffer inputSlice = clij.create(new long[]{input.getWidth(), input.getHeight()}, input.getNativeType()); 39 | ClearCLBuffer thresholded = clij.create(inputSlice); 40 | ClearCLBuffer shifted = clij.create(inputSlice); 41 | 42 | double formerX = 0; 43 | double formerY = 0; 44 | 45 | // process all slices; only the first stays where it is 46 | for (int z = 0; z < imp.getNSlices(); z++) { 47 | System.out.println("z: " + z); 48 | clij.op().copySlice(input, inputSlice, z); 49 | 50 | // determine center of mass 51 | 52 | clij.op().threshold(inputSlice, thresholded, threshold); 53 | double[] centerOfMass = clij.op().centerOfMass(thresholded); 54 | 55 | if (z > 0) { 56 | 57 | // determine shift 58 | double deltaX = centerOfMass[0] - formerX; 59 | double deltaY = centerOfMass[1] - formerY; 60 | 61 | // apply translation transformation 62 | AffineTransform3D at = new AffineTransform3D(); 63 | at.translate(-deltaX, -deltaY, 0); 64 | 65 | clij.op().affineTransform(inputSlice, shifted, at); 66 | 67 | // copy result back 68 | clij.op().copySlice(shifted, input, z); 69 | 70 | } else { 71 | formerX = centerOfMass[0]; 72 | formerY = centerOfMass[1]; 73 | } 74 | } 75 | 76 | // show result 77 | ImagePlus result = clij.pull(input); 78 | result.setDisplayRange(imp.getDisplayRangeMin(), imp.getDisplayRangeMax()); 79 | result.setTitle("Motion corrected"); 80 | result.show(); 81 | 82 | input.close(); 83 | inputSlice.close(); 84 | thresholded.close(); 85 | shifted.close(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/MultipleGPUDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples; 2 | 3 | import com.sun.org.apache.xpath.internal.operations.Mult; 4 | import ij.IJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * This demo runs on a computer with multiple GPUs. It processes images in parallel on both GPUs. 13 | * 14 | * Author: Robert Haase, MPI CBG 15 | * June 2019 16 | */ 17 | public class MultipleGPUDemo { 18 | 19 | public static void main(String... args) { 20 | new MultipleGPUDemo().run(); 21 | } 22 | 23 | public void run() { 24 | ArrayList deviceIndices = new ArrayList(); 25 | 26 | int count = 0; 27 | // print out all GPU names 28 | for (String deviceName : CLIJ.getAvailableDeviceNames()) { 29 | System.out.println(deviceName); 30 | if (deviceName.toLowerCase().contains("gpu") || // Intel HD GPUs 31 | deviceName.toLowerCase().contains("gfx") || // AMD Ryzen GPUs 32 | deviceName.toLowerCase().contains("geforce") // NVidia Geforce GPUs 33 | ) { 34 | deviceIndices.add(count); 35 | } 36 | count++; 37 | } 38 | 39 | if (deviceIndices.size() < 2) { 40 | System.out.println("This computer doesn't have several GPUs. This demo needs several GPUs."); 41 | return; 42 | } 43 | 44 | // get CLIJ instances operating on different GPUs 45 | CLIJ clijGPU1 = new CLIJ(deviceIndices.get(0)); 46 | CLIJ clijGPU2 = new CLIJ(deviceIndices.get(1)); 47 | 48 | ImagePlus imp = IJ.openImage("src/main/resources/droso_crop.tif"); 49 | 50 | // create multiple processors using different GPUs 51 | Processor processorGPU1 = new Processor(clijGPU1, imp); 52 | Processor processorGPU2 = new Processor(clijGPU2, imp); 53 | 54 | // start processing 55 | processorGPU1.start(); 56 | processorGPU2.start(); 57 | 58 | // wait until processing is done on both GPUs 59 | try { 60 | processorGPU1.join(); 61 | processorGPU2.join(); 62 | 63 | Thread.sleep(5000); 64 | } catch (InterruptedException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | 69 | class Processor extends Thread { 70 | CLIJ clij; 71 | ImagePlus imp; 72 | public Processor(CLIJ clij, ImagePlus imp) { 73 | this.clij = clij; 74 | this.imp = imp; 75 | } 76 | 77 | @Override 78 | public void run() { 79 | String gpuName = clij.getGPUName(); 80 | log(gpuName + " start"); 81 | 82 | // send an image to GPU and allocate memory for another image 83 | ClearCLBuffer input = clij.push(imp); 84 | ClearCLBuffer output = clij.create(input); 85 | log(gpuName + " copy done"); 86 | 87 | // apply a Gaussian blur 88 | float sigma = 25; 89 | clij.op().blur(input, output, sigma, sigma, sigma); 90 | log(gpuName + " blur done"); 91 | 92 | // show results 93 | clij.show(output, "Result on " + clij.getGPUName()); 94 | log(gpuName + " finished"); 95 | 96 | // cleanup memory 97 | input.close(); 98 | output.close(); 99 | } 100 | } 101 | 102 | private void log(String text) { 103 | synchronized (this) { 104 | System.out.println("" + System.currentTimeMillis() + "\t" + text); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/advanced/CLIJMacroPluginServiceDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples.advanced; 2 | 3 | import ij.IJ; 4 | import ij.macro.ExtensionDescriptor; 5 | import net.haesleinhuepf.clij.macro.CLIJHandler; 6 | import net.haesleinhuepf.clij.macro.CLIJMacroPluginService; 7 | import net.imagej.ImageJ; 8 | 9 | import java.util.Arrays; 10 | 11 | /** 12 | * The CLIJMacroPluginServiceDemo shows how to run CLJI Macro modules from Java. 13 | *

14 | * Author: @haesleinhuepf 15 | * December 2018 16 | */ 17 | public class CLIJMacroPluginServiceDemo { 18 | public static void main(String... args) { 19 | ImageJ ij = new ImageJ(); 20 | ij.ui().showUI(); 21 | 22 | // get the plugin service from ImageJ 23 | CLIJMacroPluginService clijMacroPluginService = ij.get(CLIJMacroPluginService.class); 24 | 25 | // print out registered plugins / methods 26 | for (String name : clijMacroPluginService.getCLIJMethodNames()) { 27 | System.out.println(name); 28 | } 29 | 30 | // print some more details; namely parameters 31 | for (ExtensionDescriptor ed : CLIJHandler.getInstance().getExtensionFunctions()) { 32 | System.out.println(ed.name + " " + Arrays.toString(ed.argTypes)); 33 | } 34 | 35 | // load image and push it to GPU 36 | IJ.open("https://github.com/clij/clij-docs/raw/master/src/main/resources/flybrain.tif"); 37 | CLIJHandler.getInstance().handleExtension("CLIJ_push", new Object[] {"flybrain.tif"}); 38 | 39 | // execute a processing CLIJ macro operation on it 40 | Object[] arguments = new Object[]{ 41 | "flybrain.tif", 42 | "out", 43 | new Double(5), 44 | new Double(5), 45 | new Double(5) 46 | }; 47 | CLIJHandler.getInstance().handleExtension("CLIJ_mean3DBox", arguments); 48 | 49 | // retrieve result 50 | CLIJHandler.getInstance().handleExtension("CLIJ_pull", new Object[] {"out"}); 51 | 52 | // clean up 53 | CLIJHandler.getInstance().handleExtension("CLIJ_clear", new Object[]{}); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/advanced/CustomOpenCLDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples.advanced; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import net.haesleinhuepf.clij.CLIJ; 7 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 8 | import net.haesleinhuepf.clij.kernels.Kernels; 9 | import net.imglib2.RandomAccessibleInterval; 10 | import net.imglib2.img.display.imagej.ImageJFunctions; 11 | 12 | import java.io.IOException; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * This example shows how to take input images, process them through 18 | * by two OpenCL kernels and show the result 19 | *

20 | * Author: Robert Haase (http://haesleinhuepf.net) at MPI CBG (http://mpi-cbg.de) 21 | * February 2018 22 | */ 23 | public class CustomOpenCLDemo { 24 | 25 | public static void main(String... args) throws IOException { 26 | // Initialize ImageJ and example images 27 | new ImageJ(); 28 | ImagePlus inputImp = IJ.openImage("https://github.com/clij/clij-docs/raw/master/src/main/resources/flybrain.tif"); 29 | inputImp.show(); 30 | 31 | // Startup OpenCL device, convert images to ClearCL format 32 | CLIJ clij = CLIJ.getInstance(); 33 | 34 | ClearCLBuffer inputCLBuffer = clij.push(inputImp); 35 | ClearCLBuffer outputCLBuffer = clij.create(inputCLBuffer); 36 | 37 | // --------------------------------------------------------------- 38 | // Example step 1: Downsampling 39 | 40 | Map parameterMap = new HashMap<>(); 41 | parameterMap.put("src", inputCLBuffer); 42 | parameterMap.put("dst", outputCLBuffer); 43 | parameterMap.put("factor_x", 0.5f); 44 | parameterMap.put("factor_y", 0.5f); 45 | parameterMap.put("factor_z", 1.f); 46 | 47 | clij.execute(Kernels.class, "downsampling.cl", "downsample_3d_nearest", parameterMap); 48 | 49 | // Convert/copy and show intermediate result 50 | RandomAccessibleInterval intermediateResult = clij.convert(outputCLBuffer, RandomAccessibleInterval.class); 51 | 52 | ImageJFunctions.show(intermediateResult); 53 | 54 | // --------------------------------------------------------------- 55 | // Example Step 2: Bluring 56 | HashMap blurParameterMap = new HashMap<>(); 57 | blurParameterMap.put("Nx", 3); 58 | blurParameterMap.put("Ny", 3); 59 | blurParameterMap.put("Nz", 3); 60 | blurParameterMap.put("sx", 2.0f); 61 | blurParameterMap.put("sy", 2.0f); 62 | blurParameterMap.put("sz", 2.0f); 63 | // we reuse memory in the GPU by taking the result from the former 64 | // step as input here and the input from the former step as 65 | // output: 66 | blurParameterMap.put("src", outputCLBuffer); 67 | blurParameterMap.put("dst", inputCLBuffer); 68 | 69 | clij.execute(Kernels.class, "blur.cl", "gaussian_blur_image3d", blurParameterMap); 70 | 71 | // Convert and show final result 72 | RandomAccessibleInterval result = clij.convert(inputCLBuffer, RandomAccessibleInterval.class); 73 | 74 | ImageJFunctions.show(result); 75 | 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/advanced/DifferenceOfGaussianCLDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples.advanced; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import ij.plugin.Duplicator; 7 | import net.haesleinhuepf.clij.CLIJ; 8 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 9 | import net.imglib2.RandomAccessibleInterval; 10 | import net.imglib2.img.display.imagej.ImageJFunctions; 11 | import net.imglib2.type.numeric.integer.UnsignedShortType; 12 | 13 | import java.io.IOException; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | /** 18 | * This 19 | *

20 | * Author: Robert Haase (http://haesleinhuepf.net) at MPI CBG (http://mpi-cbg.de) 21 | * February 2018 22 | */ 23 | public class DifferenceOfGaussianCLDemo { 24 | public static void main(String... args) throws IOException { 25 | new ImageJ(); 26 | ImagePlus inputImp = IJ.openImage("https://github.com/clij/clij-docs/raw/master/src/main/resources/flybrain.tif"); 27 | 28 | inputImp = new Duplicator().run(inputImp, 25, 25); 29 | 30 | RandomAccessibleInterval input = ImageJFunctions.wrap(inputImp); 31 | 32 | RandomAccessibleInterval output = ImageJFunctions.wrap(new Duplicator().run(inputImp)); 33 | 34 | ImageJFunctions.show(input); 35 | 36 | CLIJ clij = CLIJ.getInstance(); 37 | 38 | // --------------------------------------------------------------- 39 | // Example 1: Flip image in X 40 | { 41 | ClearCLBuffer srcImage = clij.push(input); 42 | ClearCLBuffer dstImage = clij.push(output); 43 | 44 | Map parameterMap = new HashMap<>(); 45 | parameterMap.put("src", srcImage); 46 | parameterMap.put("dst", dstImage); 47 | parameterMap.put("radius", 6); 48 | parameterMap.put("sigma_minuend", 1.5f); 49 | parameterMap.put("sigma_subtrahend", 3f); 50 | 51 | clij.execute("src/main/jython/differenceOfGaussian/differenceOfGaussian.cl", "subtract_convolved_images_2d_fast", parameterMap); 52 | 53 | ImagePlus result = clij.pull(dstImage); 54 | result.show(); 55 | IJ.run(result,"Enhance Contrast", "saturated=0.35"); 56 | 57 | } 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/advanced/FlipCustomOpenCLDemo.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.examples.advanced; 2 | 3 | import ij.IJ; 4 | import ij.ImageJ; 5 | import ij.ImagePlus; 6 | import ij.plugin.Duplicator; 7 | import net.haesleinhuepf.clij.CLIJ; 8 | import net.haesleinhuepf.clij.clearcl.ClearCLBuffer; 9 | import net.imglib2.RandomAccessibleInterval; 10 | import net.imglib2.img.display.imagej.ImageJFunctions; 11 | import net.imglib2.type.numeric.integer.UnsignedShortType; 12 | 13 | import java.io.IOException; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | /** 18 | * This 19 | *

20 | * Author: Robert Haase (http://haesleinhuepf.net) at MPI CBG (http://mpi-cbg.de) 21 | * February 2018 22 | */ 23 | public class FlipCustomOpenCLDemo { 24 | public static void main(String... args) throws IOException { 25 | new ImageJ(); 26 | ImagePlus lInputImagePlus = IJ.openImage("https://github.com/clij/clij-docs/raw/master/src/main/resources/flybrain.tif"); 27 | 28 | RandomAccessibleInterval input = ImageJFunctions.wrap(lInputImagePlus); 29 | 30 | RandomAccessibleInterval output = ImageJFunctions.wrap(new Duplicator().run(lInputImagePlus)); 31 | 32 | ImageJFunctions.show(input); 33 | 34 | CLIJ clij = CLIJ.getInstance(); 35 | 36 | // --------------------------------------------------------------- 37 | // Example 1: Flip image in X 38 | { 39 | ClearCLBuffer srcImage = clij.push(input); 40 | ClearCLBuffer dstImage = clij.push(output); 41 | 42 | Map lParameterMap = new HashMap<>(); 43 | lParameterMap.put("src", srcImage); 44 | lParameterMap.put("dst", dstImage); 45 | lParameterMap.put("flipx", 1); 46 | lParameterMap.put("flipy", 0); 47 | lParameterMap.put("flipz", 0); 48 | 49 | clij.execute("src/main/java/net/haesleinhuepf/clij/examples/advanced/flip.cl", "flip_3d", lParameterMap); 50 | 51 | ImagePlus result = clij.pull(dstImage); 52 | result.show(); 53 | IJ.run(result,"Enhance Contrast", "saturated=0.35"); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/haesleinhuepf/clij/examples/advanced/flip.cl: -------------------------------------------------------------------------------- 1 | 2 | __kernel void flip_3d ( DTYPE_IMAGE_IN_3D src, 3 | DTYPE_IMAGE_OUT_3D dst, 4 | const int flipx, 5 | const int flipy, 6 | const int flipz 7 | ) 8 | { 9 | const sampler_t intsampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; 10 | 11 | const int x = get_global_id(0); 12 | const int y = get_global_id(1); 13 | const int z = get_global_id(2); 14 | 15 | const int width = get_global_size(0); 16 | const int height = get_global_size(1); 17 | const int depth = get_global_size(2); 18 | 19 | const int4 pos = (int4)(flipx?(width-1-x):x, 20 | flipy?(height-1-y):y, 21 | flipz?(depth-1-z):z,0); 22 | 23 | const DTYPE_IN value = READ_IMAGE_3D(src, intsampler, pos).x; 24 | 25 | WRITE_IMAGE_3D (dst, (int4)(x,y,z,0), (DTYPE_OUT)value); 26 | } 27 | 28 | 29 | __kernel void flip_2d ( DTYPE_IMAGE_IN_2D src, 30 | DTYPE_IMAGE_OUT_2D dst, 31 | const int flipx, 32 | const int flipy 33 | ) 34 | { 35 | const sampler_t intsampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; 36 | 37 | const int x = get_global_id(0); 38 | const int y = get_global_id(1); 39 | 40 | const int width = get_global_size(0); 41 | const int height = get_global_size(1); 42 | 43 | const int2 pos = (int2)(flipx?(width-1-x):x, 44 | flipy?(height-1-y):y); 45 | 46 | const DTYPE_IN value = READ_IMAGE_2D(src, intsampler, pos).x; 47 | 48 | WRITE_IMAGE_2D (dst, (int2)(x,y), (DTYPE_OUT)value); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/javascript/automaticThreshold.js: -------------------------------------------------------------------------------- 1 | // automaticThreshold.js 2 | // ===================== 3 | // 4 | // Apply an automatic threshold method to an image on the GPU 5 | // 6 | // Author: Robert Haase, rhaase@mpi-cbg.de 7 | // April 2019 8 | ////////////////////////////////////////// 9 | importClass(Packages.ij.IJ); 10 | importClass(Packages.net.haesleinhuepf.clij.CLIJ); 11 | 12 | IJ.run("Close All"); 13 | 14 | // load example image 15 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 16 | imp.show(); 17 | 18 | // init GPU 19 | clij = CLIJ.getInstance(); 20 | 21 | // push image to GPU 22 | input = clij.push(imp); 23 | 24 | // reserve memory for output, same size and type as input 25 | output = clij.create(input); 26 | 27 | // apply threshold method on GPU 28 | clij.op().automaticThreshold(input, output, "Otsu"); 29 | 30 | // show result 31 | clij.pullBinary(output).show(); 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/javascript/maximumProjection.js: -------------------------------------------------------------------------------- 1 | // This script shows how generate a maximum Z projection using CLIJ and javascript. 2 | // 3 | // Author: Robert Haase (@haesleinhuepf) 4 | // April 2019 5 | // 6 | 7 | //////////////////////////////////////// 8 | importClass(Packages.ij.IJ); 9 | importClass(Packages.net.haesleinhuepf.clij.CLIJ); 10 | 11 | IJ.run("Close All"); 12 | 13 | // Init GPU 14 | clij = CLIJ.getInstance(); 15 | 16 | // get some example data 17 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 18 | 19 | // create and fill memory in GPU 20 | imageInput = clij.push(imp); 21 | dimensions = [imageInput.getWidth(), imageInput.getHeight()]; 22 | imageOutput = clij.create(dimensions, imageInput.getNativeType()); 23 | 24 | // process the image 25 | clij.op().maximumZProjection(imageInput, imageOutput); 26 | 27 | // show the result 28 | clij.show(imageOutput, "output"); 29 | 30 | // get the result back as variable 31 | result = clij.pull(imageOutput); 32 | 33 | IJ.run("Enhance Contrast", "saturated=0.35"); 34 | -------------------------------------------------------------------------------- /src/main/jython/addImages.py: -------------------------------------------------------------------------------- 1 | # addImages.py 2 | # ============ 3 | # 4 | # This script demonstrates basic image math 5 | # on the GPU 6 | # 7 | # Author: Robert Haase, rhaase@mpi-cbg.de 8 | # October 2019 9 | ######################################### 10 | 11 | from ij import IJ; 12 | from net.haesleinhuepf.clij import CLIJ; 13 | 14 | from ij.gui import NewImage; 15 | 16 | IJ.run("Close All"); 17 | 18 | # load/create example images 19 | imp1 = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 20 | IJ.run(imp1, "32-bit", ""); 21 | imp1.show(); 22 | 23 | imp2 = NewImage.createFloatImage("", imp1.getWidth(), imp1.getHeight(), 1, NewImage.FILL_RAMP); 24 | 25 | # init GPU 26 | clij = CLIJ.getInstance(); 27 | 28 | # push image to GPU 29 | input1 = clij.push(imp1); 30 | input2 = clij.push(imp2); 31 | 32 | # reserve memory for output, same size and type as input 33 | temp = clij.create(input1); 34 | output = clij.create(input1); 35 | 36 | # multiply ramp image so that it's in the same range as blobs 37 | clij.op().multiplyImageAndScalar(input2, temp, 255); 38 | 39 | # sum blobs and ramp 40 | clij.op().addImages(input1, temp, output); 41 | 42 | # show result 43 | clij.pull(output).show(); 44 | IJ.setMinAndMax(0, 255); 45 | 46 | input1.close(); 47 | input2.close(); 48 | temp.close(); 49 | output.close(); 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/jython/affineTransform.py: -------------------------------------------------------------------------------- 1 | # affineTransform.py 2 | # ================== 3 | # 4 | # This script demonstrates how to apply an 5 | # affine transform on the GPU 6 | # 7 | # Author: Robert Haase, rhaase@mpi-cbg.de 8 | # October 2019 9 | ######################################### 10 | 11 | from ij import IJ; 12 | from net.haesleinhuepf.clij import CLIJ; 13 | from net.imglib2.realtransform import AffineTransform2D; 14 | from java.lang import Math; 15 | 16 | IJ.run("Close All"); 17 | 18 | # load/create example images 19 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 20 | IJ.run(imp, "32-bit", ""); 21 | imp.show(); 22 | 23 | # init GPU 24 | clij = CLIJ.getInstance(); 25 | 26 | # push image to GPU 27 | input = clij.push(imp); 28 | 29 | # reserve memory for output, same size and type as input 30 | output = clij.create(input); 31 | 32 | 33 | at = AffineTransform2D(); 34 | at.translate(-input.getWidth() / 2, -input.getHeight() / 2); 35 | at.rotate(45.0 / 180.0 * Math.PI); 36 | at.scale(0.5, 0.5); 37 | at.translate(input.getWidth() / 2, input.getHeight() / 2); 38 | 39 | # Execute operation on GPU 40 | clij.op().affineTransform2D(input, output, at); 41 | 42 | # show result 43 | clij.pull(output).show(); 44 | IJ.setMinAndMax(0, 255); 45 | 46 | input.close(); 47 | output.close(); 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/jython/applyVectorField.py: -------------------------------------------------------------------------------- 1 | # applyVectorField.py 2 | # =================== 3 | # 4 | # This script demonstrates how to apply a 5 | # warping to an image on the GPU 6 | # 7 | # Author: Robert Haase, rhaase@mpi-cbg.de 8 | # October 2019 9 | ######################################### 10 | 11 | from ij import IJ; 12 | from net.haesleinhuepf.clij import CLIJ; 13 | from net.imglib2.realtransform import AffineTransform2D; 14 | 15 | from ij.gui import NewImage; 16 | from ij.gui import OvalRoi; 17 | 18 | from java.lang import Math; 19 | 20 | 21 | IJ.run("Close All"); 22 | 23 | # load/create example images 24 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 25 | IJ.run(imp, "32-bit", ""); 26 | imp.show(); 27 | 28 | shiftX = NewImage.createFloatImage("", imp.getWidth(), imp.getHeight(), 1, NewImage.FILL_BLACK); 29 | shiftY = NewImage.createFloatImage("", imp.getWidth(), imp.getHeight(), 1, NewImage.FILL_BLACK); 30 | 31 | # define shift some of the pixels in X 32 | shiftX.setRoi(OvalRoi(20, 98, 72, 68)); 33 | IJ.run(shiftX, "Add...", "value=25"); 34 | IJ.run(shiftX, "Select None", ""); 35 | IJ.run(shiftX, "Gaussian Blur...", "sigma=15"); 36 | 37 | # init GPU 38 | clij = CLIJ.getInstance(); 39 | 40 | # push image to GPU 41 | input = clij.push(imp); 42 | 43 | shiftXgpu = clij.push(shiftX); 44 | rotatedShiftXgpu = clij.create(shiftXgpu); 45 | shiftYgpu = clij.push(shiftY); 46 | 47 | temp = clij.create(input); 48 | 49 | # reserve memory for output 50 | output = clij.create([input.getWidth(), input.getHeight(), 36], input.getNativeType()); 51 | 52 | for i in range(0, 36): 53 | 54 | # change the shift from slice to slice 55 | at = AffineTransform2D(); 56 | at.translate(-input.getWidth() / 2, -input.getHeight() / 2); 57 | at.rotate(i * 10.0 / 180.0 * Math.PI); 58 | at.translate(input.getWidth() / 2, input.getHeight() / 2); 59 | 60 | clij.op().affineTransform2D(shiftXgpu, rotatedShiftXgpu, at); 61 | 62 | # apply transform 63 | clij.op().applyVectorfield(input, rotatedShiftXgpu, shiftYgpu, temp); 64 | 65 | # put resulting 2D image in the right plane 66 | clij.op().copySlice(temp, output, i); 67 | 68 | # show result 69 | clij.pull(output).show(); 70 | IJ.setMinAndMax(0, 255); 71 | 72 | input.close(); 73 | shiftXgpu.close(); 74 | rotatedShiftXgpu.close(); 75 | shiftYgpu.close(); 76 | temp.close(); 77 | output.close(); 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/jython/automaticThreshold.py: -------------------------------------------------------------------------------- 1 | # statistics.py 2 | # ===================== 3 | # 4 | # Derive some statistics of an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | 14 | IJ.run("Close All"); 15 | 16 | # load example image 17 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 18 | imp.show(); 19 | 20 | # init GPU 21 | clij = CLIJ.getInstance(); 22 | 23 | # push image to GPU 24 | input = clij.push(imp); 25 | 26 | # reserve memory for output, same size and type as input 27 | output = clij.create(input); 28 | 29 | # apply threshold method on GPU 30 | clij.op().automaticThreshold(input, output, "Otsu"); 31 | 32 | # show result 33 | clij.pull(output).show(); 34 | IJ.setMinAndMax(0, 1); 35 | 36 | # clean up 37 | input.close(); 38 | output.close(); 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/jython/backgroundSubtraction.py: -------------------------------------------------------------------------------- 1 | # backgroundSubtraction.py 2 | # ======================== 3 | # 4 | # Apply background subtraction to an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | 14 | IJ.run("Close All"); 15 | 16 | # load example image 17 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 18 | # IJ.run(imp, "32-bit", ""); 19 | imp.show(); 20 | 21 | # init GPU 22 | clij = CLIJ.getInstance(); 23 | 24 | # push image to GPU 25 | input = clij.push(imp); 26 | 27 | # allocated background image of same size and type as input 28 | background = clij.create(input); 29 | 30 | # reserve memory for output, same size and type 31 | output = clij.create(input); 32 | 33 | # get a background image by Gaussian blurring 34 | clij.op().blur(input, background, 10, 10, 1); 35 | 36 | # subtract background from original image 37 | clij.op().subtractImages(input, background, output); 38 | 39 | # show result 40 | clij.pull(output).show(); 41 | IJ.setMinAndMax(0, 255); 42 | 43 | # clean up 44 | input.close(); 45 | background.close(); 46 | output.close(); 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/jython/binaryProcessing.py: -------------------------------------------------------------------------------- 1 | # binaryProcessing.py 2 | # =================== 3 | # 4 | # Apply an automatic threshold method to an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | threshold = 128; 14 | 15 | IJ.run("Close All"); 16 | 17 | 18 | # load example image 19 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 20 | # imp = IJ.openImage("c:/structure/data/blobs.tif"); 21 | imp.show(); 22 | 23 | # init GPU 24 | clij = CLIJ.getInstance(); 25 | 26 | # push image to GPU 27 | input = clij.push(imp); 28 | 29 | # reserve memory for output, same size and type as input 30 | output = clij.create(input); 31 | 32 | # reserve some more memory for intermediate results 33 | temp = clij.create(input); 34 | 35 | # apply a given fixed threshold on GPU 36 | clij.op().threshold(input, output, threshold); 37 | 38 | # binary opening: erosion + dilation, twice each 39 | clij.op().erodeBox(output, temp); 40 | clij.op().erodeBox(temp, output); 41 | 42 | clij.op().dilateBox(output, temp); 43 | clij.op().dilateBox(temp, output); 44 | 45 | # show result 46 | clij.pull(output).show(); 47 | IJ.setMinAndMax(0, 1); 48 | 49 | # clean up 50 | input.close(); 51 | temp.close(); 52 | output.close(); 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/jython/blur.py: -------------------------------------------------------------------------------- 1 | # binaryProcessing.py 2 | # =================== 3 | # 4 | # Apply an automatic threshold method to an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | IJ.run("Close All"); 14 | 15 | 16 | # load example image 17 | # imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 18 | imp = IJ.openImage("c:/structure/data/blobs.tif"); 19 | imp.show(); 20 | 21 | # init GPU 22 | clij = CLIJ.getInstance(); 23 | 24 | # push image to GPU 25 | input = clij.push(imp); 26 | 27 | # reserve memory for output, same size and type as input 28 | output = clij.create(input); 29 | 30 | # apply a Gaussian blur on GPU 31 | clij.op().blur(input, output, 5, 5); 32 | 33 | # show result 34 | clij.pull(output).show(); 35 | 36 | # clean up 37 | input.close(); 38 | output.close(); 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/jython/blurg.py: -------------------------------------------------------------------------------- 1 | # binaryProcessing.py 2 | # =================== 3 | # 4 | # Apply an automatic threshold method to an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | threshold = 128; 14 | 15 | IJ.run("Close All"); 16 | 17 | 18 | # load example image 19 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 20 | # imp = IJ.openImage("c:/structure/data/blobs.tif"); 21 | imp.show(); 22 | 23 | # init GPU 24 | clij = CLIJ.getInstance(); 25 | 26 | # push image to GPU 27 | input = clij.push(imp); 28 | 29 | # reserve memory for output, same size and type as input 30 | output = clij.create(input); 31 | 32 | # reserve some more memory for intermediate results 33 | temp = clij.create(input); 34 | 35 | # apply a given fixed threshold on GPU 36 | clij.op().threshold(input, output, threshold); 37 | 38 | # binary opening: erosion + dilation, twice each 39 | clij.op().erodeBox(output, temp); 40 | clij.op().erodeBox(temp, output); 41 | 42 | clij.op().dilateBox(output, temp); 43 | clij.op().dilateBox(temp, output); 44 | 45 | # show result 46 | clij.pull(output).show(); 47 | IJ.setMinAndMax(0, 1); 48 | 49 | # clean up 50 | input.close(); 51 | temp.close(); 52 | output.close(); 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/jython/clinfo.py: -------------------------------------------------------------------------------- 1 | # clinfo.py 2 | # =================== 3 | # 4 | # Output all information about found GPUs 5 | # (or rather: all found OpenCL devices) 6 | # 7 | # Author: Robert Haase, rhaase@mpi-cbg.de 8 | # October 2019 9 | ######################################### 10 | 11 | from ij import IJ; 12 | from net.haesleinhuepf.clij import CLIJ; 13 | 14 | IJ.log(CLIJ.clinfo()); 15 | -------------------------------------------------------------------------------- /src/main/jython/crop.py: -------------------------------------------------------------------------------- 1 | # crop.py 2 | # ======= 3 | # 4 | # Crop out a part of an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | IJ.run("Close All"); 14 | 15 | # load example image 16 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 17 | # imp = IJ.openImage("c:/structure/data/blobs.tif"); 18 | imp.show(); 19 | 20 | # init GPU 21 | clij = CLIJ.getInstance(); 22 | 23 | # push image to GPU 24 | input = clij.push(imp); 25 | 26 | # reserve memory for output, with a given size and type as input 27 | output = clij.create([75, 75], input.getNativeType()); 28 | 29 | # crop 30 | clij.op().crop(input, output, 10, 10); 31 | 32 | # show result 33 | clij.pull(output).show(); 34 | 35 | # clean up 36 | input.close(); 37 | output.close(); 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/jython/differenceOfGaussian/differenceOfGaussian.cl: -------------------------------------------------------------------------------- 1 | 2 | __kernel void subtract_convolved_images_3d_fast( 3 | DTYPE_IMAGE_IN_3D src, 4 | DTYPE_IMAGE_OUT_3D dst, 5 | __private int radius, 6 | __private float sigma_minuend, 7 | __private float sigma_subtrahend 8 | ) 9 | { 10 | const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; 11 | 12 | int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0}; 13 | 14 | float sum_minuend = 0.0f; 15 | float sum_subtrahend = 0.0f; 16 | float weighted_sum_minuend = 0.0f; 17 | float weighted_sum_subtrahend = 0.0f; 18 | 19 | for(int x = -radius; x < radius + 1; x++) 20 | { 21 | for(int y = -radius; y < radius + 1; y++) 22 | { 23 | for(int z = -radius; z < radius + 1; z++) 24 | { 25 | const int4 kernelPos = {x+radius, y+radius, z+radius, 0}; 26 | const int4 imagePos = pos + (int4){ x, y, z, 0}; 27 | 28 | float image_pixel_value = READ_IMAGE_3D(src, sampler, imagePos).x; 29 | 30 | float weight_minuend = exp(-((float) (x * x + y * y + z * z) / (3.0f 31 | * sigma_minuend 32 | * sigma_minuend 33 | * sigma_minuend))); 34 | float weight_subtrahend = exp(-((float) (x * x + y * y + z * z) / (3.0f 35 | * sigma_subtrahend 36 | * sigma_subtrahend 37 | * sigma_subtrahend))); 38 | 39 | weighted_sum_minuend += weight_minuend * image_pixel_value; 40 | weighted_sum_subtrahend += weight_subtrahend * image_pixel_value; 41 | 42 | sum_minuend += weight_minuend; 43 | sum_subtrahend += weight_subtrahend; 44 | } 45 | } 46 | } 47 | 48 | float pix = weighted_sum_minuend / sum_minuend - weighted_sum_subtrahend / sum_subtrahend; //,0,0,0}; 49 | WRITE_IMAGE_3D(dst, pos, (DTYPE_OUT)pix); 50 | } 51 | 52 | 53 | __kernel void subtract_convolved_images_3d_slice_by_slice( 54 | DTYPE_IMAGE_IN_3D src, 55 | DTYPE_IMAGE_OUT_3D dst, 56 | __private int radius, 57 | __private float sigma_minuend, 58 | __private float sigma_subtrahend 59 | ) 60 | { 61 | const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; 62 | 63 | int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0}; 64 | 65 | float sum_minuend = 0.0f; 66 | float sum_subtrahend = 0.0f; 67 | float weighted_sum_minuend = 0.0f; 68 | float weighted_sum_subtrahend = 0.0f; 69 | 70 | for(int x = -radius; x < radius + 1; x++) 71 | { 72 | for(int y = -radius; y < radius + 1; y++) 73 | { 74 | int z = 0; 75 | const int4 kernelPos = {x+radius, y+radius, z+radius, 0}; 76 | const int4 imagePos = pos + (int4){ x, y, z, 0}; 77 | 78 | float image_pixel_value = READ_IMAGE_3D(src, sampler, imagePos).x; 79 | 80 | float weight_minuend = exp(-((float) (x * x + y * y + z * z) / (3.0f 81 | * sigma_minuend 82 | * sigma_minuend 83 | * sigma_minuend))); 84 | float weight_subtrahend = exp(-((float) (x * x + y * y + z * z) / (3.0f 85 | * sigma_subtrahend 86 | * sigma_subtrahend 87 | * sigma_subtrahend))); 88 | 89 | weighted_sum_minuend += weight_minuend * image_pixel_value; 90 | weighted_sum_subtrahend += weight_subtrahend * image_pixel_value; 91 | 92 | sum_minuend += weight_minuend; 93 | sum_subtrahend += weight_subtrahend; 94 | } 95 | } 96 | 97 | float pix = weighted_sum_minuend / sum_minuend - weighted_sum_subtrahend / sum_subtrahend; 98 | WRITE_IMAGE_3D(dst, pos, (DTYPE_OUT)pix); 99 | } 100 | 101 | __kernel void subtract_convolved_images_2d_fast( 102 | DTYPE_IMAGE_IN_2D src, 103 | DTYPE_IMAGE_OUT_2D dst, 104 | __private int radius, 105 | __private float sigma_minuend, 106 | __private float sigma_subtrahend 107 | ) 108 | { 109 | const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; 110 | 111 | int2 pos = {get_global_id(0), get_global_id(1)}; 112 | 113 | float sum_minuend = 0.0f; 114 | float sum_subtrahend = 0.0f; 115 | float weighted_sum_minuend = 0.0f; 116 | float weighted_sum_subtrahend = 0.0f; 117 | 118 | for(int x = -radius; x < radius + 1; x++) 119 | { 120 | for(int y = -radius; y < radius + 1; y++) 121 | { 122 | const int2 kernelPos = {x+radius, y+radius}; 123 | const int2 imagePos = pos + (int2){ x, y}; 124 | 125 | float image_pixel_value = READ_IMAGE_2D(src, sampler, imagePos).x; 126 | 127 | float weight_minuend = exp(-((float) (x * x + y * y) / (2.0f 128 | * sigma_minuend 129 | * sigma_minuend))); 130 | float weight_subtrahend = exp(-((float) (x * x + y * y) / (2.0f 131 | * sigma_subtrahend 132 | * sigma_subtrahend))); 133 | 134 | weighted_sum_minuend += weight_minuend * image_pixel_value; 135 | weighted_sum_subtrahend += weight_subtrahend * image_pixel_value; 136 | 137 | sum_minuend += weight_minuend; 138 | sum_subtrahend += weight_subtrahend; 139 | 140 | } 141 | } 142 | 143 | float pix = weighted_sum_minuend / sum_minuend - weighted_sum_subtrahend / sum_subtrahend; //,0,0,0}; 144 | WRITE_IMAGE_2D(dst, pos, (DTYPE_OUT)pix); 145 | } 146 | 147 | -------------------------------------------------------------------------------- /src/main/jython/differenceOfGaussian/differenceOfGaussian.py: -------------------------------------------------------------------------------- 1 | # this example ImageJ/Fiji jython script shows how to apply a 2 | # difference of gaussian (DoG) filter to an image using an 3 | # OpenCL kernel. 4 | # 5 | # Author: Robert Haase (@haesleinhuepf) 6 | # March 2018 7 | # 8 | 9 | from net.haesleinhuepf.clij import CLIJ; 10 | from net.imglib2.view import Views; 11 | from ij import IJ; 12 | from java.lang import Float 13 | import os; 14 | import inspect 15 | 16 | # retrieve the folder where this script is located (thanks to @mountain_man from the ImageJ forum) 17 | filesPath = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda:0))) + "/" 18 | 19 | # take the current image which is open in ImageJ 20 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 21 | 22 | # initialize ClearCL context and convenience layer 23 | clij = CLIJ.getInstance(); 24 | 25 | # convert imglib2 image to CL images (ready for the GPU) 26 | inputCLImage = clij.push(imp); 27 | tempCLImage = clij.create([inputCLImage.getWidth(), inputCLImage.getHeight()], inputCLImage.getNativeType()); 28 | outputCLImage = clij.create([inputCLImage.getWidth(), inputCLImage.getHeight()], inputCLImage.getNativeType()); 29 | 30 | # crop out a center plane of the 3D data set 31 | clij.op().copySlice(inputCLImage, tempCLImage, 64); 32 | 33 | # apply a filter to the image using ClearCL / OpenCL 34 | clij.execute(filesPath + "differenceOfGaussian.cl", "subtract_convolved_images_2d_fast", { 35 | "src":tempCLImage, 36 | "dst":outputCLImage, 37 | "radius":6, 38 | "sigma_minuend":Float(1.5), 39 | "sigma_subtrahend":Float(3)}); 40 | 41 | # convert the result back to imglib2 and show it 42 | result = clij.pull(outputCLImage); 43 | result.show(); 44 | IJ.run("Enhance Contrast", "saturated=0.35"); 45 | 46 | # clean up 47 | inputCLImage.close(); 48 | tempCLImage.close(); 49 | outputCLImage.close(); 50 | -------------------------------------------------------------------------------- /src/main/jython/maximumProjection.py: -------------------------------------------------------------------------------- 1 | # This script shows how generate a maximum Z projection using CLIJ and jython. 2 | # 3 | # Author: Robert Haase (@haesleinhuepf) 4 | # March 2018 5 | # 6 | ####################################### 7 | 8 | from ij import IJ; 9 | from ij import ImagePlus; 10 | from net.haesleinhuepf.clij import CLIJ; 11 | 12 | # Init GPU 13 | clij = CLIJ.getInstance(); 14 | 15 | # get some example data 16 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 17 | 18 | # create and fill memory in GPU 19 | imageInput = clij.push(imp); 20 | imageOutput = clij.create([imageInput.getWidth(), imageInput.getHeight()], imageInput.getNativeType()); 21 | 22 | # process the image 23 | clij.op().maximumZProjection(imageInput, imageOutput); 24 | 25 | # show the result 26 | clij.show(imageOutput, "output"); 27 | 28 | # get the result back as variable 29 | result = clij.pull(imageOutput); 30 | 31 | # clean up 32 | imageInput.close(); 33 | imageOutput.close(); 34 | 35 | -------------------------------------------------------------------------------- /src/main/jython/multi_GPU_demo.py: -------------------------------------------------------------------------------- 1 | # multi_GPU_demo.py 2 | # ================ 3 | # 4 | # This Jython script demonstrates how to process images 5 | # on multiple GPUs (or: OpenCL devices) in parallel. 6 | # 7 | # Author: Robert Haase, rhaase@mpi-cbg.de 8 | # August 2019 9 | # 10 | ######################################################## 11 | 12 | from ij import IJ; 13 | 14 | from java.lang import Thread; 15 | 16 | # The Processor class extends Thread so that we can run it 17 | # in parallel 18 | class Processor(Thread): 19 | # the CLIJ instance doing the heavy work 20 | clij = None; 21 | # the image which should be processed 22 | image = None; 23 | # a flag that says some work is ongoing 24 | working = False; 25 | # a flag that says is work was done in the past 26 | finished = False; 27 | 28 | # Constructor 29 | def __init__(self, clij): 30 | self.clij = clij; 31 | 32 | # sets the image which should be processed 33 | def setImage(self, image): 34 | self.image = image; 35 | 36 | # the actual procedure. Run processor.start() to get started in parallel. 37 | def run(self): 38 | # set status flags and initialize 39 | self.finished = False; 40 | self.working = True; 41 | # print("" + str(self.clij) + " starts working...\n"); 42 | 43 | clij = self.clij; 44 | 45 | # push the image to GPU memory 46 | input_image = clij.push(self.image); 47 | 48 | # allocate more memory on the GPU for temp and resul images 49 | temp_image = clij.create(input_image); 50 | backgroundSubtracted_image = clij.create(input_image); 51 | max_projection_image = clij.create([input_image.getWidth(), input_image.getHeight()], input_image.getNativeType()); 52 | 53 | # perform a background-subtracted maximum projection 54 | clij.op().blur(input_image, temp_image, 5, 5, 1); 55 | clij.op().subtract(input_image, temp_image, backgroundSubtracted_image); 56 | clij.op().maximumZProjection(backgroundSubtracted_image, max_projection_image); 57 | 58 | # pull result back from GPU memory and show it 59 | result = clij.pull(max_projection_image); 60 | # result.show(); 61 | # IJ.run("Enhance Contrast", "saturated=0.35"); 62 | 63 | # clean up by the end 64 | input_image.close(); 65 | temp_image.close(); 66 | backgroundSubtracted_image.close(); 67 | max_projection_image.close(); 68 | 69 | # set status flags 70 | self.working = False; 71 | self.finished = True; 72 | 73 | def isWorking(self): 74 | return self.working; 75 | 76 | def isFinished(self): 77 | return self.finished; 78 | 79 | def getCLIJ(self): 80 | return self.clij; 81 | 82 | #imp = IJ.openImage("C:/structure/data/2018-05-23-16-18-13-89-Florence_multisample/processed/tif/000116.raw.tif"); 83 | imp = IJ.openImage("https://bds.mpi-cbg.de/CLIJ_benchmarking_data/000461.raw.tif"); 84 | 85 | from net.haesleinhuepf.clij import CLIJ; 86 | 87 | # print out available OpenCL devices 88 | print("Available devices:"); 89 | for name in CLIJ.getAvailableDeviceNames(): 90 | print(name); 91 | 92 | # initialize a hand full of processors 93 | processors = [] 94 | for i in range(0, len(CLIJ.getAvailableDeviceNames())): 95 | processors.append(Processor(CLIJ(i))); 96 | 97 | from java.lang import System; 98 | startTime = System.currentTimeMillis(); 99 | 100 | # loop until a given number of images was processed 101 | processed_images = 0; 102 | while(processed_images < 10): 103 | # go trough all processors and see if one is doing nothing 104 | for j in range(0, len(processors)): 105 | processor = processors[j]; 106 | if(not processor.isWorking()): 107 | # found a sleeping processor! 108 | 109 | # was he done with something? 110 | if (processor.isFinished()): 111 | processed_images += 1; 112 | # update log 113 | IJ.log("\\Clear"); 114 | IJ.log("Processed images: " + str(processed_images)); 115 | 116 | # replace it with a new processor 117 | processor = Processor(processor.getCLIJ()); 118 | processors[j] = processor; 119 | 120 | # Starting a processor 121 | processor.setImage(imp); 122 | processor.start(); 123 | 124 | # wait a moment 125 | Thread.sleep(100); 126 | 127 | print("Processing on " + str(len(CLIJ.getAvailableDeviceNames())) + " devices took " + str(System.currentTimeMillis() - startTime) + " ms"); 128 | -------------------------------------------------------------------------------- /src/main/jython/reslicing.py: -------------------------------------------------------------------------------- 1 | # CLIJ example script: reslicing.py 2 | # --------------------------------- 3 | # 4 | # This example Jython script shows how to 5 | # reslice an image in the GPU. 6 | # 7 | # 8 | # Author: Robert Haase, rhaase@mpi-cbg.de 9 | # October 2019 10 | ########################################## 11 | 12 | from net.haesleinhuepf.clij import CLIJ; 13 | from ij import IJ; 14 | 15 | IJ.run("Close All"); 16 | 17 | # init CLIJ and GPU 18 | clij = CLIJ.getInstance(); 19 | 20 | # get an example data set 21 | imp = IJ.openImage("http://imagej.nih.gov/ij/images/t1-head.zip"); 22 | imp.show(); 23 | imp.setRoi(86,3,100,250); 24 | imp = imp.crop("25-74"); 25 | imp.show(); 26 | 27 | # push it to the GPU 28 | src = clij.push(imp); 29 | # generate the output-image on the GPU with thee right size 30 | dst = clij.create([src.getWidth(), src.getDepth(), src.getHeight()], src.getNativeType()); 31 | 32 | # Reslice on GPU 33 | clij.op().resliceTop(src, dst); 34 | 35 | # show result 36 | dstImagePlus = clij.pull(dst); 37 | dstImagePlus.show(); 38 | dstImagePlus.setZ(dstImagePlus.getNSlices() / 2); 39 | IJ.run(dstImagePlus, "Enhance Contrast", "saturated=0.35"); 40 | 41 | # cleanup memory on GPU 42 | src.close(); 43 | dst.close(); -------------------------------------------------------------------------------- /src/main/jython/rgbReplaceBlackAndWhite.cl: -------------------------------------------------------------------------------- 1 | 2 | __kernel void rgbReplaceBlackAndWhite( 3 | DTYPE_IMAGE_IN_3D src, 4 | DTYPE_IMAGE_OUT_3D dst 5 | ) 6 | { 7 | const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; 8 | 9 | // set positions from where to read 10 | int4 posR = {get_global_id(0), get_global_id(1), 0, 0}; 11 | int4 posG = {get_global_id(0), get_global_id(1), 1, 0}; 12 | int4 posB = {get_global_id(0), get_global_id(1), 2, 0}; 13 | 14 | // read original pixel values 15 | float r = READ_IMAGE_3D(src, sampler, posR).x; 16 | float g = READ_IMAGE_3D(src, sampler, posG).x; 17 | float b = READ_IMAGE_3D(src, sampler, posB).x; 18 | 19 | // do the math suggested by Jan Eglinger https://forum.image.sc/t/invert-rgb-image-without-changing-colors/33571 20 | float ir = 255 - (g + b) / 2; 21 | float ig = 255 - (r + b) / 2; 22 | float ib = 255 - (r + g) / 2; 23 | 24 | // write the pixels back to the destination image 25 | WRITE_IMAGE_3D(dst, posR, CONVERT_DTYPE_OUT(ir)); 26 | WRITE_IMAGE_3D(dst, posG, CONVERT_DTYPE_OUT(ig)); 27 | WRITE_IMAGE_3D(dst, posB, CONVERT_DTYPE_OUT(ib)); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/jython/rgbReplaceBlackAndWhite.py: -------------------------------------------------------------------------------- 1 | # this example ImageJ/Fiji jython script shows how to apply a 2 | # custom OpenCL kernel to an image which replaces black by 3 | # white in an image 4 | # 5 | # Author: Robert Haase (@haesleinhuepf) 6 | # February 2020 7 | 8 | 9 | from net.haesleinhuepf.clij import CLIJ; 10 | from ij import IJ; 11 | from java.lang import System; 12 | import os; 13 | import inspect 14 | 15 | # retrieve the folder where this script is located (thanks to @mountain_man from the ImageJ forum) 16 | filesPath = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda:0))) + "/" 17 | 18 | # open an example image 19 | imp = IJ.openImage("https://clij.github.io/clij-benchmarking/plotting_jmh/images/imagesize/clij_ij_comparison_BinaryAnd2D.png"); 20 | IJ.run(imp, "RGB Stack", ""); 21 | imp.show(); 22 | IJ.run(imp, "Make Composite", "display=Composite"); 23 | 24 | # initialize ClearCL context and convenience layer 25 | time = System.currentTimeMillis(); 26 | clij = CLIJ.getInstance(); 27 | 28 | # convert ImagePlus image to CL images (ready for the GPU) 29 | input = clij.push(imp); 30 | output = clij.create(input); 31 | 32 | # apply a filter to the image using ClearCL / OpenCL 33 | parameters = { 34 | "src":input, 35 | "dst":output 36 | }; 37 | clij.execute(filesPath + "rgbReplaceBlackAndWhite.cl", "rgbReplaceBlackAndWhite", parameters); 38 | 39 | # convert the result back to ImagePlus and show it 40 | result = clij.pull(output) 41 | result.show(); 42 | IJ.log("The custom kernel execution took " + str(System.currentTimeMillis() - time) + " ms"); 43 | 44 | IJ.run(result, "Make Composite", "display=Composite"); 45 | 46 | # clean up 47 | input.close(); 48 | output.close(); 49 | -------------------------------------------------------------------------------- /src/main/jython/rotateFree.py: -------------------------------------------------------------------------------- 1 | # rotateFree.py 2 | # ============= 3 | # 4 | # Rotate an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | from net.imglib2.realtransform import AffineTransform2D; 14 | from java.lang import Math; 15 | 16 | 17 | IJ.run("Close All"); 18 | 19 | # load example image 20 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 21 | # imp = IJ.openImage("c:/structure/data/blobs.tif"); 22 | imp.show(); 23 | 24 | # init GPU 25 | clij = CLIJ.getInstance(); 26 | 27 | # push image to GPU 28 | input = clij.push(imp); 29 | 30 | # reserve memory for output, same size and type as input 31 | temp = clij.create(input); 32 | 33 | # reserve memory for the resulting video of the rotating input 34 | result = clij.create([input.getWidth(), input.getHeight(), 36], input.getNativeType()); 35 | 36 | for i in range(0, 36): 37 | at = AffineTransform2D(); 38 | at.translate(-input.getWidth() / 2, -input.getHeight() / 2); 39 | at.rotate(i * 10.0 / 180.0 * Math.PI); 40 | at.translate(input.getWidth() / 2, input.getHeight() / 2); 41 | 42 | # Execute operation on GPU 43 | clij.op().affineTransform2D(input, temp, at); 44 | 45 | clij.op().copySlice(temp, result, i); 46 | 47 | # show result 48 | clij.pull(result).show(); 49 | IJ.setMinAndMax(0, 255); 50 | 51 | # clean up 52 | input.close(); 53 | temp.close(); 54 | result.close(); 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/jython/rotateOverwriteOiginal.py: -------------------------------------------------------------------------------- 1 | # rotateOverwriteOriginal.py 2 | # ========================== 3 | # 4 | # Rotate an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | from net.haesleinhuepf.clij.clearcl import ClearCLImage 13 | 14 | from net.imglib2.realtransform import AffineTransform2D; 15 | from java.lang import Math; 16 | from ij import ImagePlus; 17 | 18 | 19 | IJ.run("Close All"); 20 | 21 | # load example image 22 | # imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 23 | imp = IJ.openImage("c:/structure/data/blobs.tif"); 24 | IJ.run(imp, "32-bit", ""); 25 | imp.show(); 26 | 27 | # init GPU 28 | clij = CLIJ.getInstance(); 29 | 30 | # push image to GPU; we're using images instead of buffers 31 | # because they suppport interpolation 32 | input = clij.convert(imp, ClearCLImage); 33 | 34 | # reserve memory for output, same size and type as input 35 | temp = clij.create(input); 36 | #[input.getWidth(), input.getHeight()], input.getNativeType()); 37 | 38 | # reserve memory for the resulting video of the rotating input 39 | result = clij.create([input.getWidth(), input.getHeight(), 360], input.getChannelDataType()); 40 | 41 | for i in range(0, 360): 42 | at = AffineTransform2D(); 43 | at.translate(-input.getWidth() / 2, -input.getHeight() / 2); 44 | at.rotate(i / 180.0 * Math.PI); 45 | at.translate(input.getWidth() / 2, input.getHeight() / 2); 46 | 47 | # Execute operation on GPU 48 | clij.op().affineTransform2D(input, temp, at); 49 | 50 | # never overwrite the original with the rotated image! 51 | # this is just an academic example to show what can go wrong 52 | clij.op().copy(temp, input); 53 | 54 | # copy the resulting rotated image in the right plane in the 55 | # final video stack 56 | clij.op().copySlice(temp, result, i); 57 | 58 | # show result 59 | clij.convert(result, ImagePlus).show(); 60 | IJ.setMinAndMax(0, 255); 61 | 62 | # clean up 63 | input.close(); 64 | temp.close(); 65 | result.close(); 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/jython/statistics.py: -------------------------------------------------------------------------------- 1 | # statistics.py 2 | # ============= 3 | # 4 | # Derive pixel statistics of an image on the GPU 5 | # 6 | # Author: Robert Haase, rhaase@mpi-cbg.de 7 | # October 2019 8 | ######################################### 9 | 10 | from ij import IJ; 11 | from net.haesleinhuepf.clij import CLIJ; 12 | 13 | 14 | IJ.run("Close All"); 15 | 16 | # load example image 17 | imp = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); 18 | # imp = IJ.openImage("c:/structure/data/blobs.tif"); 19 | imp.show(); 20 | 21 | # init GPU 22 | clij = CLIJ.getInstance(); 23 | 24 | # push image to GPU 25 | input = clij.push(imp); 26 | 27 | meanIntensity = clij.op().sumPixels(input) / input.getWidth() / input.getHeight(); 28 | IJ.log("Mean intensity of all pixels: " + str(meanIntensity)); 29 | 30 | 31 | # reserve memory for a mask and masked image, same size and type as input 32 | mask = clij.create(input); 33 | masked = clij.create(input); 34 | 35 | # apply threshold method on GPU 36 | clij.op().automaticThreshold(input, mask, "Otsu"); 37 | 38 | # mask the image 39 | clij.op().mask(input, mask, masked); 40 | 41 | # determine mean intensity of masked area: 42 | meanIntensity = clij.op().sumPixels(masked) / input.getWidth() / input.getHeight(); 43 | IJ.log("Mean intensity of masked pixels: " + str(meanIntensity)); 44 | 45 | # clean up 46 | input.close(); 47 | mask.close(); 48 | masked.close(); 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/macro/addImages.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: addImages.ijm 2 | // 3 | // This macro shows how add images of different bit-type 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | // Get test data 12 | run("Blobs (25K)"); 13 | run("8-bit"); 14 | rename("original"); 15 | getDimensions(width, height, channels, slices, frames) 16 | 17 | newImage("background", "16-bit ramp", width, height, slices); 18 | 19 | // init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push images to GPU 24 | Ext.CLIJ_push("original"); 25 | Ext.CLIJ_push("background"); 26 | 27 | 28 | // cleanup imagej 29 | run("Close All"); 30 | 31 | // create output image with 32 bits 32 | Ext.CLIJ_create2D("originalWithBackground", width, height, 32); 33 | 34 | // add images 35 | Ext.CLIJ_addImagesWeighted("original", "background", "originalWithBackground", 1, 0.01); 36 | 37 | // show result 38 | Ext.CLIJ_pull("originalWithBackground"); 39 | run("Invert LUT"); 40 | -------------------------------------------------------------------------------- /src/main/macro/affineTransform.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: affineTransform.ijm 2 | // 3 | // This macro shows how to apply an affine transform in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | // Get test data 12 | run("Blobs (25K)"); 13 | //open("C:/structure/data/blobs.gif"); 14 | 15 | 16 | run("32-bit"); // interplation works better with float images 17 | rename("original"); 18 | 19 | // init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push images to GPU 24 | Ext.CLIJ_push("original"); 25 | 26 | // cleanup imagej 27 | run("Close All"); 28 | 29 | transform = "center "; 30 | transform = transform + " rotate=45"; // degrees 31 | transform = transform + " scaleX=2"; // relative zoom factor 32 | transform = transform + " translateY=25"; // pixels 33 | transform = transform + " -center"; 34 | 35 | Ext.CLIJ_affineTransform2D("original", "target", transform); 36 | 37 | // show result 38 | Ext.CLIJ_pull("target"); 39 | run("Invert LUT"); 40 | -------------------------------------------------------------------------------- /src/main/macro/allocateBigImages.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: allocateBigImages.ijm 2 | // 3 | // This macro shows how to process/handle big images in the GPU. 4 | // Basically: They have to pushed in smaller blocks. 5 | // 6 | // Author: Robert Haase 7 | // December 2018 8 | // --------------------------------------------- 9 | 10 | run ("Close All"); 11 | 12 | 13 | // Get test data 14 | //open("C:/structure/data/blobs.gif"); 15 | run("Blobs (25K)"); 16 | 17 | // define image names 18 | input = "input"; 19 | bigStack = "bigStack"; 20 | crop = "crop"; 21 | 22 | // Init GPU 23 | run("CLIJ Macro Extensions", "cl_device="); 24 | Ext.CLIJ_clear(); 25 | 26 | // push images to GPU 27 | rename(input); 28 | Ext.CLIJ_push(input); 29 | 30 | // CleanUp ImageJ 31 | close(); 32 | 33 | // create an 8 GB image in GPU memory 34 | Ext.CLIJ_create3D(bigStack, 2048, 2048, 1000, 16); 35 | 36 | 37 | for (i = 0; i < 10; i++) { 38 | // fill the image with content 39 | Ext.CLIJ_copySlice(input, bigStack, i); 40 | } 41 | Ext.CLIJ_crop3D(bigStack, crop, 0, 0, 0, 150, 150, 10); 42 | 43 | // Get results back from GPU 44 | Ext.CLIJ_pull(crop); 45 | 46 | // report about what's allocated in the GPU memory 47 | Ext.CLIJ_reportMemory(); 48 | 49 | // Cleanup by the end 50 | Ext.CLIJ_clear(); 51 | -------------------------------------------------------------------------------- /src/main/macro/applyVectorField.ijm: -------------------------------------------------------------------------------- 1 | // This script demonstrates how to apply a vector field 2 | // to an image in order to transform it non-rigidly 3 | // 4 | // Author: Robert Haase, rhaase@mpi-cbg.de 5 | // March 2019 6 | // 7 | 8 | run("Close All"); 9 | 10 | // get test image 11 | run("Blobs (25K)"); 12 | run("32-bit"); 13 | rename("blobs"); 14 | 15 | // create two images describing local shift 16 | newImage("shiftX", "32-bit black", 256, 254, 1); 17 | newImage("shiftY", "32-bit black", 256, 254, 1); 18 | 19 | // reserve memory for the result video 20 | newImage("resultStack", "32-bit black", 256, 254, 36); 21 | 22 | 23 | // shift some of the pixels in X 24 | selectImage("shiftX"); 25 | makeOval(20, 98, 72, 68); 26 | run("Add...", "value=25"); 27 | run("Select None"); 28 | run("Gaussian Blur...", "sigma=15"); 29 | run("Enhance Contrast", "saturated=0.35"); 30 | 31 | // init GPU 32 | run("CLIJ Macro Extensions", "cl_device="); 33 | Ext.CLIJ_push("blobs"); 34 | Ext.CLIJ_push("shiftX"); 35 | Ext.CLIJ_push("shiftY"); 36 | Ext.CLIJ_push("resultStack"); 37 | 38 | for (i = 0; i < 36; i++) { 39 | 40 | // change the shift from slice to slice 41 | Ext.CLIJ_affineTransform2D("shiftX", "rotatedShiftX", "center rotate=" + (i * 10) + " -center"); 42 | 43 | // apply transform 44 | Ext.CLIJ_applyVectorField2D("blobs", "rotatedShiftX", "shiftY", "transformed"); 45 | 46 | // put resulting 2D image in the right plane 47 | Ext.CLIJ_copySlice("transformed", "resultStack", i); 48 | } 49 | 50 | 51 | // get result back from GPU 52 | Ext.CLIJ_pull("resultStack"); 53 | run("Invert LUT"); 54 | -------------------------------------------------------------------------------- /src/main/macro/autoThreshold.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: autoThreshold.ijm 2 | // 3 | // This macro shows how to apply an automatic 4 | // threshold method to an image in the GPU. 5 | // 6 | // Author: Robert Haase 7 | // December 2018 8 | // --------------------------------------------- 9 | 10 | 11 | // Get test data 12 | run("Blobs (25K)"); 13 | //open("C:/structure/data/blobs.gif"); 14 | getDimensions(width, height, channels, slices, frames); 15 | input = getTitle(); 16 | 17 | mask = "Mask"; 18 | 19 | // Init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push data to GPU 24 | Ext.CLIJ_push(input); 25 | 26 | // cleanup ImageJ 27 | run("Close All"); 28 | 29 | // create a mask using a fixed threshold 30 | Ext.CLIJ_automaticThreshold(input, mask, "Otsu"); 31 | 32 | // show result 33 | Ext.CLIJ_pullBinary(mask); 34 | -------------------------------------------------------------------------------- /src/main/macro/backgroundSubtraction.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: backgroundSubtraction.ijm 2 | // 3 | // This macro shows how background subtraction can be done in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | run ("Close All"); 10 | 11 | // Get test data 12 | //open("C:/structure/data/t1-head.tif"); 13 | run("T1 Head (2.4M, 16-bits)"); 14 | input = getTitle(); 15 | background = "background"; 16 | background_subtracted = "background_subtracted"; 17 | 18 | // Init GPU 19 | run("CLIJ Macro Extensions", "cl_device="); 20 | Ext.CLIJ_clear(); 21 | 22 | // push images to GPU 23 | Ext.CLIJ_push(input); 24 | 25 | // CleanUp ImageJ 26 | close(); 27 | 28 | // Blur in GPU 29 | Ext.CLIJ_blur3D(input, background, 10, 10, 1); 30 | 31 | // subtraction from original 32 | Ext.CLIJ_addImagesWeighted(input, background, background_subtracted, 1, -1); 33 | 34 | // Get results back from GPU 35 | Ext.CLIJ_pull(background_subtracted); 36 | Ext.CLIJ_pull(input); 37 | 38 | 39 | // Cleanup by the end 40 | Ext.CLIJ_clear(); 41 | -------------------------------------------------------------------------------- /src/main/macro/benchmarking.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: benchmarking.ijm 2 | // 3 | // This macro shows how to measure performance of GPU and CPU based ImageJ macro code. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | // Get test data 10 | run("T1 Head (2.4M, 16-bits)"); 11 | input = getTitle(); 12 | getDimensions(width, height, channels, slices, frames); 13 | 14 | blurred = "Blurred"; 15 | 16 | // Init GPU 17 | run("CLIJ Macro Extensions", "cl_device="); 18 | Ext.CLIJ_clear(); 19 | 20 | // Local mean filter in CPU 21 | for (i = 1; i <= 10; i++) { 22 | time = getTime(); 23 | run("Mean 3D...", "x=3 y=3 z=3"); 24 | print("CPU mean filter no " + i + " took " + (getTime() - time) + " msec"); 25 | } 26 | 27 | // push images to GPU 28 | time = getTime(); 29 | Ext.CLIJ_push(input); 30 | print("Pushing one image to the GPU took " + (getTime() - time) + " msec"); 31 | 32 | // cleanup ImageJ 33 | run("Close All"); 34 | 35 | // Local mean filter in GPU 36 | for (i = 1; i <= 10; i++) { 37 | time = getTime(); 38 | Ext.CLIJ_mean3DBox(input, blurred, 3, 3, 3); 39 | print("GPU mean filter no " + i + " took " + (getTime() - time) + " msec"); 40 | } 41 | 42 | // Get results back from GPU 43 | time = getTime(); 44 | Ext.CLIJ_pull(blurred); 45 | 46 | print("Pulling one image from the GPU took " + (getTime() - time) + " msec"); 47 | 48 | // Cleanup GPU 49 | Ext.CLIJ_clear(); 50 | -------------------------------------------------------------------------------- /src/main/macro/bigImageTransfer.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: bigImageTransfer.ijm 2 | // 3 | // This macro shows how to process big images on the GPU 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | // Get test dat - a 4 GB image of type 8-bit 12 | width = 1024; 13 | height = 1024; 14 | slices = 4095; 15 | newImage("original", "8-bit ramp", width, height, slices); 16 | 17 | // init GPU 18 | run("CLIJ Macro Extensions", "cl_device="); 19 | Ext.CLIJ_clear(); 20 | 21 | // push images to GPU 22 | Ext.CLIJ_push("original"); 23 | 24 | // cleanup imagej 25 | run("Close All"); 26 | 27 | // add images 28 | Ext.CLIJ_maximumZProjection("original", "max"); 29 | 30 | // show result 31 | Ext.CLIJ_pull("max"); 32 | 33 | Ext.CLIJ_reportMemory(); 34 | Ext.CLIJ_clear(); -------------------------------------------------------------------------------- /src/main/macro/binaryProcessing.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: binaryProcessing.ijm 2 | // 3 | // This macro shows how to deal with binary images, e.g. thresholding, dilation, erosion, in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | 12 | // Get test data 13 | run("Blobs (25K)"); 14 | //open("C:/structure/data/blobs.gif"); 15 | getDimensions(width, height, channels, slices, frames); 16 | input = getTitle(); 17 | threshold = 128; 18 | 19 | mask = "mask"; 20 | 21 | temp = "temp"; 22 | 23 | 24 | // Init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push data to GPU 29 | Ext.CLIJ_push(input); 30 | 31 | // cleanup ImageJ 32 | run("Close All"); 33 | 34 | // create a mask using a fixed threshold 35 | Ext.CLIJ_threshold(input, mask, threshold); 36 | 37 | // binary opening: erosion + dilation, twice each 38 | Ext.CLIJ_erodeBox(mask, temp); 39 | Ext.CLIJ_erodeBox(temp, mask); 40 | 41 | Ext.CLIJ_dilateBox(mask, temp); 42 | Ext.CLIJ_dilateBox(temp, mask); 43 | 44 | 45 | // show result 46 | Ext.CLIJ_pullBinary(mask); 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/macro/bitdepthConversion.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: bitdepthConversion.ijm 2 | // 3 | // This macro shows how change the bit-depth of 4 | // images in the GPU. 5 | // 6 | // Author: Robert Haase 7 | // March 2019 8 | // --------------------------------------------- 9 | 10 | 11 | 12 | // create an image with 32-bit 13 | newImage("image32", "32-bit ramp", 20, 20, 1); 14 | 15 | // init GPU 16 | run("CLIJ Macro Extensions", "cl_device="); 17 | Ext.CLIJ_clear(); 18 | 19 | // send image to GPU 20 | Ext.CLIJ_push("image32"); 21 | 22 | // scale the image pixel intensities with a given factor 23 | intensityScalingFactor = 255; 24 | Ext.CLIJ_multiplyImageAndScalar("image32", "temp", intensityScalingFactor); 25 | 26 | // convert it to 8 bit 27 | Ext.CLIJ_convertUInt16("temp", "image16"); 28 | 29 | // get converted image back from GPU 30 | Ext.CLIJ_pull("image16"); 31 | 32 | -------------------------------------------------------------------------------- /src/main/macro/blur.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: blur.ijm 2 | // 3 | // This macro shows how to blur an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | input = getTitle(); 13 | getDimensions(width, height, channels, slices, frames); 14 | 15 | blurred = "Blurred"; 16 | 17 | // Init GPU 18 | run("CLIJ Macro Extensions", "cl_device="); 19 | Ext.CLIJ_clear(); 20 | 21 | // push images to GPU 22 | Ext.CLIJ_push(input); 23 | 24 | // cleanup ImageJ 25 | run("Close All"); 26 | 27 | // Blur in GPU 28 | Ext.CLIJ_blur3D(input, blurred, 5, 5, 1); 29 | 30 | // Get results back from GPU 31 | Ext.CLIJ_pull(blurred); 32 | 33 | // Cleanup by the end 34 | Ext.CLIJ_clear(); 35 | -------------------------------------------------------------------------------- /src/main/macro/blur_batch.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: blur_batch.ijm 2 | // 3 | // This macro shows how to blur a folder of 4 | // images in the GPU. 5 | // 6 | // Author: Robert Haase 7 | // November 2019 8 | // --------------------------------------------- 9 | run("Close All"); 10 | 11 | // set image names 12 | input = "input"; 13 | blurred = "Blurred"; 14 | 15 | // Init GPU 16 | run("CLIJ Macro Extensions", "cl_device="); 17 | Ext.CLIJ_clear(); 18 | 19 | // set folders 20 | path_to_results = "C:/structure/temp/"; 21 | // path_to_images = "/path/to/images/"; 22 | // files = getFileList(path_to_images) 23 | 24 | // demo with online folder 25 | path_to_images = "https://samples.fiji.sc/"; 26 | files = newArray("blobs.png", "blobs.png", "blobs.png"); 27 | 28 | 29 | // go through the folder 30 | for (i = 0; i < lengthOf(files); i++) { 31 | open(path_to_images + files[i]); 32 | rename(input); 33 | 34 | // push images to GPU 35 | Ext.CLIJ_push(input); 36 | 37 | // cleanup ImageJ 38 | run("Close All"); 39 | 40 | // Blur in GPU 41 | Ext.CLIJ_blur3D(input, blurred, 5, 5, 1); 42 | 43 | // Get results back from GPU 44 | Ext.CLIJ_pull(blurred); 45 | 46 | // save result 47 | saveAs("tif", path_to_results + files[i]); 48 | 49 | // if your input images have different sizes, you should call clear now, 50 | // otherwise they may be cropped because memory of former images is reused. 51 | // Ext.CLIJ_clear(); 52 | close(); 53 | } 54 | 55 | // Cleanup by the end 56 | Ext.CLIJ_clear(); 57 | -------------------------------------------------------------------------------- /src/main/macro/clInfo.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: clInfo.ijm 2 | // 3 | // Outputs information about OpenCL devices 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | 10 | run("CLIJ Macro Extensions", "cl_device="); 11 | Ext.CLIJ_clInfo(); -------------------------------------------------------------------------------- /src/main/macro/convert.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: convert,ijm 2 | // 3 | // This macro shows how to convert an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | cl_device = ""; 12 | 13 | run("Blobs (25K)"); 14 | source = getTitle(); 15 | 16 | run("CLIJ Macro Extensions", "cl_device=" + cl_device); 17 | Ext.CLIJ_clear(); 18 | 19 | Ext.CLIJ_push(source); 20 | 21 | Ext.CLIJ_convertFloat(source, "float"); 22 | Ext.CLIJ_pull("float"); 23 | 24 | Ext.CLIJ_convertUInt8("float", "uint8"); 25 | Ext.CLIJ_pull("uint8"); 26 | 27 | Ext.CLIJ_convertUInt16(source, "uint16"); 28 | Ext.CLIJ_pull("uint16"); 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/macro/create_object_outlines.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: create_object_outlines.ijm 2 | // 3 | // This macro shows how to deal with binary images, e.g. thresholding, dilation, erosion, in the GPU. 4 | // 5 | // This macro was generate using the ImageJ macro recorder. 6 | // 7 | // Author: Robert Haase 8 | // December 2018 9 | // --------------------------------------------- 10 | 11 | run("Blobs (25K)"); 12 | 13 | //run("Close All"); 14 | //open("C:/structure/data/blobs.gif"); 15 | run("CLIJ Macro Extensions", "cl_device="); 16 | 17 | Ext.CLIJ_push("blobs.gif"); 18 | Ext.CLIJ_mean2DBox("blobs.gif", "CLIJ_mean2DBox_destination_blobs.gif", 2.0, 2.0); 19 | Ext.CLIJ_threshold("CLIJ_mean2DBox_destination_blobs.gif", "CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif", 127.0); 20 | Ext.CLIJ_erodeBox("CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif", "CLIJ_erodeBox_destination_CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif"); 21 | Ext.CLIJ_binaryXOr("CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif", "CLIJ_erodeBox_destination_CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif", "CLIJ_binaryXOr_destination_CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif"); 22 | Ext.CLIJ_pull("CLIJ_binaryXOr_destination_CLIJ_threshold_destination_CLIJ_mean2DBox_destination_blobs.gif"); 23 | -------------------------------------------------------------------------------- /src/main/macro/crop.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: crop.ijm 2 | // 3 | // This macro shows how crop an image in the GPU 4 | // 5 | // Author: Robert Haase 6 | // September 2019 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | // Get test data 12 | run("Blobs (25K)"); 13 | rename("original"); 14 | 15 | // init GPU 16 | run("CLIJ Macro Extensions", "cl_device="); 17 | Ext.CLIJ_clear(); 18 | 19 | // push images to GPU 20 | Ext.CLIJ_push("original"); 21 | 22 | // crop image 23 | Ext.CLIJ_crop2D("original", "cropped", 10, 10, 75, 75); 24 | 25 | // show result 26 | Ext.CLIJ_pull("cropped"); 27 | run("Invert LUT"); 28 | -------------------------------------------------------------------------------- /src/main/macro/flip.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rotate.ijm 2 | // 3 | // This macro shows how stacks can be rotated in the GPU 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | //open("C:/structure/data/t1-head.tif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle(); 15 | 16 | flipped = "Flipped along X"; 17 | 18 | // Init GPU 19 | run("CLIJ Macro Extensions", "cl_device="); 20 | Ext.CLIJ_clear(); 21 | 22 | // push data to GPU 23 | Ext.CLIJ_push(input); 24 | 25 | // cleanup ImageJ 26 | run("Close All"); 27 | 28 | // flip along x axis 29 | Ext.CLIJ_flip3D(input, flipped, true, false, false); 30 | 31 | // show results 32 | Ext.CLIJ_pull(flipped); 33 | -------------------------------------------------------------------------------- /src/main/macro/help.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: help.ijm 2 | // 3 | // This macro shows how to get help on CLIJ methods 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | 10 | run("CLIJ Macro Extensions", "cl_device="); 11 | Ext.CLIJ_help(""); -------------------------------------------------------------------------------- /src/main/macro/localMaximum.ijm: -------------------------------------------------------------------------------- 1 | // localMaximum.ijm 2 | // 3 | // Demonstrates differences between local "maximum" filters in IJ and CLIJ. 4 | // 5 | // Author: haesleinhuepf 6 | // Jan 2019 7 | 8 | run("Close All"); 9 | 10 | for (radius = 1; radius < 4; radius++) { 11 | 12 | newImage("original", "8-bit black", 9, 9, 9); 13 | Stack.setSlice(5); 14 | makeRectangle(4, 4, 1, 1); 15 | run("Add...", "value=255 slice"); 16 | run("Select None"); 17 | 18 | selectWindow("original"); 19 | run("Duplicate...", "title=orignal1slice"); 20 | 21 | 22 | run("CLIJ Macro Extensions", "cl_device="); 23 | Ext.CLIJ_clear(); 24 | 25 | Ext.CLIJ_push("original"); 26 | Ext.CLIJ_push("orignal1slice"); 27 | 28 | 29 | 30 | Ext.CLIJ_maximum3DSphere("original", "maximum3DSphereCLIJ_" + radius, radius, radius, radius); 31 | Ext.CLIJ_pull("maximum3DSphereCLIJ_" + radius); 32 | zoom("maximum3DSphereCLIJ_" + radius); 33 | 34 | Ext.CLIJ_maximum2DSphere("orignal1slice", "maximum2DSphereCLIJ_" + radius, radius, radius); 35 | Ext.CLIJ_pull("maximum2DSphereCLIJ_" + radius); 36 | zoom("maximum2DSphereCLIJ_" + radius); 37 | 38 | selectWindow("original"); 39 | run("Duplicate...", "title=maximum3DIJ_" + radius + " duplicate"); 40 | run("Maximum 3D...", "x=" + radius + " y=" + radius + " z=" + radius); 41 | zoom("maximum3DIJ_" + radius); 42 | 43 | selectWindow("orignal1slice"); 44 | run("Duplicate...", "title=maximum2DIJ_" + radius); 45 | run("Maximum...", "radius=" + radius); 46 | zoom("maximum2DIJ_" + radius); 47 | } 48 | 49 | function zoom(title) { 50 | selectWindow(title); 51 | for (i = 0; i < 10; i++) { 52 | run("In [+]"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/macro/maximumProjection.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: backgroundSubtraction.ijm 2 | // 3 | // This macro shows how maximum projection can be done in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | run ("Close All"); 10 | 11 | // Get test data 12 | //open("C:/structure/data/t1-head.tif"); 13 | run("T1 Head (2.4M, 16-bits)"); 14 | input = getTitle(); 15 | background = "background"; 16 | background_subtracted = "background_subtracted"; 17 | maximum_projected = "maximum_projected"; 18 | 19 | // Init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push images to GPU 24 | Ext.CLIJ_push(input); 25 | 26 | // CleanUp ImageJ 27 | close(); 28 | 29 | // maximum projection 30 | Ext.CLIJ_maximumZProjection(input, maximum_projected); 31 | 32 | // Get results back from GPU 33 | Ext.CLIJ_pull(maximum_projected); 34 | 35 | // Cleanup by the end 36 | Ext.CLIJ_clear(); 37 | -------------------------------------------------------------------------------- /src/main/macro/mean.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: mean.ijm 2 | // 3 | // This macro shows how the mean average filter works in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | run("Close All"); 10 | 11 | // Get test data 12 | run("T1 Head (2.4M, 16-bits)"); 13 | rename("Mean CPU") 14 | input = getTitle(); 15 | getDimensions(width, height, channels, slices, frames); 16 | 17 | blurred = "Mean GPU"; 18 | 19 | // Init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push images to GPU 24 | Ext.CLIJ_push(input); 25 | 26 | // Local mean filter in CPU 27 | selectWindow(input); 28 | run("Mean 3D...", "x=3 y=3 z=3"); 29 | 30 | 31 | // Local mean filter in GPU 32 | Ext.CLIJ_mean3DSphere(input, blurred, 3, 3, 3); 33 | 34 | // Get results back from GPU 35 | Ext.CLIJ_pull(blurred); 36 | 37 | // Cleanup GPU 38 | Ext.CLIJ_clear(); 39 | 40 | 41 | imageCalculator("Subtract create 32-bit stack", "Mean CPU","Mean GPU"); 42 | selectWindow("Result of Mean CPU"); 43 | rename("Difference between CPU and GPU"); 44 | setSlice(60); 45 | run("Enhance Contrast", "saturated=0.35"); 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/macro/mean2d.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: mean.ijm 2 | // 3 | // This macro shows how the mean average filter works in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | run("Duplicate...", " "); 13 | rename("Mean CPU") 14 | input = getTitle(); 15 | getDimensions(width, height, channels, slices, frames); 16 | 17 | blurred = "Mean GPU"; 18 | 19 | // Init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // push images to GPU 24 | Ext.CLIJ_push(input); 25 | 26 | // Local mean filter in CPU 27 | selectWindow(input); 28 | run("Mean...", "radius=3"); 29 | 30 | // Local mean filter in GPU 31 | Ext.CLIJ_mean2DBox(input, blurred, 3, 3); 32 | 33 | // Get results back from GPU 34 | Ext.CLIJ_pull(blurred); 35 | 36 | // Cleanup GPU 37 | Ext.CLIJ_clear(); 38 | 39 | 40 | imageCalculator("Subtract create 32-bit stack", "Mean CPU","Mean GPU"); 41 | selectWindow("Result of Mean CPU"); 42 | rename("Difference between CPU and GPU"); 43 | //setSlice(60); 44 | run("Enhance Contrast", "saturated=0.35"); 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/macro/mean_detailed_comparison_IJ_CLIJ.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: mean_detailed_comparison_IJ_CLIJ.ijm 2 | // 3 | // This macro shows differences between ImageJ and CLIJ when executing a mean filter. 4 | // Starting from an image (2D or 3D) where a single pixel is set to 255, mean filters are applied. 5 | // While we observe differences between 2D and 3D in ImageJ. CLIJ is more consistent. 6 | // 7 | // Author: Robert Haase 8 | // June 2019 9 | // --------------------------------------------- 10 | 11 | run("Close All"); 12 | 13 | radius = 1; 14 | 15 | 16 | // ----------------------------------------------------------------- 17 | 18 | // create 2D example image 19 | input = "example2d"; 20 | newImage(input, "8-bit black", 10, 10, 1); 21 | makeRectangle(4, 5, 1, 1); 22 | run("Add...", "value=255"); 23 | run("Select None"); 24 | 25 | // visualise input image 26 | zoom(10); 27 | setWindowPosition(0, 0); 28 | setMinAndMax(0, 1); 29 | makeOverlay(); 30 | 31 | // init GPU 32 | run("CLIJ Macro Extensions", "cl_device="); 33 | 34 | // do operation on GPU 35 | outputGPU = "mean2d_GPU"; 36 | Ext.CLIJ_push(input); 37 | Ext.CLIJ_mean2DSphere(input, outputGPU, radius, radius); 38 | Ext.CLIJ_pull(outputGPU); 39 | 40 | // visualise result 41 | zoom(10); 42 | setWindowPosition(1, 0); 43 | setMinAndMax(0, 1); 44 | makeOverlay(); 45 | 46 | // do operation on CPU 47 | selectWindow(input); 48 | run("Duplicate...", "title=mean2D_CPU"); 49 | run("Mean...", "radius=" + radius); 50 | 51 | // visualise result 52 | zoom(10); 53 | setWindowPosition(2, 0); 54 | setMinAndMax(0, 1); 55 | makeOverlay(); 56 | 57 | // ----------------------------------------------------------------- 58 | 59 | // create 3D example image 60 | input = "example3d"; 61 | newImage(input, "8-bit black", 10, 10, 10); 62 | setSlice(4); 63 | makeRectangle(4, 5, 1, 1); 64 | run("Add...", "value=255"); 65 | run("Select None"); 66 | 67 | // visualise input image 68 | zoom(10); 69 | setWindowPosition(0, 1); 70 | setMinAndMax(0, 1); 71 | makeOverlay(); 72 | 73 | // init GPU 74 | run("CLIJ Macro Extensions", "cl_device="); 75 | 76 | // do operation on GPU 77 | outputGPU = "mean3d_GPU"; 78 | Ext.CLIJ_push(input); 79 | Ext.CLIJ_mean3DSphere(input, outputGPU, radius, radius, radius); 80 | Ext.CLIJ_pull(outputGPU); 81 | 82 | // visualise result 83 | setSlice(4); 84 | zoom(10); 85 | setWindowPosition(1, 1); 86 | setMinAndMax(0, 1); 87 | makeOverlay(); 88 | 89 | // do operation on CPU 90 | selectWindow(input); 91 | run("Duplicate...", "title=mean3D_CPU duplicate"); 92 | run("Mean 3D...", "x=" + radius + " y=" + radius + " z=" + radius); 93 | 94 | // visualise result 95 | zoom(10); 96 | setSlice(4); 97 | setWindowPosition(2, 1); 98 | setMinAndMax(0, 1); 99 | makeOverlay(); 100 | 101 | // ----------------------------------------------------------------- 102 | 103 | function zoom(count) { 104 | for (i = 0; i < count; i++) { 105 | run("In [+]"); 106 | } 107 | } 108 | 109 | function setWindowPosition(x, y) { 110 | setLocation(x * 330, y * 370); 111 | } 112 | 113 | function makeOverlay() { 114 | for (y = 1; y <= 9; y += 2) { 115 | makeRectangle(0, y, 10, 1); 116 | Roi.setStrokeColor("gray"); 117 | run("Add Selection..."); 118 | } 119 | for (x = 1; x <= 9; x += 2) { 120 | makeRectangle(x, 0, 1, 10); 121 | Roi.setStrokeColor("gray"); 122 | run("Add Selection..."); 123 | } 124 | run("Select None"); 125 | } 126 | -------------------------------------------------------------------------------- /src/main/macro/mean_detailed_comparison_IJ_CLIJ_radius.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: mean_detailed_comparison_IJ_CLIJ_radius.ijm 2 | // 3 | // This macro shows differences between ImageJ and CLIJ when executing a mean filter. 4 | // Starting from a 2D image where a single pixel is set to 255, mean filters with 5 | // different radii are applied. 6 | // 7 | // Author: Robert Haase 8 | // June 2019 9 | // --------------------------------------------- 10 | 11 | run("Close All"); 12 | 13 | for (radius = 1; radius < 5; radius++) { 14 | // ----------------------------------------------------------------- 15 | 16 | // create 2D example image 17 | input = "example2d"; 18 | newImage(input, "8-bit black", 10, 10, 1); 19 | makeRectangle(4, 5, 1, 1); 20 | run("Add...", "value=255"); 21 | run("Select None"); 22 | 23 | // visualise input image 24 | zoom(10); 25 | setWindowPosition(0, 0); 26 | setMinAndMax(0, 1); 27 | makeOverlay(); 28 | 29 | // init GPU 30 | run("CLIJ Macro Extensions", "cl_device="); 31 | 32 | // do operation on GPU 33 | outputGPU = "mean2d_GPU (r=" + radius + ")"; 34 | Ext.CLIJ_push(input); 35 | Ext.CLIJ_mean2DSphere(input, outputGPU, radius, radius); 36 | Ext.CLIJ_pull(outputGPU); 37 | 38 | // visualise result 39 | zoom(10); 40 | setWindowPosition(radius, 0); 41 | setMinAndMax(0, 1); 42 | makeOverlay(); 43 | 44 | // do operation on CPU 45 | selectWindow(input); 46 | run("Duplicate...", "title=[mean2D_CPU (r=" + radius + ")]"); 47 | run("Mean...", "radius=" + radius); 48 | 49 | // visualise result 50 | zoom(10); 51 | setWindowPosition(radius, 1); 52 | setMinAndMax(0, 1); 53 | makeOverlay(); 54 | } 55 | // ----------------------------------------------------------------- 56 | 57 | function zoom(count) { 58 | for (i = 0; i < count; i++) { 59 | run("In [+]"); 60 | } 61 | } 62 | 63 | function setWindowPosition(x, y) { 64 | setLocation(x * 330, y * 370); 65 | } 66 | 67 | function makeOverlay() { 68 | for (y = 1; y <= 9; y += 2) { 69 | makeRectangle(0, y, 10, 1); 70 | Roi.setStrokeColor("gray"); 71 | run("Add Selection..."); 72 | } 73 | for (x = 1; x <= 9; x += 2) { 74 | makeRectangle(x, 0, 1, 10); 75 | Roi.setStrokeColor("gray"); 76 | run("Add Selection..."); 77 | } 78 | run("Select None"); 79 | } 80 | -------------------------------------------------------------------------------- /src/main/macro/memory_reuse_versus_reallocation.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: memory_reuse_versus_reallocation.ijm 2 | // 3 | // This exmple macro shows that processing speed can be gained 4 | // by reusing image memory in the GPU instead of allocating 5 | // memory during every iteration 6 | // 7 | // Author: Robert Haase 8 | // July 2019 9 | // --------------------------------------------- 10 | 11 | run("Close All"); 12 | 13 | width = 1024; 14 | height = 1024; 15 | slices = 100; 16 | 17 | // Get test data 18 | newImage("original", "16-bit ramp", width, height, slices); 19 | 20 | // init GPU 21 | run("CLIJ Macro Extensions", "cl_device="); 22 | Ext.CLIJ_clear(); 23 | 24 | // push images to GPU 25 | Ext.CLIJ_push("original"); 26 | 27 | // cleanup imagej 28 | run("Close All"); 29 | 30 | for (j = 0; j < 10; j++) { 31 | // copy the image 10 times wihile reusing target memory 32 | time = getTime(); 33 | for (i = 0; i < 10; i++) { 34 | Ext.CLIJ_copy("original", "copy"); 35 | } 36 | IJ.log("Copying with memory reusing took " + (getTime() - time)); 37 | 38 | // copy the image 10 times while releasing and reallocating target memory. 39 | time = getTime(); 40 | for (i = 0; i < 10; i++) { 41 | Ext.CLIJ_copy("original", "copy"); 42 | Ext.CLIJ_release("copy"); 43 | } 44 | IJ.log("Copying with memory reallocation took " + (getTime() - time)); 45 | } -------------------------------------------------------------------------------- /src/main/macro/minimum.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: minimum.ijm 2 | // 3 | // This macro shows how apply a minimum filter in the GPU 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | run("Duplicate...", "use"); 13 | 14 | //open("C:/structure/data/t1-head.tif"); 15 | getDimensions(width, height, channels, slices, frames); 16 | input = getTitle(); 17 | 18 | minimum = "minimum"; 19 | 20 | // Init GPU 21 | run("CLIJ Macro Extensions", "cl_device="); 22 | Ext.CLIJ_clear(); 23 | 24 | // push data to GPU 25 | Ext.CLIJ_push(input); 26 | 27 | // cleanup ImageJ 28 | run("Close All"); 29 | 30 | // reslice 31 | Ext.CLIJ_minimum3DBox(input, minimum, 3, 3, 3); 32 | 33 | // show results 34 | Ext.CLIJ_pull(input); 35 | Ext.CLIJ_pull(minimum); 36 | 37 | -------------------------------------------------------------------------------- /src/main/macro/motionCorrection.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: motionCorrection,ijm 2 | // 3 | // This macro shows how to do motion correction 4 | // image stack where slices might be shifted to 5 | // each other in the GPU. 6 | // 7 | // Author: Robert Haase 8 | // December 2018 9 | // --------------------------------------------- 10 | run("Close All"); 11 | 12 | // define move to correct 13 | file = "https://github.com/clij/clij-docs/raw/master/src/main/resources/motion_correction_Drosophila_DSmanila1.tif"; 14 | //file = "C:/structure/code/clij-docs/src/main/resources/motion_correction_Drosophila_DSmanila1.tif"; 15 | 16 | // define identifiers for intermediate results in the GPU 17 | inputStack = "inputStack"; 18 | slice = "slice"; 19 | shifted = "shifted"; 20 | binary = "binary"; 21 | 22 | // define a threshold to differentiate object and background 23 | threshold = 50; 24 | 25 | // open image 26 | open(file); 27 | rename(inputStack); 28 | run("32-bit"); 29 | 30 | // collect info about it 31 | getDimensions(width, height, channels, slices, frames); 32 | 33 | 34 | // Init GPU 35 | run("CLIJ Macro Extensions", "cl_device="); 36 | Ext.CLIJ_clear(); 37 | 38 | 39 | Ext.CLIJ_push(inputStack); 40 | 41 | formerX = 0; 42 | formerY = 0; 43 | 44 | // process all slices; only the first stays where it is 45 | for (z = 0; z < slices; z++) { 46 | IJ.log("z: " + z); 47 | 48 | Ext.CLIJ_copySlice(inputStack, slice, z); 49 | 50 | // determine center of mass 51 | Ext.CLIJ_threshold(slice, binary, threshold); 52 | Ext.CLIJ_centerOfMass(binary); 53 | x = getResult("MassX", nResults() - 1); 54 | y = getResult("MassY", nResults() - 1); 55 | 56 | if (z > 0) { 57 | 58 | // determine shift 59 | deltaX = x - formerX; 60 | deltaY = y - formerY; 61 | 62 | // apply translation transformation 63 | Ext.CLIJ_affineTransform2D(slice, shifted, "translatex=" + deltaX + " translatey=" + deltaY); 64 | 65 | // copy result back 66 | Ext.CLIJ_copySlice(shifted, inputStack, z); 67 | 68 | } else { 69 | formerX = x; 70 | formerY = y; 71 | } 72 | } 73 | 74 | // show result 75 | Ext.CLIJ_pull(inputStack); 76 | rename("outputStack"); 77 | -------------------------------------------------------------------------------- /src/main/macro/motionCorrection_compare_stackreg.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: motionCorrection_compare_stackreg.ijm 2 | // 3 | // This macro compares performance of motion correction 4 | // on the GPU with StackReg. You need to install the 5 | // BIG-EPFL update site in order to test it. 6 | // 7 | // Author: Robert Haase 8 | // June 2019 9 | // --------------------------------------------- 10 | run("Close All"); 11 | 12 | // define move to correct 13 | file = "https://github.com/clij/clij-docs/raw/master/src/main/resources/motion_correction_Drosophila_DSmanila1.tif"; 14 | //file = "C:/structure/code/clij-docs/src/main/resources/motion_correction_Drosophila_DSmanila1.tif"; 15 | 16 | // define identifiers for intermediate results in the GPU 17 | inputStack = "inputStack"; 18 | slice = "slice"; 19 | shifted = "shifted"; 20 | binary = "binary"; 21 | 22 | // define a threshold to differentiate object and background 23 | threshold = 50; 24 | 25 | // open image 26 | open(file); 27 | rename(inputStack); 28 | run("32-bit"); 29 | 30 | // collect info about it 31 | getDimensions(width, height, channels, slices, frames); 32 | 33 | 34 | // Init GPU 35 | time = getTime(); 36 | run("CLIJ Macro Extensions", "cl_device="); 37 | Ext.CLIJ_clear(); 38 | 39 | Ext.CLIJ_push(inputStack); 40 | 41 | formerX = 0; 42 | formerY = 0; 43 | 44 | // process all slices; only the first stays where it is 45 | for (z = 0; z < slices; z++) { 46 | Ext.CLIJ_copySlice(inputStack, slice, z); 47 | 48 | // determine center of mass 49 | Ext.CLIJ_threshold(slice, binary, threshold); 50 | Ext.CLIJ_centerOfMass(binary); 51 | x = getResult("MassX", nResults() - 1); 52 | y = getResult("MassY", nResults() - 1); 53 | 54 | if (z > 0) { 55 | 56 | // determine shift 57 | deltaX = x - formerX; 58 | deltaY = y - formerY; 59 | 60 | // apply translation transformation 61 | Ext.CLIJ_affineTransform2D(slice, shifted, "translatex=" + deltaX + " translatey=" + deltaY); 62 | 63 | // copy result back 64 | Ext.CLIJ_copySlice(shifted, inputStack, z); 65 | 66 | } else { 67 | formerX = x; 68 | formerY = y; 69 | } 70 | } 71 | 72 | // show result 73 | Ext.CLIJ_pull(inputStack); 74 | rename("CLIJ motion corrected"); 75 | IJ.log("Motion correction with CLIJ took " + (getTime() - time) + " msec"); 76 | 77 | // open image again and register with stackreg 78 | open(file); 79 | time = getTime(); 80 | rename("StackReg motion corrected"); 81 | run("32-bit"); 82 | run("StackReg", "transformation=Translation"); 83 | 84 | IJ.log("Motion correction with StackReg took " + (getTime() - time) + " msec"); 85 | 86 | open(file); 87 | rename("Original"); 88 | run("32-bit"); 89 | 90 | imageCalculator("Subtract create 32-bit stack", "CLIJ motion corrected", "StackReg motion corrected"); 91 | rename("Difference"); 92 | 93 | images = newArray("Original", "CLIJ motion corrected", "StackReg motion corrected", "Difference"); 94 | for (i = 0; i < 4; i++) { 95 | selectWindow(images[i]); 96 | setLocation(50 + 300 * i, 50); 97 | run("Out [-]"); 98 | run("Out [-]"); 99 | } 100 | -------------------------------------------------------------------------------- /src/main/macro/orthogonalMaximumProjections.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: orthogonalMaximumProjections.ijm 2 | // 3 | // This macro shows how maximum-X, -Y and -Z projections can be created using the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | //open("C:/structure/data/t1-head.tif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle(); 15 | downScalingFactorInXY = 0.666; // because the image has slice distance 1.5 16 | downScalingFactorInZ = 1; 17 | 18 | downscaled = "Downscaled"; 19 | 20 | maximumProjectionX = "Maximum projection in X"; 21 | maximumProjectionY = "Maximum projection in Y"; 22 | maximumProjectionZ = "Maximum projection in Z"; 23 | 24 | // Init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push data to GPU 29 | Ext.CLIJ_push(input); 30 | 31 | // cleanup ImageJ 32 | run("Close All"); 33 | 34 | // process 35 | Ext.CLIJ_downsample3D(input, downscaled, downScalingFactorInXY, downScalingFactorInXY, downScalingFactorInZ); 36 | 37 | Ext.CLIJ_maximumXYZProjection(downscaled, maximumProjectionX, 2, 1, 0); 38 | Ext.CLIJ_maximumXYZProjection(downscaled, maximumProjectionY, 2, 0, 1); 39 | Ext.CLIJ_maximumXYZProjection(downscaled, maximumProjectionZ, 0, 1, 2); 40 | 41 | // show results 42 | Ext.CLIJ_pull(maximumProjectionX); 43 | Ext.CLIJ_pull(maximumProjectionY); 44 | Ext.CLIJ_pull(maximumProjectionZ); 45 | -------------------------------------------------------------------------------- /src/main/macro/project3D.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: project3D.ijm 2 | // 3 | // This macro shows how a 3D projection can be done in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | 10 | run("Close All"); 11 | 12 | // Get test data 13 | //open("C:/structure/data/t1-head.tif"); 14 | run("T1 Head (2.4M, 16-bits)"); 15 | 16 | angle_step = 10; 17 | 18 | run("32-bit"); 19 | rename("original"); 20 | 21 | time = getTime(); 22 | run("3D Project...", "projection=[Brightest Point] axis=Y-Axis slice=1 initial=0 total=360 rotation=" + angle_step + " lower=1 upper=255 opacity=0 surface=100 interior=50 interpolate"); 23 | close(); 24 | IJ.log("CPU 3D projection took " + (getTime()-time) + " msec"); 25 | 26 | getDimensions(width, height, channels, depth, frames); 27 | 28 | 29 | // init GPU 30 | run("CLIJ Macro Extensions", "cl_device="); 31 | Ext.CLIJ_clear(); 32 | 33 | time = getTime(); 34 | 35 | // push images to GPU 36 | Ext.CLIJ_push("original"); 37 | // reserve the right amount of memory for the result image 38 | Ext.CLIJ_create3D("target", width, height, 360 / angle_step, 32); 39 | 40 | // reserve a bit more pixels in Z for translated and rotated image because we 41 | // need space for the shoulders if we rotated the patient around the Y-axis 42 | Ext.CLIJ_create3D("rotated", width, height, depth * 2, 32); 43 | Ext.CLIJ_create3D("translated", width, height, depth * 2, 32); 44 | 45 | // cleanup imagej 46 | run("Close All"); 47 | 48 | // we need to translate the stack in Z to get some space for the shoulders 49 | // when we rotate the head around the y-axis 50 | Ext.CLIJ_translate3D("original", "translated", 0, 0, depth / 2); 51 | 52 | count = 0; 53 | for (angle = 0; angle < 360; angle += angle_step) { 54 | Ext.CLIJ_rotate3D("translated", "rotated", 0, angle, 0.0, true); 55 | Ext.CLIJ_maximumZProjection("rotated", "maxProjected"); 56 | 57 | // put the maximum projection in the right place in the result stack 58 | Ext.CLIJ_copySlice("maxProjected", "target", count); 59 | 60 | count++; 61 | } 62 | 63 | // show result 64 | Ext.CLIJ_pull("target"); 65 | 66 | IJ.log("GPU 3D projection took " + (getTime()-time) + " msec"); 67 | -------------------------------------------------------------------------------- /src/main/macro/push.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: push.ijm 2 | // 3 | // This macro shows how an image is pushed to the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | input = getTitle(); 13 | 14 | // Init GPU 15 | run("CLIJ Macro Extensions", "cl_device="); 16 | Ext.CLIJ_clear(); 17 | 18 | // push images to GPU 19 | Ext.CLIJ_push(input); 20 | 21 | Ext.CLIJ_reportMemory(); -------------------------------------------------------------------------------- /src/main/macro/pushCurrentZStack.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: pushCurrentZStack.ijm 2 | // 3 | // This macro shows how the current Z-stack of an image is pushed to the GPU. 4 | // 5 | // Author: Robert Haase 6 | // September 2019 7 | // --------------------------------------------- 8 | 9 | 10 | // Get test data 11 | run("Mitosis (26MB, 5D stack)"); 12 | input = getTitle(); 13 | 14 | // Init GPU 15 | run("CLIJ Macro Extensions", "cl_device="); 16 | Ext.CLIJ_clear(); 17 | 18 | // push images to GPU 19 | Ext.CLIJ_pushCurrentZStack(input); 20 | 21 | run("Close All"); 22 | 23 | // pull the image back to see what it was 24 | Ext.CLIJ_pull(input); 25 | -------------------------------------------------------------------------------- /src/main/macro/pushSlice.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: pushSlice.ijm 2 | // 3 | // This macro shows how the current slice of an image is pushed to the GPU. 4 | // 5 | // Author: Robert Haase 6 | // September 2019 7 | // --------------------------------------------- 8 | 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | input = getTitle(); 13 | 14 | // Init GPU 15 | run("CLIJ Macro Extensions", "cl_device="); 16 | Ext.CLIJ_clear(); 17 | 18 | // push images to GPU 19 | Ext.CLIJ_pushCurrentSlice(input); 20 | 21 | run("Close All"); 22 | 23 | // pull the image back to see what it was 24 | Ext.CLIJ_pull(input); 25 | -------------------------------------------------------------------------------- /src/main/macro/reslicing.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: reslicing.ijm 2 | // 3 | // This macro shows how stacks can be resliced in the GPU 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | //open("C:/structure/data/t1-head.tif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle(); 15 | 16 | resliced = "Resliced left"; 17 | 18 | // Init GPU 19 | run("CLIJ Macro Extensions", "cl_device="); 20 | Ext.CLIJ_clear(); 21 | 22 | // push data to GPU 23 | Ext.CLIJ_push(input); 24 | 25 | // reslice 26 | Ext.CLIJ_resliceLeft(input, resliced); 27 | 28 | // show results 29 | Ext.CLIJ_pull(resliced); 30 | -------------------------------------------------------------------------------- /src/main/macro/rgb_invert_black_white.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rgb_invert_black_white.ijm 2 | // 3 | // This macro shows how replace black by white in 4 | // plots in the GPU. 5 | // 6 | // Author: Robert Haase 7 | // February 2020 8 | // --------------------------------------------- 9 | run("Close All"); 10 | 11 | // get example data 12 | open("https://clij.github.io/clij-benchmarking/plotting_jmh/images/imagesize/clij_ij_comparison_BinaryAnd2D.png"); 13 | run("RGB Stack"); 14 | run("32-bit"); // we do it in 32 bit because we need negative values 15 | run("Make Composite", "display=Composite"); 16 | 17 | input = getTitle(); 18 | 19 | // Init GPU 20 | run("CLIJ Macro Extensions", "cl_device="); 21 | Ext.CLIJ_clear(); 22 | 23 | // send input to GPU 24 | time = getTime(); 25 | Ext.CLIJ_push(input); 26 | 27 | // crop three 2D single channel images 28 | R = "R"; 29 | Ext.CLIJ_copySlice(input, R, 0); 30 | G = "G"; 31 | Ext.CLIJ_copySlice(input, G, 1); 32 | B = "B"; 33 | Ext.CLIJ_copySlice(input, B, 2); 34 | 35 | // do the math Jan Eglinger suggested: https://forum.image.sc/t/invert-rgb-image-without-changing-colors/33571 36 | 37 | function mixChannels(c1, c2) { 38 | temp1 = "temp1"; 39 | temp2 = "temp2"; 40 | 41 | // c1 + c2 42 | Ext.CLIJ_addImages(c1, c2, temp1); 43 | // divide by 2 44 | Ext.CLIJ_multiplyImageAndScalar(temp1, temp2, 0.5); 45 | // - 46 | Ext.CLIJ2_invert(temp2, temp1); 47 | // add 255 48 | Ext.CLIJ2_addImageAndScalar(temp1, temp2, 255); 49 | return temp2; 50 | } 51 | 52 | // ------------------------------------------------- 53 | // G + B 54 | result = mixChannels(G, B); 55 | Ext.CLIJ2_copySlice(result, input, 0); 56 | 57 | // R + B 58 | result = mixChannels(R, B); 59 | Ext.CLIJ2_copySlice(result, input, 1); 60 | 61 | // R + G 62 | result = mixChannels(R, G); 63 | Ext.CLIJ2_copySlice(result, input, 2); 64 | 65 | // ------------------------------------------------- 66 | Ext.CLIJ_pull(input); 67 | print("The workflow execution took " + (getTime() - time) + " ms"); 68 | run("8-bit"); 69 | run("Make Composite", "display=Composite"); 70 | -------------------------------------------------------------------------------- /src/main/macro/rotate.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rotate.ijm 2 | // 3 | // This macro shows how stacks can be rotated in the GPU 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | run("Close All"); 9 | 10 | // Get test data 11 | run("T1 Head (2.4M, 16-bits)"); 12 | //open("C:/structure/data/t1-head.tif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle(); 15 | 16 | rotated = "Rotate left"; 17 | 18 | // Init GPU 19 | run("CLIJ Macro Extensions", "cl_device="); 20 | Ext.CLIJ_clear(); 21 | 22 | // push data to GPU 23 | Ext.CLIJ_push(input); 24 | 25 | // rotate 26 | Ext.CLIJ_rotateLeft(input, rotated); 27 | 28 | // show results 29 | Ext.CLIJ_pull(rotated); 30 | -------------------------------------------------------------------------------- /src/main/macro/rotateFree.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rotateFree.ijm 2 | // 3 | // This macro shows how to rotate an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | 10 | //run("Close All"); 11 | 12 | // Get test data 13 | run("Blobs (25K)"); 14 | //open("C:/structure/data/blobs.gif"); 15 | 16 | 17 | angle_step = 10; 18 | 19 | run("32-bit"); 20 | rename("original"); 21 | 22 | getDimensions(width, height, channels, depth, frames); 23 | 24 | // init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push images to GPU 29 | Ext.CLIJ_push("original"); 30 | // reserve the right amount of memory for the result image 31 | Ext.CLIJ_create3D("target", width, height, 360 / angle_step, 32); 32 | 33 | // cleanup imagej 34 | run("Close All"); 35 | 36 | count = 0; 37 | for (angle = 0; angle < 360; angle += angle_step) { 38 | Ext.CLIJ_rotate2D("original", "rotated", angle, true); 39 | 40 | // put the rotated image in the right place in the result stack 41 | Ext.CLIJ_copySlice("rotated", "target", count); 42 | 43 | count++; 44 | } 45 | 46 | // show result 47 | Ext.CLIJ_pull("target"); 48 | run("Invert LUT"); 49 | -------------------------------------------------------------------------------- /src/main/macro/rotateOverwriteOriginal.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rotateOverwriteOriginal.ijm 2 | // 3 | // This macro shows how to rotate an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | 10 | //run("Close All"); 11 | 12 | // Get test data 13 | run("Blobs (25K)"); 14 | //open("C:/structure/data/blobs.gif"); 15 | 16 | 17 | angle_step = 1; 18 | 19 | run("32-bit"); 20 | rename("original"); 21 | 22 | getDimensions(width, height, channels, depth, frames); 23 | 24 | // init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push images to GPU 29 | Ext.CLIJ_push("original"); 30 | // reserve the right amount of memory for the result image 31 | Ext.CLIJ_create3D("target", width, height, 360 / angle_step, 32); 32 | 33 | // cleanup imagej 34 | run("Close All"); 35 | 36 | count = 0; 37 | for (angle = 0; angle < 360; angle += angle_step) { 38 | Ext.CLIJ_rotate2D("original", "rotated", angle_step, true); 39 | 40 | // never overwrite the original with the rotated image! 41 | // this is just an academic example to show what can go wrong 42 | Ext.CLIJ_copy("rotated", "original"); 43 | 44 | // put the rotated image in the right place in the result stack 45 | Ext.CLIJ_copySlice("rotated", "target", count); 46 | 47 | count++; 48 | } 49 | 50 | // show result 51 | Ext.CLIJ_pull("target"); 52 | run("Invert LUT"); 53 | -------------------------------------------------------------------------------- /src/main/macro/rotate_comparison_IJ_CLIJ.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: rotate_comparison_IJ_CLIJ.ijm 2 | // 3 | // This macro shows how stacks can be rotated in the GPU 4 | // and how different results are between CLIJ and ImageJ. 5 | // 6 | // Author: Robert Haase 7 | // July 2019 8 | // --------------------------------------------- 9 | run("Close All"); 10 | 11 | // Get test data 12 | run("Blobs (25K)"); 13 | run("32-bit"); 14 | 15 | getDimensions(width, height, channels, slices, frames); 16 | input = getTitle(); 17 | 18 | rotated = "Rotated"; 19 | 20 | // Init GPU 21 | run("CLIJ Macro Extensions", "cl_device=1070"); 22 | Ext.CLIJ_clear(); 23 | 24 | // push data to GPU 25 | Ext.CLIJ_push(input); 26 | 27 | // rotate on CPU 28 | run("Rotate... ", "angle=45 grid=1 interpolation=Bilinear"); 29 | 30 | // rotate on GPU 31 | Ext.CLIJ_affineTransform2D(input, rotated, "center rotate=45 -center"); 32 | 33 | // show results 34 | Ext.CLIJ_pull(rotated); 35 | 36 | // calculate difference image between CPU and GPU 37 | imageCalculator("Subtract create 32-bit", input, rotated); 38 | -------------------------------------------------------------------------------- /src/main/macro/scaleFree.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: project3D.ijm 2 | // 3 | // This macro shows how to rotate an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // January 2019 7 | // --------------------------------------------- 8 | 9 | 10 | run("Close All"); 11 | 12 | // Get test data 13 | run("Blobs (25K)"); 14 | //open("C:/structure/data/blobs.gif"); 15 | 16 | 17 | zoom_step = 0.03; 18 | 19 | run("32-bit"); 20 | rename("original"); 21 | 22 | getDimensions(width, height, channels, depth, frames); 23 | 24 | // init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push images to GPU 29 | Ext.CLIJ_push("original"); 30 | // reserve the right amount of memory for the result image 31 | Ext.CLIJ_create3D("target", width, height, 1.0 / zoom_step, 32); 32 | 33 | // cleanup imagej 34 | run("Close All"); 35 | 36 | count = 0; 37 | for (zoom = 1; zoom > 0; zoom -= zoom_step) { 38 | Ext.CLIJ_scale2D("original", "zoomed", zoom, true); 39 | 40 | // put the zoomed image in the right place in the result stack 41 | Ext.CLIJ_copySlice("zoomed", "target", count); 42 | 43 | count++; 44 | } 45 | 46 | // show result 47 | Ext.CLIJ_pull("target"); 48 | run("Invert LUT"); 49 | -------------------------------------------------------------------------------- /src/main/macro/statistics.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: statistics,ijm 2 | // 3 | // This macro shows derive statistics form an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // September 2019 7 | // --------------------------------------------- 8 | 9 | 10 | // Get test data 11 | run("Blobs (25K)"); 12 | //open("C:/structure/data/blobs.gif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle() 15 | 16 | // Init GPU 17 | run("CLIJ Macro Extensions", "cl_device="); 18 | Ext.CLIJ_clear(); 19 | 20 | // push data to GPU 21 | Ext.CLIJ_push(input); 22 | 23 | // get min/max of all pixels 24 | Ext.CLIJ_minimumOfAllPixels(input); 25 | minimumIntensity = getResult("Minimum", nResults() - 1); 26 | Ext.CLIJ_maximumOfAllPixels(input); 27 | maximumIntensity = getResult("Maximum", nResults() - 1); 28 | 29 | // create a binary image 30 | binary = "binary"; 31 | Ext.CLIJ_automaticThreshold(input, binary, "Otsu"); 32 | 33 | // area of binary image 34 | Ext.CLIJ_sumOfAllPixels(binary); 35 | mx = getResult("Sum", nResults() - 1); 36 | 37 | // determine center of mass 38 | Ext.CLIJ_centerOfMass(binary); 39 | mx = getResult("MassX", nResults() - 1); 40 | my = getResult("MassY", nResults() - 1); 41 | -------------------------------------------------------------------------------- /src/main/macro/thresholding.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: thresholding,ijm 2 | // 3 | // This macro shows how to apply a threshold to an image in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | 10 | // Get test data 11 | run("Blobs (25K)"); 12 | //open("C:/structure/data/blobs.gif"); 13 | getDimensions(width, height, channels, slices, frames); 14 | input = getTitle(); 15 | threshold = 128; 16 | 17 | // create memory for mask image 18 | newImage("Untitled", "8-bit black", width, height, slices); 19 | rename("Mask"); 20 | mask = getTitle(); 21 | 22 | // Init GPU 23 | run("CLIJ Macro Extensions", "cl_device="); 24 | Ext.CLIJ_clear(); 25 | 26 | // push data to GPU 27 | Ext.CLIJ_push(input); 28 | Ext.CLIJ_push(mask); 29 | 30 | // cleanup ImageJ 31 | run("Close All"); 32 | 33 | // create a mask using a fixed threshold 34 | Ext.CLIJ_threshold(input, mask, threshold); 35 | 36 | // show result 37 | Ext.CLIJ_pullBinary(mask); 38 | -------------------------------------------------------------------------------- /src/main/macro/topHat.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: topHat.ijm 2 | // 3 | // This macro shows how a top-hat filter can be applied in the GPU. 4 | // 5 | // Author: Robert Haase 6 | // December 2018 7 | // --------------------------------------------- 8 | 9 | radiusXY = 10; 10 | radiusZ = 0; 11 | 12 | run ("Close All"); 13 | 14 | // Get test data 15 | //open("C:/structure/data/t1-head.tif"); 16 | run("T1 Head (2.4M, 16-bits)"); 17 | 18 | input = getTitle(); 19 | median = "median"; 20 | temp1 = "temp1"; 21 | temp2 = "temp2"; 22 | output = "output"; 23 | 24 | // Init GPU 25 | run("CLIJ Macro Extensions", "cl_device="); 26 | Ext.CLIJ_clear(); 27 | 28 | // push images to GPU 29 | Ext.CLIJ_push(input); 30 | 31 | // CleanUp ImageJ 32 | close(); 33 | 34 | 35 | Ext.CLIJ_medianSliceBySliceSphere(input, median, 1, 1); 36 | Ext.CLIJ_minimum3DBox(median, temp1, radiusXY, radiusXY, radiusZ); 37 | Ext.CLIJ_maximum3DBox(temp1, temp2, radiusXY, radiusXY, radiusZ); 38 | Ext.CLIJ_subtractImages(median, temp2, output); 39 | 40 | Ext.CLIJ_pull(input); 41 | Ext.CLIJ_pull(output); 42 | 43 | // Cleanup by the end 44 | Ext.CLIJ_clear(); 45 | -------------------------------------------------------------------------------- /src/main/macro/translate.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: translate.ijm 2 | // 3 | // This macro shows how to translate an image in the GPU 4 | // and make a video of an openign curtain. 5 | // 6 | // Author: Robert Haase 7 | // July 2019 8 | // --------------------------------------------- 9 | 10 | 11 | //run("Close All"); 12 | 13 | // Get test data 14 | run("Blobs (25K)"); 15 | //open("C:/structure/data/blobs.gif"); 16 | 17 | 18 | step = 10; 19 | 20 | run("32-bit"); 21 | rename("original"); 22 | 23 | getDimensions(width, height, channels, depth, frames); 24 | 25 | // init GPU 26 | run("CLIJ Macro Extensions", "cl_device="); 27 | Ext.CLIJ_clear(); 28 | 29 | // push images to GPU 30 | Ext.CLIJ_push("original"); 31 | // reserve the right amount of memory for the result image 32 | Ext.CLIJ_create3D("target", width, height, 200 / step, 32); 33 | 34 | // cleanup imagej 35 | run("Close All"); 36 | 37 | count = 0; 38 | for (displacement = 0; displacement < 200; displacement += step) { 39 | Ext.CLIJ_translate2D("original", "translated", displacement, 0); 40 | 41 | // put the translated image in the right place in the result stack 42 | Ext.CLIJ_copySlice("translated", "target", count); 43 | 44 | count++; 45 | } 46 | 47 | // show result 48 | Ext.CLIJ_pull("target"); 49 | run("Invert LUT"); 50 | -------------------------------------------------------------------------------- /src/main/macro/turn_stack.ijm: -------------------------------------------------------------------------------- 1 | // CLIJ example macro: turn_stack.ijm 2 | // 3 | // This macro shows how to wrangle voxels in 3D in the GPU. 4 | // 5 | // This marco was created using the macro recorder 6 | // 7 | // Author: Robert Haase 8 | // December 2018 9 | // --------------------------------------------- 10 | 11 | run("Close All"); 12 | 13 | run("T1 Head (2.4M, 16-bits)"); 14 | //open("C:/structure/data/t1-head.tif"); 15 | run("CLIJ Macro Extensions", "cl_device="); 16 | Ext.CLIJ_push("t1-head.tif"); 17 | Ext.CLIJ_resliceLeft("t1-head.tif", "CLIJ_resliceLeft_destination_t1-head.tif"); 18 | Ext.CLIJ_rotateRight("CLIJ_resliceLeft_destination_t1-head.tif", "CLIJ_rotateRight_destination_CLIJ_resliceLeft_destination_t1-head.tif"); 19 | Ext.CLIJ_pull("CLIJ_rotateRight_destination_CLIJ_resliceLeft_destination_t1-head.tif"); 20 | Ext.CLIJ_reportMemory(); -------------------------------------------------------------------------------- /src/main/macro/warpCat.ijm: -------------------------------------------------------------------------------- 1 | // This script demonstrates how to apply a vector field 2 | // to an image in order to transform it non-rigidly 3 | // 4 | // It uses a picture showing Pixel. 5 | // Yes, the cats name is Pixel. 6 | // 7 | // Make sure to activate the "CLIJ" update site before 8 | // running this macro in Fiji. 9 | // 10 | // Author: Robert Haase, rhaase@mpi-cbg.de 11 | // May 2019 12 | // 13 | 14 | 15 | run("Close All"); 16 | 17 | // get test image 18 | open("https://github.com/clij/clij-docs/raw/master/src/main/resources/pixel_cat.tif"); 19 | run("32-bit"); 20 | rename("cat"); 21 | 22 | getDimensions(width, height, channels, slices, frames) 23 | 24 | // create two images describing local shift 25 | newImage("shiftX", "32-bit black", width, height, 1); 26 | newImage("shiftY", "32-bit black", width, height, 1); 27 | 28 | // reserve memory for the result video 29 | newImage("resultStack", "32-bit black", width, height, 36); 30 | 31 | 32 | // shift some of the pixels in X 33 | selectImage("shiftX"); 34 | makeOval(150, 150, 200, 200); 35 | run("Add...", "value=50"); 36 | run("Select None"); 37 | run("Gaussian Blur...", "sigma=50"); 38 | run("Enhance Contrast", "saturated=0.35"); 39 | 40 | // init GPU 41 | run("CLIJ Macro Extensions", "cl_device="); 42 | Ext.CLIJ_push("cat"); 43 | Ext.CLIJ_push("shiftX"); 44 | Ext.CLIJ_copy("shiftX", "shiftY"); 45 | Ext.CLIJ_push("resultStack"); 46 | 47 | // clean up imagej 48 | run("Close All"); 49 | 50 | for (i = 0; i < 36; i++) { 51 | 52 | // change the shift from slice to slice 53 | Ext.CLIJ_affineTransform2D("shiftX", "rotatedShiftX", "center rotate=" + (i * 10) + " -center"); 54 | Ext.CLIJ_affineTransform2D("shiftY", "rotatedShiftY", "center rotate=" + (i * 10) + " -center"); 55 | 56 | // apply transform 57 | Ext.CLIJ_applyVectorField2D("cat", "rotatedShiftX", "rotatedShiftY", "transformed"); 58 | 59 | // put resulting 2D image in the right plane 60 | Ext.CLIJ_copySlice("transformed", "resultStack", i); 61 | } 62 | 63 | 64 | // get result back from GPU 65 | Ext.CLIJ_pull("resultStack"); 66 | 67 | Ext.CLIJ_clear(); 68 | -------------------------------------------------------------------------------- /src/main/macro/warpCat_RGB.ijm: -------------------------------------------------------------------------------- 1 | // This script demonstrates how to apply a vector field 2 | // to an RGB image in order to transform it non-rigidly 3 | // 4 | // It uses a picture showing Pixel. 5 | // Yes, the cats name is Pixel. 6 | // 7 | // Make sure to activate the "CLIJ" update site before 8 | // running this macro in Fiji. 9 | // 10 | // Author: Robert Haase, rhaase@mpi-cbg.de 11 | // November 2019 12 | // 13 | 14 | 15 | run("Close All"); 16 | 17 | // get test image 18 | open("https://github.com/clij/clij-docs/raw/master/src/main/resources/pixel_cat_rgb.jpg"); 19 | run("RGB Stack"); 20 | rename("catRGB"); 21 | 22 | getDimensions(width, height, channels, slices, frames) 23 | 24 | // create two images describing local shift 25 | newImage("shiftX", "32-bit black", width, height, 1); 26 | newImage("shiftY", "32-bit black", width, height, 1); 27 | 28 | // reserve memory for the result video 29 | newImage("resultStack", "32-bit black", width, height, 36 * 3); 30 | 31 | 32 | // shift some of the pixels in X 33 | selectImage("shiftX"); 34 | makeOval(350, 660, 200, 200); 35 | run("Add...", "value=50"); 36 | run("Select None"); 37 | run("Gaussian Blur...", "sigma=50"); 38 | run("Enhance Contrast", "saturated=0.35"); 39 | 40 | // init GPU 41 | run("CLIJ Macro Extensions", "cl_device="); 42 | Ext.CLIJ_push("catRGB"); 43 | Ext.CLIJ_push("shiftX"); 44 | Ext.CLIJ_copy("shiftX", "shiftY"); 45 | Ext.CLIJ_push("resultStack"); 46 | 47 | // create a 32-bit float image for processing individual channels 48 | Ext.CLIJ_create2D("cat", width, height, 32); 49 | 50 | // clean up imagej 51 | run("Close All"); 52 | 53 | for (i = 0; i < 36; i++) { 54 | // iterate over channels 55 | for (c = 0; c < 3; c++) { 56 | Ext.CLIJ_copySlice("catRGB", "cat", c); 57 | 58 | // change the shift from slice to slice 59 | Ext.CLIJ_affineTransform2D("shiftX", "rotatedShiftX", "center translateX=" + (i * 20) + " translateY=" + (i * -10) + " -center"); 60 | Ext.CLIJ_affineTransform2D("shiftY", "rotatedShiftY", "center translateX=" + (i * 20) + " translateY=" + (i * -10) + " -center"); 61 | 62 | // apply transform 63 | Ext.CLIJ_applyVectorField2D("cat", "rotatedShiftX", "rotatedShiftY", "transformed"); 64 | 65 | // put resulting 2D image in the right plane 66 | Ext.CLIJ_copySlice("transformed", "resultStack", i * 3 + c); 67 | } 68 | //break; 69 | } 70 | 71 | 72 | // get result back from GPU 73 | Ext.CLIJ_pull("resultStack"); 74 | 75 | // correct visualisation 76 | run("Stack to Hyperstack...", "order=xyczt(default) channels=3 slices=1 frames=36 display=Composite"); 77 | run("Enhance Contrast", "saturated=0.35"); 78 | Stack.setChannel(1); 79 | resetMinAndMax(); 80 | Stack.setChannel(2); 81 | resetMinAndMax(); 82 | Stack.setChannel(3); 83 | resetMinAndMax(); 84 | 85 | Ext.CLIJ_clear(); 86 | -------------------------------------------------------------------------------- /src/main/resources/blobs.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/blobs.tif -------------------------------------------------------------------------------- /src/main/resources/droso_crop.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/droso_crop.tif -------------------------------------------------------------------------------- /src/main/resources/flybrain.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/flybrain.tif -------------------------------------------------------------------------------- /src/main/resources/motion_correction_Drosophila_DSmanila1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/motion_correction_Drosophila_DSmanila1.tif -------------------------------------------------------------------------------- /src/main/resources/pixel_cat.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/pixel_cat.tif -------------------------------------------------------------------------------- /src/main/resources/pixel_cat_rgb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clij/clij-docs/d6297fc1671dd845a17e64d4f458be8f1af3fb19/src/main/resources/pixel_cat_rgb.jpg -------------------------------------------------------------------------------- /src/test/java/net/haesleinhuepf/clij/macro/documentation/MarkdownIJMacroDocumentationGenerator.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.macro.documentation; 2 | 3 | import net.haesleinhuepf.clij.CLIJ; 4 | import net.haesleinhuepf.clij.macro.CLIJMacroPlugin; 5 | import net.haesleinhuepf.clij.macro.CLIJMacroPluginService; 6 | import net.haesleinhuepf.clij.macro.documentation.MarkDownDocumentationTemplate; 7 | import net.haesleinhuepf.clij.macro.documentation.OffersDocumentation; 8 | import org.scijava.Context; 9 | 10 | import java.io.File; 11 | import java.io.FileWriter; 12 | import java.io.IOException; 13 | import java.util.ArrayList; 14 | import java.util.Collections; 15 | 16 | /** 17 | * MarkdownIJMacroDocumentationGenerator 18 | *

19 | *

20 | *

21 | * Author: @haesleinhuepf 22 | * 12 2018 23 | */ 24 | public class MarkdownIJMacroDocumentationGenerator { 25 | public static void main(String... args) throws IOException { 26 | generateMethodReference(); 27 | } 28 | 29 | private static void generateMethodReference() throws IOException { 30 | CLIJMacroPluginService service = new Context(CLIJMacroPluginService.class).getService(CLIJMacroPluginService.class); 31 | 32 | StringBuilder documentation = new StringBuilder(); 33 | documentation.append("# CLIJ reference for ImageJ macro\n\n"); 34 | 35 | ArrayList methodNames = new ArrayList(); 36 | methodNames.addAll(service.getCLIJMethodNames()); 37 | Collections.sort(methodNames); 38 | 39 | for (String name : methodNames) { 40 | CLIJMacroPlugin plugin = service.getCLIJMacroPlugin(name); 41 | documentation.append("\n"); 42 | if (plugin instanceof OffersDocumentation) { 43 | OffersDocumentation documentedPlugin = (OffersDocumentation) plugin; 44 | documentation.append(new MarkDownDocumentationTemplate(documentedPlugin.getDescription(), documentedPlugin.getAvailableForDimensions(), plugin)); 45 | } else { 46 | documentation.append("## " + name); 47 | documentation.append("Parameters: " + plugin.getParameterHelpText()); 48 | } 49 | 50 | String linkToExamples = AbstractDocumentationGenerator.searchForExampleScripts(name, "src/main/macro/", "https://github.com/clij/clij-docs/blob/master/src/main/macro/"); 51 | if(linkToExamples.length() > 0) { 52 | documentation.append("\n\n### Example scripts\n" + linkToExamples + "\n\n"); 53 | } 54 | 55 | } 56 | documentation.append("\n\n" + methodNames.size() + " plugins documented."); 57 | 58 | documentation.append("[Back to CLIJ documentation](https://clij.github.io/)\n" + 59 | "\n" + 60 | "[Imprint](https://clij.github.io/imprint)\n"); 61 | 62 | FileWriter writer = new FileWriter(new File("reference.md")); 63 | writer.write(documentation.toString()); 64 | writer.close(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/net/haesleinhuepf/clij/macro/documentation/RunAll.java: -------------------------------------------------------------------------------- 1 | package net.haesleinhuepf.clij.macro.documentation; 2 | 3 | import java.io.IOException; 4 | 5 | public class RunAll { 6 | public static void main(String... args) throws IOException { 7 | MarkdownGroovyOpDocumentationGenerator.main(args); 8 | MarkdownJavaOpDocumentationGenerator.main(args); 9 | MarkdownIJMacroDocumentationGenerator.main(args); 10 | MarkdownJythonOpDocumentationGenerator.main(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /testedsystems.md: -------------------------------------------------------------------------------- 1 | # Supported / tested platforms 2 | * Intel(R) Iris(R) Plus Graphics (OpenCL 2.0, Win 10 64 bit, November 2019) 3 | * [clij-core](https://github.com/clij/clij-docs/blob/master/testprotocols/20191101_clij-core_finley.txt) [clij](https://github.com/clij/clij-docs/blob/master/testprotocols/20191101_clij_finley.txt) 4 | * Intel(R) HD Graphics 620 (OpenCL 1.2, Win 10 64 bit, August 2019) 5 | * [clij-core](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij-core_ulice.txt) [clij](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij_ulice.txt) 6 | * NVidia GeForce 1070 Max-Q (OpenCL 1.2, Win 10 64 bit, August 2019) 7 | * [clij-core](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij-core_einstein2.txt) [clij](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij_einstein2.txt) 8 | * Intel(R) HD Graphics 630 (OpenCL 2.1, Win 10 64 bit, August 2019) 9 | * [clij-core](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij-core_einstein.txt) [clij](https://github.com/clij/clij-docs/blob/master/testprotocols/20190804_clij_einstein.txt) 10 | * Intel(R) HD Graphics 620 (OpenCL 2.0, Ubuntu 18.04, 64 bit / beignet 1.3.2, August 2019) 11 | * [clij-core](https://github.com/clij/clij-docs/blob/master/testprotocols/20190803_clij-core_ux38.txt) [clij](https://github.com/clij/clij-docs/blob/master/testprotocols/20190803_clij_ux38.txt) 12 | 13 | 14 | * AMD Radeon RX Vega 6 (OpenCL 2.0, Win 10 64 bit, Nov 2018) 15 | * Nvidia GeForce 940MX (OpenCL 2.0, Win 10 64 bit, Apr 2018) 16 | * NVidia GeForce GTX 960M (OpenCL 1.2, Win 10 64 bit, Feb 2018) 17 | * Intel(R) HD Graphics 620 (OpenCL 2.0, Fedora 27, Nov 2018) 18 | * Intel(R) HD Graphics 630 (OpenCL 1.2, Win 10 64bit, May 2019) 19 | * Intel(R) HD Graphics 530 (OpenCL 2.0, Win 10 64 bit, Feb 2018) 20 | * Intel(R) HD Graphics 515 (OpenCL 2.0, Win 10 64 bit, Feb 2018) 21 | * Intel(R) HD Graphics 405 (OpenCL 1.2, Win 10 64 bit, Feb 2018) 22 | * Intel(R) HD Graphics 400 (OpenCL 1.2, Win 10 64 bit, Nov 2018) 23 | * Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz (OpenCL 1.2, Win 10 64 bit, Apr 2018) 24 | * Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (OpenCL 2.0, Win 10 64 bit, Feb 2018) 25 | * Intel(R) Core(TM) m3-6Y30 CPU @ 0.90GHz (OpenCL 2.0, Win 10 64 bit, Feb 2018) 26 | * Intel(R) Atom(TM) x7-Z8750 CPU @ 1.60GHz (OpenCL 1.2, Win 10 64 bit, Feb 2018) 27 | * Intel(R) Atom(TM) x5-Z8350 CPU @ 1.44GHz (OpenCL 1.2, Win 10 64 bit, Nov 2018) 28 | 29 | Some of the tests failed on these devices: 30 | * AMD Ryzen 3* (OpenCL 1.2, Win 10 64 bit, Sept 2018) 31 | * AMD A10-8700P Radeon R6, 10 Compute Cores 4C+6G* (OpenCL 1.2, Win 10 64 bit, Feb 2018) 32 | * Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz* (OpenCL 1.2, macOS 10.12.6, Feb 2018) 33 | * Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz* (OpenCL 1.2, Win 10 64 bit, Mar 2018) 34 | * Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz* (OpenCL 2.0, Fedora 27, Apr 2018) 35 | 36 | * These CPU devices are accompanied by built-in GPUs which were tested successfully using CLIJ. 37 | 38 | 39 | [Back to CLIJ documentation](https://clij.github.io/) 40 | 41 | [Imprint](https://clij.github.io/imprint) 42 | -------------------------------------------------------------------------------- /troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | ## Big Images on NVidia graphics cards 3 | Errors may pop up when processing big images on NVidia cards on Windows (CL_INVALID_COMMAND_QUEUE, CL_INVALID_PROGRAM_EXECUTABLE, CL_MEM_OBJECT_ALLOCATION_FAILURE): The issue is related to a timeout of the operating system interrupting processing on the GPU. Add these keys to the windows registry and restart the machine (warning, don't do this if you're not sure. Ask you IT department for support. [Read the BSD3 license file](license.txt) for details on what why we're not responsible for your actions on your computer ): 4 | ``` 5 | [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers] 6 | "TdrDelay"=dword:0000003c 7 | "TdrDdiDelay"=dword:0000003c 8 | ``` 9 | Here is more information about what TDR is: https://docs.microsoft.com/en-us/windows-hardware/drivers/display/tdr-registry-keys 10 | 11 | ## Big Images on AMD graphics cards 12 | Similar to NVidia drives (see above), issues may appear due to a timeout when processing large images. The issue is related to a timeout of the operating system interrupting processing on the GPU. Add these keys to the windows registry and restart the machine (warning, don't do this if you're not sure. Ask you IT department for support. [Read the BSD3 license file](license.txt) for details on what why we're not responsible for your actions on your computer ). Similar to the solution above, enter a new key in the registry of Windows in this path 13 | ``` 14 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers 15 | ``` 16 | The key should be called `TdrDelay` and have a value of 8. 17 | 18 | Sources: 19 | https://community.amd.com/thread/180166 20 | https://support.microsoft.com/en-us/help/2665946/display-driver-stopped-responding-and-has-recovered-error-in-windows-7 21 | 22 | ## Initialisation fails 23 | Fiji crashes when calling the first CLIJ filter: Check if the initialisation contains a proper name for a GPU. 24 | 25 | ## Repeated initialisation fails on AMD Vega 10 26 | When creating CLIJ instances and closing them repeatedly, it crashes after about 40 attempts. [This test](https://github.com/clij/clij-core/blob/master/src/test/java/net/haesleinhuepf/clij/test/InitialisationTest.java#L17) allows reproducing the issue on specified hardward. Workaround: 27 | Don't close the CLIJ instance and keep working with the singleton instance. 28 | ## Result image is black or shows random textures 29 | This might happend with older GPUs which have not been tested. A helpful workaround is converting all images to 32 bit using `run("32-bit");` before sending them to the GPU. 30 | ## filename.cl not found 31 | "java.io.IOException: Cannot find source: [Object] " exception: Navigate to the jars subdirectory of your Fiji installation and locate `clearcl.jar` files, e.g. by typing `dir clearcl*` or `ls clearcl*`. If there are several versions installed, remove the older one. In order to fix this exception, you need at least `clearcl-0.5.5-RH.jar`. 32 | ## Problem while setting argument 33 | "clearcl.exceptions.ClearCLException: problem while setting argument 'parameter_of_type_float'": To hand over parameters of type float, you need to explicitly type it. Use `from java.lang import Float` and `Float(1.5)` to handover a value of 1.5 to an OpenCL parameter of type float. 34 | ## Class not found on Linux 35 | CLIJ doesn't start on Ubuntu linux with an error message that a class called ClearCLBackendJOCL cannot be initialized. Installing 'ocl-icd-opencl-dev' helped here. 36 | ## Exceptions on Linux 37 | CLIJ throws various exceptions, like CL_OUT_OF_HOST_MEMORY on Linux. Try installing an OpenCL-driver such as beignet. On Fedora 27 Linux, this command list helped: 38 | 39 | ``` 40 | sudo yum install ocl-icd-devel 41 | sudo yum install cmake 42 | sudo yum install llvm 43 | sudo yum install llvm-devel 44 | sudo yum install libdrm libdrm-devel 45 | sudo yum install libXext-devel 46 | sudo yum install libXfixes-devel 47 | sudo yum install clang-devel 48 | 49 | git clone https://github.com/intel/beignet.git 50 | cd beignet/ 51 | mkdir build 52 | cd build 53 | cmake ../ 54 | make 55 | sudo make install 56 | 57 | ``` 58 | More info can be found on the website of the [beignet project](https://www.freedesktop.org/wiki/Software/Beignet/). 59 | 60 | 61 | 62 | [Back to CLIJ documentation](https://clij.github.io/) 63 | 64 | [Imprint](https://clij.github.io/imprint) 65 | --------------------------------------------------------------------------------