(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 | 
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 | 
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 | 
6 |
7 | Furthermore, CLIJ has its own menu: `Plugins > ImageJ on GPU (CLIJ)` with sub menus offering all CLIJ functionality.
8 | 
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 | 
12 |
13 | CLIJ is fully macro-recordable. After recording your workflow, it can be executed right away.
14 | 
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 |
--------------------------------------------------------------------------------