pyfast 4.12.0__cp36-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. fast/README.md +41 -0
  2. fast/__init__.py +22 -0
  3. fast/bin/UFFviewer +0 -0
  4. fast/bin/fast_configuration.txt +14 -0
  5. fast/bin/runPipeline +0 -0
  6. fast/bin/systemCheck +0 -0
  7. fast/doc/bright-plotting-style.ini +66 -0
  8. fast/doc/dark-plotting-style.ini +66 -0
  9. fast/doc/fonts/UFL.txt +96 -0
  10. fast/doc/fonts/Ubuntu-Bold.ttf +0 -0
  11. fast/doc/fonts/Ubuntu-BoldItalic.ttf +0 -0
  12. fast/doc/fonts/Ubuntu-Italic.ttf +0 -0
  13. fast/doc/fonts/Ubuntu-Light.ttf +0 -0
  14. fast/doc/fonts/Ubuntu-LightItalic.ttf +0 -0
  15. fast/doc/fonts/Ubuntu-Medium.ttf +0 -0
  16. fast/doc/fonts/Ubuntu-MediumItalic.ttf +0 -0
  17. fast/doc/fonts/Ubuntu-Regular.ttf +0 -0
  18. fast/doc/fonts/UbuntuMono-Bold.ttf +0 -0
  19. fast/doc/fonts/UbuntuMono-BoldItalic.ttf +0 -0
  20. fast/doc/fonts/UbuntuMono-Italic.ttf +0 -0
  21. fast/doc/fonts/UbuntuMono-Regular.ttf +0 -0
  22. fast/doc/images/FAST_logo_square.png +0 -0
  23. fast/doc/images/fast_icon.ico +0 -0
  24. fast/doc/images/fast_icon.png +0 -0
  25. fast/entry_points.py +14 -0
  26. fast/fast.py +19833 -0
  27. fast/kernels/Algorithms/AirwaySegmentation/AirwaySegmentation.cl +85 -0
  28. fast/kernels/Algorithms/ApplyColormap/ApplyColormap.cl +146 -0
  29. fast/kernels/Algorithms/BinaryThresholding/BinaryThresholding2D.cl +61 -0
  30. fast/kernels/Algorithms/BinaryThresholding/BinaryThresholding3D.cl +61 -0
  31. fast/kernels/Algorithms/BlockMatching/BlockMatching.cl +257 -0
  32. fast/kernels/Algorithms/CenterlineExtraction/CenterlineExtraction.cl +153 -0
  33. fast/kernels/Algorithms/CoherentPointDrift/CoherentPointDrift.cl +0 -0
  34. fast/kernels/Algorithms/Color/ColorToGrayscale.cl +22 -0
  35. fast/kernels/Algorithms/Color/GrayscaleToColor.cl +19 -0
  36. fast/kernels/Algorithms/GaussianSmoothing/GaussianSmoothing2D.cl +35 -0
  37. fast/kernels/Algorithms/GaussianSmoothing/GaussianSmoothing3D.cl +75 -0
  38. fast/kernels/Algorithms/GradientVectorFlow/EulerGradientVectorFlow.cl +174 -0
  39. fast/kernels/Algorithms/GradientVectorFlow/MultigridGradientVectorFlow.cl +407 -0
  40. fast/kernels/Algorithms/HounsefieldConverter/HounsefieldConverter.cl +22 -0
  41. fast/kernels/Algorithms/ImageAdd/ImageAdd.cl +79 -0
  42. fast/kernels/Algorithms/ImageCaster/ImageCaster.cl +38 -0
  43. fast/kernels/Algorithms/ImageChannelConverter/ImageChannelConverter.cl +121 -0
  44. fast/kernels/Algorithms/ImageFlipper/ImageFlipper2D.cl +23 -0
  45. fast/kernels/Algorithms/ImageFlipper/ImageFlipper3D.cl +51 -0
  46. fast/kernels/Algorithms/ImageGradient/ImageGradient.cl +71 -0
  47. fast/kernels/Algorithms/ImageInverter/ImageInverter.cl +30 -0
  48. fast/kernels/Algorithms/ImageMultiply/ImageMultiply.cl +79 -0
  49. fast/kernels/Algorithms/ImagePatch/PatchStitcher2D.cl +22 -0
  50. fast/kernels/Algorithms/ImagePatch/PatchStitcher3D.cl +95 -0
  51. fast/kernels/Algorithms/ImageResampler/ImageResampler2D.cl +40 -0
  52. fast/kernels/Algorithms/ImageResampler/ImageResampler3D.cl +32 -0
  53. fast/kernels/Algorithms/ImageResizer/ImageResizer.cl +134 -0
  54. fast/kernels/Algorithms/ImageSharpening/ImageSharpening.cl +47 -0
  55. fast/kernels/Algorithms/ImageSlicer/ImageSlicer.cl +77 -0
  56. fast/kernels/Algorithms/ImageTransposer/ImageTransposer2D.cl +16 -0
  57. fast/kernels/Algorithms/ImageTransposer/ImageTransposer3D.cl +45 -0
  58. fast/kernels/Algorithms/IntensityClipping/IntensityClipping2D.cl +19 -0
  59. fast/kernels/Algorithms/IntensityClipping/IntensityClipping3D.cl +20 -0
  60. fast/kernels/Algorithms/IntensityNormalization/IntensityNormalization.cl +85 -0
  61. fast/kernels/Algorithms/IntensityNormalization/ZeroMeanUnitVariance.cl +76 -0
  62. fast/kernels/Algorithms/KalmanFilterModelSegmentation/AppearanceModels/RidgeEdge/RidgeEdgeModel.cl +81 -0
  63. fast/kernels/Algorithms/LabelModifier/LabelModifier.cl +20 -0
  64. fast/kernels/Algorithms/LaplacianOfGaussian/LaplacianOfGaussian2D.cl +27 -0
  65. fast/kernels/Algorithms/LevelSet/LevelSetSegmentation.cl +132 -0
  66. fast/kernels/Algorithms/LungSegmentation/LungSegmentation.cl +22 -0
  67. fast/kernels/Algorithms/MeshToSegmentation/MeshToSegmentation.cl +184 -0
  68. fast/kernels/Algorithms/Morphology/Dilation.cl +56 -0
  69. fast/kernels/Algorithms/Morphology/Erosion.cl +64 -0
  70. fast/kernels/Algorithms/NeuralNetwork/NeuralNetwork.cl +122 -0
  71. fast/kernels/Algorithms/NeuralNetwork/VertexTensorToSegmentation.cl +13 -0
  72. fast/kernels/Algorithms/NonLocalMeans/NonLocalMeans2D.cl +94 -0
  73. fast/kernels/Algorithms/SeededRegionGrowing/SeededRegionGrowing2D.cl +57 -0
  74. fast/kernels/Algorithms/SeededRegionGrowing/SeededRegionGrowing3D.cl +58 -0
  75. fast/kernels/Algorithms/Skeletonization/Skeletonization2D.cl +77 -0
  76. fast/kernels/Algorithms/SurfaceExtraction/SurfaceExtraction.cl +519 -0
  77. fast/kernels/Algorithms/SurfaceExtraction/SurfaceExtraction_no_3d_write.cl +739 -0
  78. fast/kernels/Algorithms/TemporalSmoothing/ImageMovingAverage.cl +66 -0
  79. fast/kernels/Algorithms/TemporalSmoothing/ImageWeightedMovingAverage.cl +74 -0
  80. fast/kernels/Algorithms/TissueSegmentation/TissueSegmentation.cl +18 -0
  81. fast/kernels/Algorithms/TubeSegmentationAndCenterlineExtraction/InverseGradientSegmentation.cl +203 -0
  82. fast/kernels/Algorithms/TubeSegmentationAndCenterlineExtraction/TubeSegmentationAndCenterlineExtraction.cl +566 -0
  83. fast/kernels/Algorithms/Ultrasound/EnvelopeAndLogCompressor.cl +45 -0
  84. fast/kernels/Algorithms/Ultrasound/ScanConverter.cl +76 -0
  85. fast/kernels/Algorithms/UltrasoundImageCropper/UltrasoundImageCropper.cl +31 -0
  86. fast/kernels/Algorithms/UltrasoundImageEnhancement/UltrasoundImageEnhancement.cl +27 -0
  87. fast/kernels/Algorithms/VectorMedianFilter/VectorMedianFilter.cl +31 -0
  88. fast/kernels/ImageFill.cl +30 -0
  89. fast/kernels/ImageMinMax.cl +196 -0
  90. fast/kernels/ImageSum.cl +170 -0
  91. fast/kernels/Tests/Algorithms/DoubleFilter.cl +7 -0
  92. fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.frag +8 -0
  93. fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.geom +69 -0
  94. fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.vert +17 -0
  95. fast/kernels/Visualization/HeatmapRenderer/HeatmapRenderer.cl +51 -0
  96. fast/kernels/Visualization/ImagePyramidRenderer/ImagePyramidRenderer.frag +11 -0
  97. fast/kernels/Visualization/ImagePyramidRenderer/ImagePyramidRenderer.vert +15 -0
  98. fast/kernels/Visualization/ImageRenderer/ImageRenderer.vert +15 -0
  99. fast/kernels/Visualization/ImageRenderer/ImageRendererFLOAT.frag +18 -0
  100. fast/kernels/Visualization/ImageRenderer/ImageRendererINT.frag +18 -0
  101. fast/kernels/Visualization/ImageRenderer/ImageRendererUINT.frag +18 -0
  102. fast/kernels/Visualization/LineRenderer/LineRenderer.frag +8 -0
  103. fast/kernels/Visualization/LineRenderer/LineRenderer.geom +35 -0
  104. fast/kernels/Visualization/LineRenderer/LineRenderer.vert +20 -0
  105. fast/kernels/Visualization/LineRenderer/LineRenderer3D.frag +8 -0
  106. fast/kernels/Visualization/LineRenderer/LineRenderer3D.vert +20 -0
  107. fast/kernels/Visualization/LineRenderer/LineRendererJoints.frag +15 -0
  108. fast/kernels/Visualization/LineRenderer/LineRendererJoints.vert +24 -0
  109. fast/kernels/Visualization/SegmentationLabelRenderer/SegmentationLabelRenderer.frag +11 -0
  110. fast/kernels/Visualization/SegmentationLabelRenderer/SegmentationLabelRenderer.vert +16 -0
  111. fast/kernels/Visualization/SegmentationRenderer/SegmentationPyramidRenderer.frag +53 -0
  112. fast/kernels/Visualization/SegmentationRenderer/SegmentationRenderer.frag +52 -0
  113. fast/kernels/Visualization/SegmentationRenderer/SegmentationRenderer.vert +15 -0
  114. fast/kernels/Visualization/TextRenderer/TextRenderer.frag +11 -0
  115. fast/kernels/Visualization/TextRenderer/TextRenderer.vert +20 -0
  116. fast/kernels/Visualization/TriangleRenderer/TriangleRenderer.frag +49 -0
  117. fast/kernels/Visualization/TriangleRenderer/TriangleRenderer.vert +35 -0
  118. fast/kernels/Visualization/VectorFieldRenderer/VectorFieldColorRenderer.cl +30 -0
  119. fast/kernels/Visualization/VertexRenderer/VertexRenderer.frag +14 -0
  120. fast/kernels/Visualization/VertexRenderer/VertexRenderer.vert +23 -0
  121. fast/kernels/Visualization/View.cl +10 -0
  122. fast/kernels/Visualization/VolumeRenderer/AlphaBlendingVolumeRenderer.cl +211 -0
  123. fast/kernels/Visualization/VolumeRenderer/MaximumIntensityProjection.cl +139 -0
  124. fast/kernels/Visualization/VolumeRenderer/ThresholdVolumeRenderer.cl +178 -0
  125. fast/lib/_fast.abi3.so +0 -0
  126. fast/lib/libFAST.4.dylib +0 -0
  127. fast/lib/libInferenceEngineONNXRuntime.dylib +0 -0
  128. fast/lib/libJKQTCommonSharedLib_Release.4.0.0.dylib +0 -0
  129. fast/lib/libJKQTFastPlotterSharedLib_Release.4.0.0.dylib +0 -0
  130. fast/lib/libJKQTMathTextSharedLib_Release.4.0.0.dylib +0 -0
  131. fast/lib/libJKQTPlotterSharedLib_Release.4.0.0.dylib +0 -0
  132. fast/lib/libOpenIGTLink.3.dylib +0 -0
  133. fast/lib/libQt5Core.5.dylib +0 -0
  134. fast/lib/libQt5DBus.5.dylib +0 -0
  135. fast/lib/libQt5Gui.5.dylib +0 -0
  136. fast/lib/libQt5Multimedia.5.dylib +0 -0
  137. fast/lib/libQt5MultimediaWidgets.5.dylib +0 -0
  138. fast/lib/libQt5Network.5.dylib +0 -0
  139. fast/lib/libQt5OpenGL.5.dylib +0 -0
  140. fast/lib/libQt5PrintSupport.5.dylib +0 -0
  141. fast/lib/libQt5SerialPort.5.dylib +0 -0
  142. fast/lib/libQt5Svg.5.dylib +0 -0
  143. fast/lib/libQt5Widgets.5.dylib +0 -0
  144. fast/lib/libQt5Xml.5.dylib +0 -0
  145. fast/lib/libbrotlicommon.1.dylib +0 -0
  146. fast/lib/libbrotlidec.1.dylib +0 -0
  147. fast/lib/libbrotlienc.1.dylib +0 -0
  148. fast/lib/libdcmdata.17.dylib +0 -0
  149. fast/lib/libdcmimage.17.dylib +0 -0
  150. fast/lib/libdcmimgle.17.dylib +0 -0
  151. fast/lib/libdcmjpeg.17.dylib +0 -0
  152. fast/lib/libijg12.17.dylib +0 -0
  153. fast/lib/libijg12.dylib +0 -0
  154. fast/lib/libijg16.17.dylib +0 -0
  155. fast/lib/libijg16.dylib +0 -0
  156. fast/lib/libijg8.17.dylib +0 -0
  157. fast/lib/libijg8.dylib +0 -0
  158. fast/lib/libjxl.0.11.dylib +0 -0
  159. fast/lib/libjxl_cms.0.11.dylib +0 -0
  160. fast/lib/libjxl_threads.0.11.dylib +0 -0
  161. fast/lib/liboflog.17.dylib +0 -0
  162. fast/lib/libofstd.17.dylib +0 -0
  163. fast/lib/libonnxruntime.1.22.0.dylib +0 -0
  164. fast/lib/libonnxruntime.dylib +0 -0
  165. fast/lib/libopenslide.1.dylib +0 -0
  166. fast/lib/libz.1.dylib +0 -0
  167. fast/licenses/OpenIGTLink/LICENSE.txt +30 -0
  168. fast/licenses/OpenJPEG/LICENSE +39 -0
  169. fast/licenses/OpenSlide/COPYING.LESSER +504 -0
  170. fast/licenses/PCRE2/LICENCE.md +103 -0
  171. fast/licenses/cairo/COPYING +33 -0
  172. fast/licenses/cairo/COPYING-LGPL-2.1 +510 -0
  173. fast/licenses/cairo/COPYING-MPL-1.1 +470 -0
  174. fast/licenses/dcmtk/COPYRIGHT +1034 -0
  175. fast/licenses/eigen/COPYING.APACHE +203 -0
  176. fast/licenses/eigen/COPYING.BSD +26 -0
  177. fast/licenses/eigen/COPYING.GPL +674 -0
  178. fast/licenses/eigen/COPYING.LGPL +502 -0
  179. fast/licenses/eigen/COPYING.MINPACK +51 -0
  180. fast/licenses/eigen/COPYING.MPL2 +373 -0
  181. fast/licenses/eigen/COPYING.README +18 -0
  182. fast/licenses/fast/LICENSE +25 -0
  183. fast/licenses/gdk-pixbuf/COPYING +502 -0
  184. fast/licenses/glib/COPYING +175 -0
  185. fast/licenses/hdf5/COPYING +106 -0
  186. fast/licenses/jkqtplotter/LICENSE +505 -0
  187. fast/licenses/jpegxl/LICENSE.brotli +19 -0
  188. fast/licenses/jpegxl/LICENSE.highway +201 -0
  189. fast/licenses/jpegxl/LICENSE.jpeg-xl +27 -0
  190. fast/licenses/jpegxl/LICENSE.skcms +29 -0
  191. fast/licenses/jpegxl/PATENTS +22 -0
  192. fast/licenses/libdicom/LICENSE +21 -0
  193. fast/licenses/libjpeg-turbo/LICENSE.md +135 -0
  194. fast/licenses/libjpeg-turbo/README.ijg +260 -0
  195. fast/licenses/libpng/LICENSE +134 -0
  196. fast/licenses/libtiff/LICENSE.md +23 -0
  197. fast/licenses/onnxruntime/LICENSE +21 -0
  198. fast/licenses/onnxruntime/Privacy.md +21 -0
  199. fast/licenses/onnxruntime/ThirdPartyNotices.txt +6156 -0
  200. fast/licenses/opencl/LICENSE +201 -0
  201. fast/licenses/pixman/COPYING +42 -0
  202. fast/licenses/proxy-libintl/COPYING +482 -0
  203. fast/licenses/qt5/LICENSE.FDL +450 -0
  204. fast/licenses/qt5/LICENSE.GPL3-EXCEPT +704 -0
  205. fast/licenses/qt5/LICENSE.GPLv2 +292 -0
  206. fast/licenses/qt5/LICENSE.GPLv3 +686 -0
  207. fast/licenses/qt5/LICENSE.LGPLv21 +514 -0
  208. fast/licenses/qt5/LICENSE.LGPLv3 +175 -0
  209. fast/licenses/qt5/LICENSE.QT-LICENSE-AGREEMENT +1315 -0
  210. fast/licenses/semaphore/Semaphore_LICENSE.txt +17 -0
  211. fast/licenses/uthash/LICENSE +21 -0
  212. fast/licenses/zip/UNLICENSE +26 -0
  213. fast/licenses/zlib/README +115 -0
  214. fast/licenses/zlib-ng/LICENSE.md +19 -0
  215. fast/pipelines/uff_viewer/colormap_and_reject.fpl +26 -0
  216. fast/pipelines/uff_viewer/default.fpl +9 -0
  217. fast/pipelines/uff_viewer/non_local_means.fpl +34 -0
  218. fast/plugins/audio/libqtaudio_coreaudio.dylib +0 -0
  219. fast/plugins/bearer/libqgenericbearer.dylib +0 -0
  220. fast/plugins/generic/libqtuiotouchplugin.dylib +0 -0
  221. fast/plugins/iconengines/libqsvgicon.dylib +0 -0
  222. fast/plugins/imageformats/libqgif.dylib +0 -0
  223. fast/plugins/imageformats/libqicns.dylib +0 -0
  224. fast/plugins/imageformats/libqico.dylib +0 -0
  225. fast/plugins/imageformats/libqjpeg.dylib +0 -0
  226. fast/plugins/imageformats/libqmacheif.dylib +0 -0
  227. fast/plugins/imageformats/libqmacjp2.dylib +0 -0
  228. fast/plugins/imageformats/libqsvg.dylib +0 -0
  229. fast/plugins/imageformats/libqtga.dylib +0 -0
  230. fast/plugins/imageformats/libqtiff.dylib +0 -0
  231. fast/plugins/imageformats/libqwbmp.dylib +0 -0
  232. fast/plugins/imageformats/libqwebp.dylib +0 -0
  233. fast/plugins/mediaservice/libqavfcamera.dylib +0 -0
  234. fast/plugins/mediaservice/libqavfmediaplayer.dylib +0 -0
  235. fast/plugins/mediaservice/libqtmedia_audioengine.dylib +0 -0
  236. fast/plugins/platforms/libqcocoa.dylib +0 -0
  237. fast/plugins/platforms/libqminimal.dylib +0 -0
  238. fast/plugins/platforms/libqoffscreen.dylib +0 -0
  239. fast/plugins/platformthemes/libqxdgdesktopportal.dylib +0 -0
  240. fast/plugins/playlistformats/libqtmultimedia_m3u.dylib +0 -0
  241. fast/plugins/printsupport/libcocoaprintersupport.dylib +0 -0
  242. fast/plugins/sqldrivers/libqsqlite.dylib +0 -0
  243. fast/plugins/styles/libqmacstyle.dylib +0 -0
  244. pyfast-4.12.0.dist-info/METADATA +81 -0
  245. pyfast-4.12.0.dist-info/RECORD +248 -0
  246. pyfast-4.12.0.dist-info/WHEEL +5 -0
  247. pyfast-4.12.0.dist-info/entry_points.txt +5 -0
  248. pyfast-4.12.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,85 @@
1
+ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
2
+ __constant sampler_t sampler2 = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
3
+
4
+ #define LPOS(pos) pos.x+pos.y*get_global_size(0)+pos.z*get_global_size(0)*get_global_size(1)
5
+
6
+ __kernel void convertToHU(
7
+ __read_only image3d_t input,
8
+ #ifdef fast_3d_image_writes
9
+ __write_only image3d_t output
10
+ #else
11
+ __global short* output
12
+ #endif
13
+ ) {
14
+ const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
15
+
16
+ int value = read_imageui(input, sampler, pos).x;
17
+ value -= 1024;
18
+ #ifdef fast_3d_image_writes
19
+ write_imagei(output, pos, value);
20
+ #else
21
+ output[LPOS(pos)] = value;
22
+ #endif
23
+ }
24
+
25
+ __kernel void dilate(
26
+ __read_only image3d_t volume,
27
+ #ifdef fast_3d_image_writes
28
+ __write_only image3d_t result
29
+ #else
30
+ __global uchar * result
31
+ #endif
32
+ ) {
33
+ int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
34
+
35
+ if(read_imageui(volume, sampler, pos).x == 1) {
36
+ const int N = 2;
37
+ for(int a = -N; a <= N; ++a) {
38
+ for(int b = -N; b <= N; ++b) {
39
+ for(int c = -N; c <= N; ++c) {
40
+ int4 nPos = pos + (int4)(a,b,c,0);
41
+ #ifdef fast_3d_image_writes
42
+ write_imageui(result, nPos, 1);
43
+ #else
44
+ // Check if in bounds
45
+ if(nPos.x >= 0 && nPos.y >= 0 && nPos.z >= 0 &&
46
+ nPos.x < get_global_size(0) && nPos.y < get_global_size(1) && nPos.z < get_global_size(2))
47
+ result[LPOS(nPos)] = 1;
48
+ #endif
49
+ }}}
50
+ }
51
+
52
+ }
53
+
54
+ __kernel void erode(
55
+ __read_only image3d_t volume,
56
+ #ifdef fast_3d_image_writes
57
+ __write_only image3d_t result
58
+ #else
59
+ __global uchar * result
60
+ #endif
61
+ ) {
62
+ int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
63
+
64
+ int value = read_imageui(volume, sampler, pos).x;
65
+ if(value == 1) {
66
+ bool keep = true;
67
+ const int N = 2;
68
+ // Check if all pixels in neighborhood is 1
69
+ for(int a = -N; a <= N; ++a) {
70
+ for(int b = -N; b <= N; ++b) {
71
+ for(int c = -N; c <= N; ++c) {
72
+ keep = (read_imageui(volume, sampler2, pos + (int4)(a,b,c,0)).x == 1 && keep);
73
+ }}}
74
+ #ifdef fast_3d_image_writes
75
+ write_imageui(result, pos, keep ? 1 : 0);
76
+ } else {
77
+ write_imageui(result, pos, 0);
78
+ }
79
+ #else
80
+ result[LPOS(pos)] = keep ? 1 : 0;
81
+ } else {
82
+ result[LPOS(pos)] = 0;
83
+ }
84
+ #endif
85
+ }
@@ -0,0 +1,146 @@
1
+ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
2
+
3
+ float4 readImageAsFloat2D(__read_only image2d_t image, sampler_t sampler, int2 position) {
4
+ int dataType = get_image_channel_data_type(image);
5
+ if(dataType == CLK_FLOAT || dataType == CLK_SNORM_INT16 || dataType == CLK_UNORM_INT16) {
6
+ return read_imagef(image, sampler, position);
7
+ } else if(dataType == CLK_SIGNED_INT8 || dataType == CLK_SIGNED_INT16 || dataType == CLK_SIGNED_INT32) {
8
+ return convert_float4(read_imagei(image, sampler, position));
9
+ } else {
10
+ return convert_float4(read_imageui(image, sampler, position));
11
+ }
12
+ }
13
+
14
+
15
+ void writeImageAsFloat42D(__write_only image2d_t image, int2 position, float4 value) {
16
+ int dataType = get_image_channel_data_type(image);
17
+ if(dataType == CLK_FLOAT || dataType == CLK_SNORM_INT16 || dataType == CLK_UNORM_INT16) {
18
+ write_imagef(image, position, value);
19
+ } else if(dataType == CLK_SIGNED_INT8 || dataType == CLK_SIGNED_INT16 || dataType == CLK_SIGNED_INT32) {
20
+ write_imagei(image, position, convert_int4(round(value)));
21
+ } else {
22
+ write_imageui(image, position, convert_uint4(round(value)));
23
+ }
24
+ }
25
+
26
+
27
+ void writeImageAsFloat2D(__write_only image2d_t image, int2 position, float value) {
28
+ int dataType = get_image_channel_data_type(image);
29
+ if(dataType == CLK_FLOAT || dataType == CLK_SNORM_INT16 || dataType == CLK_UNORM_INT16) {
30
+ write_imagef(image, position, value);
31
+ } else if(dataType == CLK_SIGNED_INT8 || dataType == CLK_SIGNED_INT16 || dataType == CLK_SIGNED_INT32) {
32
+ write_imagei(image, position, convert_int4(round(value)));
33
+ } else {
34
+ write_imageui(image, position, convert_uint4(round(value)));
35
+ }
36
+ }
37
+
38
+ float4 vload4_at_pos(int position, __constant float* data) {
39
+ return (float4)(data[position], data[position+1], data[position+2], 1.0f);
40
+ }
41
+
42
+ float4 vload4_at_pos_opacity(int position, __constant float* data) {
43
+ return (float4)(data[position], data[position+1], data[position+2], data[position+3]);
44
+ }
45
+
46
+ float getIntensityFromColormap(float intensity, __constant float* colormap, int steps, char interpolate) {
47
+ float first = colormap[1];
48
+ float firstIntensity = colormap[0];
49
+
50
+ if(intensity <= firstIntensity)
51
+ return first;
52
+
53
+ for(int i = 1; i < steps; ++i) {
54
+ float second = colormap[i*2+1];
55
+ float secondIntensity = colormap[i*2];
56
+ if(intensity <= secondIntensity) {
57
+ if(interpolate == 1) {
58
+ return mix(first, second, (intensity - firstIntensity)/(secondIntensity - firstIntensity));
59
+ } else {
60
+ // Nearest
61
+ if(intensity - firstIntensity < secondIntensity - intensity) {
62
+ return first;
63
+ } else {
64
+ return second;
65
+ }
66
+ }
67
+ }
68
+ first = second;
69
+ firstIntensity = secondIntensity;
70
+ }
71
+ return first;
72
+ }
73
+
74
+ float4 getColorFromColormap(float intensity, __constant float* colormap, int steps, char interpolate, char hasOpacity) {
75
+ float4 first;
76
+ if(hasOpacity == 1) {
77
+ first = vload4_at_pos_opacity(1, colormap);
78
+ } else {
79
+ first = vload4_at_pos(1, colormap);
80
+ }
81
+ float firstIntensity = colormap[0];
82
+
83
+ int values = 4;
84
+ if(hasOpacity == 1)
85
+ values = 5;
86
+
87
+ if(intensity <= firstIntensity)
88
+ return first;
89
+
90
+ for(int i = 1; i < steps; ++i) {
91
+ float4 second;
92
+ if(hasOpacity == 1) {
93
+ second = vload4_at_pos_opacity(i*values + 1, colormap);
94
+ } else {
95
+ second = vload4_at_pos(i*values + 1, colormap);
96
+ }
97
+ float secondIntensity = colormap[i*values];
98
+ if(intensity <= secondIntensity) {
99
+ if(interpolate == 1) {
100
+ return mix(first, second, (intensity - firstIntensity)/(secondIntensity - firstIntensity));
101
+ } else {
102
+ // Nearest
103
+ if(intensity - firstIntensity < secondIntensity - intensity) {
104
+ return first;
105
+ } else {
106
+ return second;
107
+ }
108
+ }
109
+ }
110
+ first = second;
111
+ firstIntensity = secondIntensity;
112
+ }
113
+ return first;
114
+ }
115
+
116
+ __kernel void applyColormap(
117
+ __read_only image2d_t input,
118
+ __write_only image2d_t output,
119
+ __constant float* colormap,
120
+ __private int steps,
121
+ __private char interpolate,
122
+ __private char grayscale,
123
+ __private char hasOpacity,
124
+ __private char isIntensityInvariant,
125
+ __private char isDiverging,
126
+ __private float minValue,
127
+ __private float maxValue
128
+ ) {
129
+ const int2 pos = {get_global_id(0), get_global_id(1)};
130
+
131
+ float4 value = readImageAsFloat2D(input, sampler, pos);
132
+
133
+ if(isIntensityInvariant == 1) {
134
+ if(isDiverging == 1) {
135
+ value.x = clamp(value.x / max(fabs(minValue), fabs(maxValue)), -1.0f, 1.0f);
136
+ } else {
137
+ value.x = clamp((value.x - minValue) / (maxValue - minValue), 0.0f, 1.0f);
138
+ }
139
+ }
140
+
141
+ if(grayscale == 1) {
142
+ writeImageAsFloat2D(output, pos, getIntensityFromColormap(value.x, colormap, steps, interpolate));
143
+ } else {
144
+ writeImageAsFloat42D(output, pos, getColorFromColormap(value.x, colormap, steps, interpolate, hasOpacity));
145
+ }
146
+ }
@@ -0,0 +1,61 @@
1
+ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
2
+
3
+ float getIntensity(__read_only image2d_t image, int2 pos) {
4
+ float value;
5
+ int dataType = get_image_channel_data_type(image);
6
+ if(dataType == CLK_FLOAT) {
7
+ value = read_imagef(image, sampler, pos).x;
8
+ } else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {
9
+ value = read_imageui(image, sampler, pos).x;
10
+ } else {
11
+ value = read_imagei(image, sampler, pos).x;
12
+ }
13
+ return value;
14
+ }
15
+
16
+ __kernel void thresholding(
17
+ __read_only image2d_t image,
18
+ __write_only image2d_t segmentation,
19
+ __private float lowerThreshold,
20
+ __private float upperThreshold
21
+ ) {
22
+ const int2 pos = {get_global_id(0), get_global_id(1)};
23
+
24
+ const float value = getIntensity(image, pos);
25
+
26
+ uchar writeValue = 0;
27
+ if(value >= lowerThreshold && value <= upperThreshold) {
28
+ writeValue = 1;
29
+ }
30
+ write_imageui(segmentation, pos, writeValue);
31
+ }
32
+ __kernel void thresholdingWithOnlyLower(
33
+ __read_only image2d_t image,
34
+ __write_only image2d_t segmentation,
35
+ __private float lowerThreshold
36
+ ) {
37
+ const int2 pos = {get_global_id(0), get_global_id(1)};
38
+
39
+ const float value = getIntensity(image, pos);
40
+
41
+ uchar writeValue = 0;
42
+ if(value >= lowerThreshold) {
43
+ writeValue = 1;
44
+ }
45
+ write_imageui(segmentation, pos, writeValue);
46
+ }
47
+ __kernel void thresholdingWithOnlyUpper(
48
+ __read_only image2d_t image,
49
+ __write_only image2d_t segmentation,
50
+ __private float upperThreshold
51
+ ) {
52
+ const int2 pos = {get_global_id(0), get_global_id(1)};
53
+
54
+ const float value = getIntensity(image, pos);
55
+
56
+ uchar writeValue = 0;
57
+ if(value <= upperThreshold) {
58
+ writeValue = 1;
59
+ }
60
+ write_imageui(segmentation, pos, writeValue);
61
+ }
@@ -0,0 +1,61 @@
1
+ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
2
+
3
+ float getIntensity(__read_only image3d_t image, int4 pos) {
4
+ float value;
5
+ int dataType = get_image_channel_data_type(image);
6
+ if(dataType == CLK_FLOAT) {
7
+ value = read_imagef(image, sampler, pos).x;
8
+ } else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {
9
+ value = read_imageui(image, sampler, pos).x;
10
+ } else {
11
+ value = read_imagei(image, sampler, pos).x;
12
+ }
13
+ return value;
14
+ }
15
+
16
+ __kernel void thresholding(
17
+ __read_only image3d_t image,
18
+ __write_only image3d_t segmentation,
19
+ __private float lowerThreshold,
20
+ __private float upperThreshold
21
+ ) {
22
+ const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
23
+
24
+ const float value = getIntensity(image, pos);
25
+
26
+ uchar writeValue = 0;
27
+ if(value >= lowerThreshold && value <= upperThreshold) {
28
+ writeValue = 1;
29
+ }
30
+ write_imageui(segmentation, pos, writeValue);
31
+ }
32
+ __kernel void thresholdingWithOnlyLower(
33
+ __read_only image3d_t image,
34
+ __write_only image3d_t segmentation,
35
+ __private float lowerThreshold
36
+ ) {
37
+ const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
38
+
39
+ const float value = getIntensity(image, pos);
40
+
41
+ uchar writeValue = 0;
42
+ if(value >= lowerThreshold) {
43
+ writeValue = 1;
44
+ }
45
+ write_imageui(segmentation, pos, writeValue);
46
+ }
47
+ __kernel void thresholdingWithOnlyUpper(
48
+ __read_only image3d_t image,
49
+ __write_only image3d_t segmentation,
50
+ __private float upperThreshold
51
+ ) {
52
+ const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
53
+
54
+ const float value = getIntensity(image, pos);
55
+
56
+ uchar writeValue = 0;
57
+ if(value <= upperThreshold) {
58
+ writeValue = 1;
59
+ }
60
+ write_imageui(segmentation, pos, writeValue);
61
+ }
@@ -0,0 +1,257 @@
1
+ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
2
+
3
+ float getPixelAsFloat(__read_only image2d_t image, int2 pos) {
4
+ float value;
5
+ int dataType = get_image_channel_data_type(image);
6
+ if(dataType == CLK_FLOAT) {
7
+ value = read_imagef(image, sampler, pos).x;
8
+ } else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {
9
+ value = read_imageui(image, sampler, pos).x;
10
+ } else {
11
+ value = read_imagei(image, sampler, pos).x;
12
+ }
13
+ return value;
14
+ }
15
+
16
+ float calculateMeanIntensity(__read_only image2d_t frame, int2 pos) {
17
+ float mean = 0.0f;
18
+ for(int y = pos.y - BLOCK_SIZE; y <= pos.y + BLOCK_SIZE; ++y) {
19
+ for(int x = pos.x - BLOCK_SIZE; x <= pos.x + BLOCK_SIZE; ++x) {
20
+ mean += getPixelAsFloat(frame, (int2)(x,y));
21
+ }
22
+ }
23
+
24
+ return mean/((BLOCK_SIZE*2+1)*(BLOCK_SIZE*2+1));
25
+ }
26
+
27
+
28
+ inline float2 findSubpixelMovement(const float2 movement, const float b[GRID_SIZE][GRID_SIZE]) {
29
+ const int index_x = (int)movement.x + SEARCH_SIZE+1;
30
+ const int index_y = (int)movement.y + SEARCH_SIZE+1;
31
+ // Subpixel parabolic fitting
32
+ const float A =
33
+ (b[index_x-1][index_y-1] - 2 * b[index_x][index_y-1] + b[index_x+1][index_y-1] + b[index_x-1][index_y] - 2 * b[index_x][index_y] + b[index_x+1][index_y] + b[index_x-1][index_y+1] - 2 * b[index_x][index_y+1] +
34
+ b[index_x+1][index_y+1]) / 6.0;
35
+ const float B = (b[index_x-1][index_y-1] - b[index_x+1][index_y-1] - b[index_x-1][index_y+1] + b[index_x+1][index_y+1]) / 4.0;
36
+ const float C =
37
+ (b[index_x-1][index_y-1] + b[index_x][index_y-1] + b[index_x+1][index_y-1] - 2 * b[index_x-1][index_y] - 2 * b[index_x][index_y] - 2 * b[index_x+1][index_y] + b[index_x-1][index_y+1] + b[index_x][index_y+1] +
38
+ b[index_x+1][index_y+1]) / 6.0;
39
+ const float D = (-b[index_x-1][index_y-1] + b[index_x+1][index_y-1] - b[index_x-1][index_y] + b[index_x+1][index_y] - b[index_x-1][index_y+1] + b[index_x+1][index_y+1]) / 6.0;
40
+ const float E = (-b[index_x-1][index_y-1] - b[index_x][index_y-1] - b[index_x+1][index_y-1] + b[index_x-1][index_y+1] + b[index_x][index_y+1] + b[index_x+1][index_y+1]) / 6.0;
41
+ const float F = (-b[index_x-1][index_y-1] + 2 * b[index_x][index_y-1] - b[index_x+1][index_y-1] + 2 * b[index_x-1][index_y] + 5 * b[index_x][index_y] + 2 * b[index_x+1][index_y] - b[index_x-1][index_y+1] +
42
+ 2 * b[index_x][index_y+1] - b[index_x+1][index_y+1]) / 9.0;
43
+
44
+ return (float2)(movement.x + (B * E - 2.0 * C * D) / (4.0 * A * C - B * B),
45
+ movement.y + (B * D - 2.0 * A * E) / (4.0 * A * C - B * B));
46
+ }
47
+
48
+ inline float2 findMovementNCC(
49
+ __read_only image2d_t previousFrame,
50
+ __read_only image2d_t currentFrame,
51
+ const int2 pos,
52
+ float targetMean
53
+ ) {
54
+ // Create grid for subpixel movement calculations
55
+ float b[GRID_SIZE][GRID_SIZE];
56
+
57
+ // For every possible block position
58
+ float bestScore = -1.0f;
59
+ float2 movement = {0, 0};
60
+ for(int y = pos.y - SEARCH_SIZE - 1; y <= pos.y + SEARCH_SIZE + 1; ++y) {
61
+ for(int x = pos.x - SEARCH_SIZE - 1; x <= pos.x + SEARCH_SIZE + 1; ++x) {
62
+ // previousframe at pos x,y is the current candidate
63
+ const float candidateMean = calculateMeanIntensity(previousFrame, (int2)(x, y));
64
+ float upperPart = 0.0f;
65
+ float lowerPart1 = 0.0f;
66
+ float lowerPart2 = 0.0f;
67
+ // Loop over target and candidate block
68
+ for(int a = -BLOCK_SIZE; a <= BLOCK_SIZE; ++a) {
69
+ for(int b = -BLOCK_SIZE; b <= BLOCK_SIZE; ++b) {
70
+ const float imagePart = getPixelAsFloat(previousFrame, (int2)(x+a, y+b)) - candidateMean;
71
+ const float targetPart = getPixelAsFloat(currentFrame, (int2)(pos.x+a, pos.y+b)) - targetMean;
72
+ upperPart += imagePart*targetPart;
73
+ lowerPart1 += imagePart*imagePart;
74
+ lowerPart2 += targetPart*targetPart;
75
+ }
76
+ }
77
+
78
+ const float result = upperPart / sqrt(lowerPart1*lowerPart2);
79
+ b[x- pos.x + SEARCH_SIZE + 1][y - pos.y + SEARCH_SIZE + 1] = result;
80
+ if(result > bestScore && abs(x - pos.x) <= SEARCH_SIZE && abs(y - pos.y) <= SEARCH_SIZE) {
81
+ bestScore = result;
82
+ movement = (float2)(x - pos.x, y - pos.y); // Movement is the offset from pos.x, pos.y
83
+ }
84
+ }
85
+ }
86
+
87
+ float2 subpixel_movement = findSubpixelMovement(movement, b);
88
+ return subpixel_movement;
89
+ }
90
+
91
+ __kernel void normalizedCrossCorrelation(
92
+ __read_only image2d_t previousFrame,
93
+ __read_only image2d_t currentFrame,
94
+ __write_only image2d_t output,
95
+ __private const float intensityThreshold,
96
+ __private const float timeLag,
97
+ __private const char forwardBackward
98
+ ) {
99
+ const int2 pos = {get_global_id(0), get_global_id(1)};
100
+
101
+ // Template is what we are looking for (target), currentFrame at pos
102
+ const float targetMean = calculateMeanIntensity(currentFrame, pos);
103
+ if(targetMean < intensityThreshold) { // if target is all zero/black, just stop here
104
+ write_imagef(output, pos, (float4)(0, 0, 0, 0));
105
+ return;
106
+ }
107
+
108
+ float2 movement = findMovementNCC(previousFrame, currentFrame, pos, targetMean);
109
+ if(forwardBackward == 1) {
110
+ const float targetMean2 = calculateMeanIntensity(previousFrame, pos);
111
+ movement = (movement - findMovementNCC(currentFrame, previousFrame, pos, targetMean2))*0.5f;
112
+ }
113
+
114
+ // If movement is larger than SEARCH_SIZE, zero it out
115
+ if(length(movement) > SEARCH_SIZE + 1)
116
+ movement = (float2)(0,0);
117
+
118
+ write_imagef(output, pos, movement.xyyy / timeLag);
119
+ }
120
+
121
+ inline float2 findMovementSSD(
122
+ __read_only image2d_t previousFrame,
123
+ __read_only image2d_t currentFrame,
124
+ const int2 pos,
125
+ float minIntensity,
126
+ float maxIntensity
127
+ ) {
128
+ // Create grid for subpixel movement calculations
129
+ float b[GRID_SIZE][GRID_SIZE];
130
+
131
+ // For every possible block position
132
+ float bestScore = 0.0f;
133
+ float2 movement = {0, 0};
134
+ for(int y = pos.y - SEARCH_SIZE - 1; y <= pos.y + SEARCH_SIZE + 1; ++y) {
135
+ for(int x = pos.x - SEARCH_SIZE - 1; x <= pos.x + SEARCH_SIZE + 1; ++x) {
136
+ // previousframe at pos x,y is the current candidate
137
+ float ssd = 0.0f;
138
+ // Loop over target and candidate block
139
+ for(int a = -BLOCK_SIZE; a <= BLOCK_SIZE; ++a) {
140
+ for(int b = -BLOCK_SIZE; b <= BLOCK_SIZE; ++b) {
141
+ float val = (getPixelAsFloat(previousFrame, (int2)(x+a,y+b)) - minIntensity)/(maxIntensity - minIntensity) -
142
+ (getPixelAsFloat(currentFrame, (int2)(pos.x+a,pos.y+b)) - minIntensity)/(maxIntensity - minIntensity);
143
+ ssd += val*val;
144
+ }
145
+ }
146
+
147
+ const float result = 1.0f - (ssd/((BLOCK_SIZE*2+1)*(BLOCK_SIZE*2+1))); // calculate average and invert
148
+
149
+ b[x- pos.x + SEARCH_SIZE + 1][y - pos.y + SEARCH_SIZE + 1] = result;
150
+ if(result > bestScore && abs(x - pos.x) <= SEARCH_SIZE && abs(y - pos.y) <= SEARCH_SIZE) {
151
+ bestScore = result;
152
+ movement = (float2)(x - pos.x, y - pos.y); // Movement is the offset from pos.x, pos.y
153
+ }
154
+ }
155
+ }
156
+ float2 subpixel_movement = findSubpixelMovement(movement, b);
157
+ return subpixel_movement;
158
+ }
159
+
160
+ __kernel void sumOfSquaredDifferences(
161
+ __read_only image2d_t previousFrame,
162
+ __read_only image2d_t currentFrame,
163
+ __write_only image2d_t output,
164
+ __private const float intensityThreshold,
165
+ __private const float timeLag,
166
+ __private const char forwardBackward,
167
+ __private const float minIntensity,
168
+ __private const float maxIntensity
169
+ ) {
170
+ const int2 pos = {get_global_id(0), get_global_id(1)};
171
+
172
+ // Template is what we are looking for (target), currentFrame at pos
173
+ const float targetMean = calculateMeanIntensity(currentFrame, pos);
174
+ if(targetMean < intensityThreshold) { // if target is all zero/black, just stop here
175
+ write_imagef(output, pos, (float4)(0, 0, 0, 0));
176
+ return;
177
+ }
178
+
179
+ float2 movement = findMovementSSD(previousFrame, currentFrame, pos, minIntensity, maxIntensity);
180
+ if(forwardBackward == 1)
181
+ movement = (movement - findMovementSSD(currentFrame, previousFrame, pos, minIntensity, maxIntensity))*0.5f;
182
+
183
+ // If movement is larger than SEARCH_SIZE, zero it out
184
+ if(length(movement) > SEARCH_SIZE + 1)
185
+ movement = (float2)(0,0);
186
+
187
+ write_imagef(output, pos, movement.xyyy / timeLag);
188
+ }
189
+
190
+ inline float2 findMovementSAD(
191
+ __read_only image2d_t previousFrame,
192
+ __read_only image2d_t currentFrame,
193
+ const int2 pos,
194
+ float minIntensity,
195
+ float maxIntensity
196
+ ) {
197
+ // Create grid for subpixel movement calculations
198
+ float b[GRID_SIZE][GRID_SIZE];
199
+
200
+ // For every possible block position
201
+ float bestScore = 0.0f;
202
+ float2 movement = {0, 0};
203
+ for(int y = pos.y - SEARCH_SIZE - 1; y <= pos.y + SEARCH_SIZE + 1; ++y) {
204
+ for(int x = pos.x - SEARCH_SIZE - 1; x <= pos.x + SEARCH_SIZE + 1; ++x) {
205
+ // previousframe at pos x,y is the current candidate
206
+ float sad = 0.0f;
207
+ // Loop over target and candidate block
208
+ for(int a = -BLOCK_SIZE; a <= BLOCK_SIZE; ++a) {
209
+ for(int b = -BLOCK_SIZE; b <= BLOCK_SIZE; ++b) {
210
+ sad += fabs((getPixelAsFloat(previousFrame, (int2)(x+a,y+b)) - minIntensity)/(maxIntensity - minIntensity) -
211
+ (getPixelAsFloat(currentFrame, (int2)(pos.x+a,pos.y+b)) - minIntensity)/(maxIntensity - minIntensity));
212
+ }
213
+ }
214
+
215
+ const float result = 1.0f - (sad/((BLOCK_SIZE*2+1)*(BLOCK_SIZE*2+1))); // calculate average and invert
216
+
217
+ b[x- pos.x + SEARCH_SIZE + 1][y - pos.y + SEARCH_SIZE + 1] = result;
218
+ if(result > bestScore && abs(x - pos.x) <= SEARCH_SIZE && abs(y - pos.y) <= SEARCH_SIZE) {
219
+ bestScore = result;
220
+ movement = (float2)(x - pos.x, y - pos.y); // Movement is the offset from pos.x, pos.y
221
+ }
222
+ }
223
+ }
224
+
225
+ float2 subpixel_movement = findSubpixelMovement(movement, b);
226
+ return subpixel_movement;
227
+ }
228
+
229
+ __kernel void sumOfAbsoluteDifferences(
230
+ __read_only image2d_t previousFrame,
231
+ __read_only image2d_t currentFrame,
232
+ __write_only image2d_t output,
233
+ __private const float intensityThreshold,
234
+ __private const float timeLag,
235
+ __private const char forwardBackward,
236
+ __private const float minIntensity,
237
+ __private const float maxIntensity
238
+ ) {
239
+ const int2 pos = {get_global_id(0), get_global_id(1)};
240
+
241
+ // Template is what we are looking for (target), currentFrame at pos
242
+ const float targetMean = calculateMeanIntensity(currentFrame, pos);
243
+ if(targetMean < intensityThreshold) { // if target is all zero/black, just stop here
244
+ write_imagef(output, pos, (float4)(0, 0, 0, 0));
245
+ return;
246
+ }
247
+
248
+ float2 movement = findMovementSAD(previousFrame, currentFrame, pos, minIntensity, maxIntensity);
249
+ if(forwardBackward == 1)
250
+ movement = (movement - findMovementSAD(currentFrame, previousFrame, pos, minIntensity, maxIntensity))*0.5f;
251
+
252
+ // If movement is larger than SEARCH_SIZE, zero it out
253
+ if(length(movement) > SEARCH_SIZE + 1)
254
+ movement = (float2)(0,0);
255
+
256
+ write_imagef(output, pos, movement.xyyy / timeLag);
257
+ }