GPU accelerated image processing for everyone
Authors: Robert Haase, Daniela Vorkel, April 2020
This macro demonstrates how to operate on spot images, pointlists, distance matrices and touch matrices in the GPU.
</pre>
// init GPU run("CLIJ2 Macro Extensions", "cl_device=[GeForce RTX 2060 SUPER]"); Ext.CLIJ2_clear(); run("Close All");
array = newArray( 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0); width = 5; height = 5; depth = 1; Ext.CLIJ2_pushArray(spots_image, array, width, height, depth); Ext.CLIJ2_pull(spots_image); zoom(100);
Ext.CLIJ2_spotsToPointList(spots_image, pointlist); Ext.CLIJ2_pull(pointlist); zoom(100);
Ext.CLIJ2_generateDistanceMatrix(pointlist, pointlist, distance_matrix); Ext.CLIJ2_pull(distance_matrix); zoom(100);
Ext.CLIJ2_labelSpots(spots_image, labelled_spots); Ext.CLIJ2_pull(labelled_spots); zoom(100); run("glasbey_on_dark");
Ext.CLIJ2_labelVoronoiOctagon(labelled_spots, label_voronoi); Ext.CLIJ2_pull(label_voronoi); zoom(100);
Ext.CLIJ2_generateTouchMatrix(label_voronoi, touch_matrix); Ext.CLIJ2_pull(touch_matrix); zoom(100);
Ext.CLIJ2_countTouchingNeighbors(touch_matrix, count_vector); Ext.CLIJ2_pull(count_vector); zoom(100);
run("Clear Results"); Ext.CLIJ2_statisticsOfLabelledPixels(spots_image, label_voronoi);
IDENTIFIER | BOUNDING_BOX_X | BOUNDING_BOX_Y | BOUNDING_BOX_Z | BOUNDING_BOX_END_X | BOUNDING_BOX_END_Y | BOUNDING_BOX_END_Z | BOUNDING_BOX_WIDTH | BOUNDING_BOX_HEIGHT | BOUNDING_BOX_DEPTH | MINIMUM_INTENSITY | MAXIMUM_INTENSITY | MEAN_INTENSITY | SUM_INTENSITY | STANDARD_DEVIATION_INTENSITY | PIXEL_COUNT | SUM_INTENSITY_TIMES_X | SUM_INTENSITY_TIMES_Y | SUM_INTENSITY_TIMES_Z | MASS_CENTER_X | MASS_CENTER_Y | MASS_CENTER_Z | SUM_X | SUM_Y | SUM_Z | CENTROID_X | CENTROID_Y | CENTROID_Z | SUM_DISTANCE_TO_MASS_CENTER | MEAN_DISTANCE_TO_MASS_CENTER | MAX_DISTANCE_TO_MASS_CENTER | MAX_MEAN_DISTANCE_TO_MASS_CENTER_RATIO | SUM_DISTANCE_TO_CENTROID | MEAN_DISTANCE_TO_CENTROID | MAX_DISTANCE_TO_CENTROID | MAX_MEAN_DISTANCE_TO_CENTROID_RATIO |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 2 | 1 | 0 | 2 | 2 | 1 | 0 | 1 | 0.333 | 1 | 0.471 | 3 | 2 | 1 | 0 | 2 | 1 | 0 | 5 | 1 | 0 | 1.667 | 0.333 | 0 | 2.414 | 0.805 | 1.414 | 1.757 | 1.962 | 0.654 | 0.745 | 1.140 |
2 | 3 | 0 | 0 | 4 | 1 | 0 | 2 | 2 | 1 | 0 | 1 | 0.250 | 1 | 0.433 | 4 | 4 | 1 | 0 | 4 | 1 | 0 | 14 | 2 | 0 | 3.500 | 0.500 | 0 | 3.414 | 0.854 | 1.414 | 1.657 | 2.828 | 0.707 | 0.707 | 1.000 |
3 | 0 | 0 | 0 | 1 | 2 | 0 | 2 | 3 | 1 | 0 | 1 | 0.200 | 1 | 0.400 | 5 | 1 | 2 | 0 | 1 | 2 | 0 | 2 | 6 | 0 | 0.400 | 1.200 | 0 | 5.650 | 1.130 | 2.236 | 1.979 | 4.239 | 0.848 | 1.265 | 1.492 |
4 | 2 | 2 | 0 | 4 | 4 | 0 | 3 | 3 | 1 | 0 | 1 | 0.111 | 1 | 0.314 | 9 | 3 | 3 | 0 | 3 | 3 | 0 | 27 | 27 | 0 | 3.000 | 3.000 | 0 | 9.657 | 1.073 | 1.414 | 1.318 | 9.657 | 1.073 | 1.414 | 1.318 |
5 | 0 | 3 | 0 | 1 | 4 | 0 | 2 | 2 | 1 | 0 | 1 | 0.250 | 1 | 0.433 | 4 | 0 | 4 | 0 | 0 | 4 | 0 | 2 | 14 | 0 | 0.500 | 3.500 | 0 | 3.414 | 0.854 | 1.414 | 1.657 | 2.828 | 0.707 | 0.707 | 1.000 |
Ext.CLIJ2_pushResultsTable(table_image); Ext.CLIJ2_pull(table_image); zoom(100);
Ext.CLIJ2_pushResultsTableColumn(mean_intensity_vector, "MEAN_INTENSITY"); Ext.CLIJ2_pull(mean_intensity_vector); zoom(100);
zoom_factor = 100; Ext.CLIJ2_multiplyImageAndScalar(pointlist, pointlist_multiplied, zoom_factor); Ext.CLIJ2_pull(pointlist_multiplied); zoom(100);
Ext.CLIJ2_create2D(mesh, width * zoom_factor, height * zoom_factor, 32); Ext.CLIJ2_touchMatrixToMesh(pointlist_multiplied, touch_matrix, mesh); Ext.CLIJ2_pull(mesh);
Ext.CLIJ2_create2D(mesh2, width * zoom_factor, height * zoom_factor, 32); Ext.CLIJ2_distanceMatrixToMesh(pointlist_multiplied, distance_matrix, mesh2, 2.5); Ext.CLIJ2_pull(mesh2);
At the end of the macro, clean up:
Ext.CLIJ2_clear();
This is just a useful function to get a nice visualization in the notebook:
function zoom(factor) { getDimensions(width, height, channels, slices, frames); before = getTitle(); run("Scale...", "x=" + factor + " y=" + factor + " width=" + (width * factor) + " height=" + (height* factor) + " interpolation=None average create"); selectWindow(before); close(); }