(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"alpha-blending\">Alpha Blending</h3>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropiate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"unsharpmask\">Unsharpmask</h3>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>','','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:16:08','2014-07-11 15:16:08','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6119,17729,'2014-07-11 15:18:00','2014-07-11 15:18:00','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections.<br />All the operations are built using some existing image manipulation functions and the awesome element-wise operations enabled in ArrayFire.<br />If you are not aware of what the JIT feature in ArrayFire lets you do, please refer to one of our previous post here.</p>\r\n<h3 id=\"contrast-modification\">Contrast modification</h3>\r\n\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"brightness-modification\">Brightness modification</h3>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    return (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h3 id=\"image-translation\">Image translation</h3>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>.</p>\r\n<h3 id=\"digital-zoom\">Digital Zoom</h3>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"alpha-blending\">Alpha Blending</h3>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropiate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"unsharpmask\">Unsharpmask</h3>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:18:00','2014-07-11 15:18:00','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6120,17729,'2014-07-11 15:19:29','2014-07-11 15:19:29','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"brightness-modification\">Brightness modification</h3>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    return (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h3 id=\"image-translation\">Image translation</h3>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>.</p>\r\n<h3 id=\"digital-zoom\">Digital Zoom</h3>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"alpha-blending\">Alpha Blending</h3>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropiate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h3 id=\"unsharpmask\">Unsharpmask</h3>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:19:29','2014-07-11 15:19:29','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6121,17729,'2014-07-11 15:22:36','2014-07-11 15:22:36','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    return (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:22:36','2014-07-11 15:22:36','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6122,17729,'2014-07-11 15:24:58','2014-07-11 15:24:58','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    return (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function `translate(a,100,100,200,126)` on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:24:58','2014-07-11 15:24:58','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6123,17729,'2014-07-11 15:41:47','2014-07-11 15:41:47','','highbright','','inherit','open','open','','highbright','','','2014-07-11 15:41:47','2014-07-11 15:41:47','',6099,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg',0,'attachment','image/jpeg',0),(6124,17729,'2014-07-11 15:51:43','2014-07-11 15:51:43','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    return (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function `translate(a,100,100,200,126)` on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project here\"','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:51:43','2014-07-11 15:51:43','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6125,17729,'2014-07-11 15:52:40','2014-07-11 15:52:40','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function `translate(a,100,100,200,126)` on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project here\"','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:52:40','2014-07-11 15:52:40','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6126,17729,'2014-07-11 15:54:29','2014-07-11 15:54:29','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function <code>translate(a,100,100,200,126)</code> on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project here\"','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 15:54:29','2014-07-11 15:54:29','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6127,17729,'2014-07-11 16:10:21','2014-07-11 16:10:21','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function <code>translate(a,100,100,200,126)</code> on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 16:10:21','2014-07-11 16:10:21','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6128,17729,'2014-07-11 16:12:42','2014-07-11 16:12:42','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function <code>translate(a,100,100,200,126)</code> on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array intensity = colorspace(fight,af_gray,af_rgb); array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 16:12:42','2014-07-11 16:12:42','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6129,17729,'2014-07-11 16:13:41','2014-07-11 16:13:41','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function <code>translate(a,100,100,200,126)</code> on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using the following code stub.\r\n<code>\r\narray intensity = colorspace(fight,af_gray,af_rgb);\r\narray mask = clamp(intensity,10.0f,255.0f)>0.0f;\r\n</code>.\r\nA more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 16:13:41','2014-07-11 16:13:41','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6130,17729,'2014-07-11 16:14:13','2014-07-11 16:14:13','<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>\r\n<ul>\r\n<li>contrast modification<br /></li>\r\n<li>brightness modification<br /></li>\r\n<li>translation<br /></li>\r\n<li>digital zoom<br /></li>\r\n<li>alpha blending<br /></li>\r\n<li>unsharp mask</li>\r\n</ul>\r\n<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections. All the operations are built using some existing image manipulation functions and the awesome element-wise operations in ArrayFire.\r\n<h4 id=\"contrast-modification\">Contrast modification</h4>\r\n<pre>\r\n/**\r\n * contrast value should be in the range [-1,1]\r\n **/\r\nvoid changeContrast(array &in, const float contrast)\r\n{\r\n    float scale     = tan((contrast+1)*Pi/4);\r\n    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg\" alt=\"highcon\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6106\"/>\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"brightness-modification\">Brightness modification</h4>\r\n<pre>\r\n/**\r\n * brightness value should be in the range [0,1]\r\n **/\r\nvoid changeBrightness(array &in, const float brightness, const float channelMax=255.0f)\r\n{\r\n    float factor = brightness*channelMax;\r\n    in = (in + factor);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highbright.jpg\" alt=\"highbright\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6105\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>\r\n<pre>\r\nimage = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;\r\n</pre>\r\nor a more generalized clamp/thresholding operation would like as below.\r\n<pre>\r\narray clamp(const array &in, float min=0.0f, float max=255.0f)\r\n{\r\n    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);\r\n}\r\n</pre>\r\n\r\n<h4 id=\"image-translation\">Image translation</h4>\r\n<p>This operation can be achieved directly by a function in our library <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__translate.htm#ga1615c8ea000ad113a0dc7a9313d7b645\"><code>translate</code></a>. A sample output of the function <code>translate(a,100,100,200,126)</code> on the sample input is provided below.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/translated.jpg\" alt=\"translated\" width=\"126\" height=\"200\" class=\"alignnone size-full wp-image-6110\" /></a>\r\n </div>\r\n</div>\r\n<h4 id=\"digital-zoom\">Digital Zoom</h4>\r\n<pre>\r\narray digZoom(const array &in, int x, int y, int width, int height)\r\n{\r\n    array cropped = in(seq(height)+x,seq(width)+y,span);\r\n    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\"/>\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/zoom.jpg\" alt=\"zoom\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6112\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"alpha-blending\">Alpha Blending</h4>\r\n<pre>\r\narray alphaBlend(const array &foreground, const array &background, const array &mask)\r\n{\r\n    array tiledMask;\r\n    if (mask.dims(2)!=foreground.dims(2))\r\n        tiledMask = tile(mask,1,1,foreground.dims(2));\r\n    return foreground*tiledMask+(1.0f-tiledMask)*background;\r\n}\r\n</pre>\r\n<p>For the purpose of this example, a very simple mask was created using the following code stub.\r\n<pre>\r\narray intensity = colorspace(fight,af_gray,af_rgb);\r\narray mask = clamp(intensity,10.0f,255.0f)>0.0f;\r\n</pre>\r\nA more detailed and accurate mask would deliver more appropriate blending.</p>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/nature-300x168.jpg\" alt=\"nature\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6109\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/fight-300x168.jpg\" alt=\"fight\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6104\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/blend-300x168.jpg\" alt=\"blend\" width=\"300\" height=\"168\" class=\"alignnone size-medium wp-image-6103\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4 id=\"unsharpmask\">Unsharpmask</h4>\r\n<pre>\r\n/**\r\n * radius effects the level of details that will effected during sharpening process\r\n * amount value should be in the range [0,1] or [1,]\r\n * note: value of 1.0 for amount results unsharp masking\r\n *       values > 1.0 results in highboost filter effect\r\n **/\r\narray usm(const array &in, float radius, float amount)\r\n{\r\n    int gKernelLen  = 2*radius + 1;\r\n    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);\r\n    array blur  = convolve(in,blurKernel);\r\n    return (in + amount*(in - blur));\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg\" alt=\"man\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6108\" />\r\n   </a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n   <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\">\r\n     <img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/usm.jpg\" alt=\"usm\" width=\"226\" height=\"300\" class=\"alignnone size-full wp-image-6111\" />\r\n   </a>\r\n </div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nWe are working on a free image editing application based on ArrayFire. This is the first part of the series that discusses our progress. You can follow the project <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire','','inherit','open','open','','6099-revision-v1','','','2014-07-11 16:14:13','2014-07-11 16:14:13','',6099,'http://sandbox.arrayfire.com/6099-revision-v1/',0,'revision','',0),(6139,17796,'2014-07-18 18:37:27','2014-07-18 18:37:27','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s GPUs, CPUs and APUs </li>\r\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support Android and Linux for embedded systems. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\r\n\r\n         <li> Qualcom Adreno GPUs </li>\r\n         <li> ARM Mali GPUs </li>\r\n         <li> <a href=\"http://sandbox.arrayfire.com/arrayfire-on-tegra-k1/\">NVIDIA Tegra K1 GPU</a> </li>\r\n         <li> Freescale Vivante GPUs </li>\r\n\r\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including <code>R</code>, <code>Fortran</code>, <code> Java </code>. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','publish','open','open','','arrayfire-capability-update-july-2014','','\nhttp://sandbox.arrayfire.com/arrayfire-on-tegra-k1/','2014-07-18 18:51:36','2014-07-18 18:51:36','',0,'http://sandbox.arrayfire.com/?p=6139',0,'post','',1),(6140,17796,'2014-07-18 17:42:19','2014-07-18 17:42:19','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n\r\n&nbsp;\r\n\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages can be found at https://github.com/arrayfire\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:42:19','2014-07-18 17:42:19','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6141,17796,'2014-07-18 17:44:29','2014-07-18 17:44:29','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n\r\n&nbsp;\r\n\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at https://github.com/arrayfire . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:44:29','2014-07-18 17:44:29','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6142,17796,'2014-07-18 17:48:22','2014-07-18 17:48:22','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n\r\n&nbsp;\r\n\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">https://github.com/arrayfire</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to <a title=\"contact us\" href=\"dev@arrayfire.com\">contact us</a> and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:48:22','2014-07-18 17:48:22','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6143,17796,'2014-07-18 17:50:22','2014-07-18 17:50:22','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n\r\n&nbsp;\r\n\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">https://github.com/arrayfire</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to <a href=\"mailto:sales@arrayfire.com\">dev@arrayfire.com</a>\r\n\r\n<a title=\"contact us\" href=\"dev@arrayfire.com\">contact us</a> and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:50:22','2014-07-18 17:50:22','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6144,17796,'2014-07-18 17:51:00','2014-07-18 17:51:00','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n\r\n&nbsp;\r\n\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">https://github.com/arrayfire</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to <a title=\"contact us\" href=\"mailto:dev@arrayfire.com\">dev@arrayfire.com</a>\r\n\r\n<a title=\"contact us\" href=\"dev@arrayfire.com\">contact us</a> and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:51:00','2014-07-18 17:51:00','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6145,17796,'2014-07-18 17:55:38','2014-07-18 17:55:38','In response to user requests for ArrayFire capabilities, we have decided to extend the library to support CPUs that do not have OpenCL support. This means that in practice ArrayFire will be portable to both devices that have OpenCL setup and devices that do not have it setup. This has required on our part to optimize a subset of our functions so that performance is maximized for different architectures and systems. These includes different lines of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n<h4> New Capabilities</h4>\r\nAs part of this process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned).\r\n<h4> Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">https://github.com/arrayfire</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:dev@arrayfire.com\">dev@arrayfire.com</a> and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 17:55:38','2014-07-18 17:55:38','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6146,17796,'2014-07-18 18:06:19','2014-07-18 18:06:19','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to non OpenCL supported CPUs systems. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We are currently supporting  multiple systems and architectures  of NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n&nbsp;\r\n<h4> New Capabilities</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to mobile devices and low power system. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit.\r\n<h4> Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found at <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">https://github.com/arrayfire</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:dev@arrayfire.com\">dev@arrayfire.com</a> and we help you.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:06:19','2014-07-18 18:06:19','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6147,17728,'2014-07-18 18:50:28','2014-07-18 18:50:28','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\n\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\n        <li> AMD\'s GPUs, CPUs and APUs </li>\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\n\n<h4>Mobile and Embedded devices</h4>\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Android and Linux . Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\n\n         <li> Qualcom Adreno GPUs </li>\n         <li> ARM Mali GPUs </li>\n         <li> <a href=\"http://sandbox.arrayfire.com/arrayfire-on-tegra-k1/\">NVIDIA Tegra K1 GPU</a> </li>\n         <li> Freescale Vivante GPUs </li>\n\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\n<h4>Language Support</h4>\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including <code>R</code>, <code>Fortran</code>, <code> Java </code>. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-autosave-v1','','','2014-07-18 18:50:28','2014-07-18 18:50:28','',6139,'http://sandbox.arrayfire.com/6139-autosave-v1/',0,'revision','',0),(6148,17728,'2014-07-18 18:25:43','2014-07-18 18:25:43','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler), AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit.\r\n\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:25:43','2014-07-18 18:25:43','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6149,17728,'2014-07-18 18:26:08','2014-07-18 18:26:08','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler)\r\n        <li> AMD\'s APUs, and Intel-based systems (x86 and PHI).\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit.\r\n\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:26:08','2014-07-18 18:26:08','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6150,17728,'2014-07-18 18:26:30','2014-07-18 18:26:30','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s APUs, and Intel-based systems (x86 and PHI). </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Qualcomm Snapdragon. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit.\r\n\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:26:30','2014-07-18 18:26:30','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6151,17728,'2014-07-18 18:34:21','2014-07-18 18:34:21','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s GPUs, CPUs and APUs </li>\r\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Android and Linux operating systems. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\r\n\r\n         <li> Qualcom Adreno GPUs </li>\r\n         <li> ARM Mali GPUs </li>\r\n         <li> NVIDIA Tegra K1 GPU </li>\r\n         <li> Freescale Vivante GPUs </li>\r\n\r\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\r\n\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including R, Fortran, Java. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:34:21','2014-07-18 18:34:21','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6152,17728,'2014-07-18 18:38:57','2014-07-18 18:38:57','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s GPUs, CPUs and APUs </li>\r\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Android and Linux operating systems. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\r\n\r\n         <li> Qualcom Adreno GPUs </li>\r\n         <li> ARM Mali GPUs </li>\r\n         <li> NVIDIA Tegra K1 GPU </li>\r\n         <li> Freescale Vivante GPUs </li>\r\n\r\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including <code>R</code>, <code>Fortran</code>, <code> Java </code>. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:38:57','2014-07-18 18:38:57','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6153,17728,'2014-07-18 18:40:31','2014-07-18 18:40:31','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s GPUs, CPUs and APUs </li>\r\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support the Android and Linux operating systems. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\r\n\r\n         <li> Qualcom Adreno GPUs </li>\r\n         <li> ARM Mali GPUs </li>\r\n         <li> <a href=\"http://sandbox.arrayfire.com/arrayfire-on-tegra-k1/\">NVIDIA Tegra K1 GPU</a> </li>\r\n         <li> Freescale Vivante GPUs </li>\r\n\r\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including <code>R</code>, <code>Fortran</code>, <code> Java </code>. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:40:31','2014-07-18 18:40:31','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6154,17728,'2014-07-18 18:50:59','2014-07-18 18:50:59','In response to user requests for additional ArrayFire capabilities, we have decided to extend the library to have CPU fall back when OpenCL drivers for CPUs are not available. This means that ArrayFire code will be portable to both devices that have OpenCL setup and devices without it. This is done through the creation of additional backends. This will allow ArrayFire users to write their code once and have it run on multiple systems. We currently support the following systems and architectures:\r\n\r\n	<li> NVIDIA GPUs (Tesla, Fermi, and Kepler) </li>\r\n        <li> AMD\'s GPUs, CPUs and APUs </li>\r\n        <li> Intel\'s CPUs, GPUs and Xeon Phi Co-Processor </li>\r\n\r\n<h4>Mobile and Embedded devices</h4>\r\nAs part of this update process we are also looking at extending ArrayFire capabilities to low power systems such as mobile and embedded devices. We have already started to port our code to support Android and Linux for embedded systems. Performance results are promising at this stage and we expect to publish initial results in the upcoming weeks (so keep tuned). The market\'s need for fast systems has brought a new and wide range of systems that all require fast algorithms at a high-level of productivity. We plan on following suit. We are currently working on the following architectures:\r\n\r\n         <li> Qualcom Adreno GPUs </li>\r\n         <li> ARM Mali GPUs </li>\r\n         <li> <a href=\"http://sandbox.arrayfire.com/arrayfire-on-tegra-k1/\">NVIDIA Tegra K1 GPU</a> </li>\r\n         <li> Freescale Vivante GPUs </li>\r\n\r\nYou can find a more comprehensive list of devices that can support ArrayFire<a href=\"https://docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1Mpzfl2NmLUVSAjIph77-FOsJeuyD9Xjha89r5iHw1hI/edit#gid=0\"> in this document</a>.\r\n<h4>Language Support</h4>\r\nTo further increase the portability of ArrayFire we have also increasing the number of supported programming languages, including <code>R</code>, <code>Fortran</code>, <code> Java </code>. The wrappers for these languages are open-source can be found on our <a title=\"https://github.com/arrayfire\" href=\"https://github.com/arrayfire\">github page</a> . If you are interested in creating a wrapper for your favorite language and require assistance, feel free to contact us at <a href=\"mailto:technical@arrayfire.com\">technical@arrayfire.com</a> and we help you.','ArrayFire Capability Update - July 2014','','inherit','open','open','','6139-revision-v1','','','2014-07-18 18:50:59','2014-07-18 18:50:59','',6139,'http://sandbox.arrayfire.com/6139-revision-v1/',0,'revision','',0),(6157,11,'2014-07-24 21:59:01','2014-07-24 21:59:01','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPU/CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1526.3 (VM)\r\n[0]: Tahiti, 2864 MB, OpenCL Version: 1.2\r\n 1 : AMD FX(tm)-8350 Eight-Core Processor, 7953 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 586ef59)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1445.5 (VM)\r\n[0]: Spectre, 624 MB, OpenCL Version: 1.2\r\n 1 : AMD A10-7850K APU with Radeon(TM) R7 Graphics, 6885 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<strong>#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.</strong>\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.\r\nIf you have OpenCL working on any other device and wish to try ArrayFire, contact us at <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a>.','ArrayFire: Write once, Run anywhere','','publish','open','open','','arrayfire-write-once-run-anywhere','','','2014-07-24 22:58:56','2014-07-24 22:58:56','',0,'http://sandbox.arrayfire.com/?p=6157',0,'post','',2),(6158,11,'2014-07-23 15:50:11','2014-07-23 15:50:11','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h4>NVIDIA GPUs (CUDA/OpenCL)</h4>\r\n\r\n<h4>NVIDIA Tegra K1 (CUDA)</h4>\r\n\r\n<h4>AMD GPUs (OpenCL)</h4>\r\n\r\n<h4>AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU Graphics (OpenCL)</h4>\r\n\r\n<h4>Intel Xeon Phi (OpenCL)</h4>\r\n\r\n<h4>ARM Devices (OpenCL)</h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)</h4>\r\n\r\n\r\n','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 15:50:11','2014-07-23 15:50:11','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6159,11,'2014-07-23 15:53:29','2014-07-23 15:53:29','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h4>NVIDIA GPUs (CUDA/OpenCL)</h4>\r\n\r\n<h4>NVIDIA Tegra K1 (CUDA)</h4>\r\n\r\n<h4>AMD GPUs (OpenCL)</h4>\r\n\r\n<h4>AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU Graphics (OpenCL)</h4>\r\n\r\n<h4>Intel Xeon Phi (OpenCL)</h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>#</sup></h4>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\n','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 15:53:29','2014-07-23 15:53:29','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6160,11,'2014-07-23 16:01:01','2014-07-23 16:01:01','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h4>NVIDIA GPUs (CUDA/OpenCL)</h4>\r\n\r\n<h4>AMD GPUs (OpenCL)</h4>\r\n\r\n<h4>AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU (OpenCL)</h4>\r\n\r\n<h4>Intel CPU Graphics (OpenCL)</h4>\r\n\r\n<h4>Intel Xeon Phi (OpenCL)</h4>\r\n\r\n<h4>NVIDIA Tegra K1 (CUDA)</h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>#</sup></h4>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\n','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:01:01','2014-07-23 16:01:01','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6161,11,'2014-07-23 16:32:17','2014-07-23 16:32:17','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: <Link Here>\r\n\r\n<h4>NVIDIA GPUs<sup>$+</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>+</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>+</sup></h4>\r\n\r\n<h4>Intel CPU<sup>+</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>+</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>+</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>+#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>+#</sup></h4>\r\n\r\n$: CUDA Capable\r\n+: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:32:17','2014-07-23 16:32:17','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6162,11,'2014-07-23 16:32:59','2014-07-23 16:32:59','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: <Link Here>\r\n\r\n<h4>NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:32:59','2014-07-23 16:32:59','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6163,11,'2014-07-23 16:33:57','2014-07-23 16:33:57','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 color=\"red\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:33:57','2014-07-23 16:33:57','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6164,11,'2014-07-23 16:35:11','2014-07-23 16:35:11','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:red;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:35:11','2014-07-23 16:35:11','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6165,11,'2014-07-23 16:35:50','2014-07-23 16:35:50','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:35:50','2014-07-23 16:35:50','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6166,11,'2014-07-23 16:36:03','2014-07-23 16:36:03','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:green;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4>AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4>AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU<sup>^</sup></h4>\r\n\r\n<h4>Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4>Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4>NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4>ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4>Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:36:03','2014-07-23 16:36:03','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6167,11,'2014-07-23 16:37:02','2014-07-23 16:37:02','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:green;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4 style=\"color:red;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:red;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:green;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4 style=\"color:yellow;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:yellow;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:37:02','2014-07-23 16:37:02','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6168,11,'2014-07-23 16:38:02','2014-07-23 16:38:02','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:red;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:blue;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:green;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4 style=\"color:yellow;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:yellow;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:38:02','2014-07-23 16:38:02','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6169,11,'2014-07-23 16:39:58','2014-07-23 16:39:58','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 16:39:58','2014-07-23 16:39:58','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6170,11,'2014-07-23 21:36:03','2014-07-23 21:36:03','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n<code>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</code>\r\n<code>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/user/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</code>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n<code>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n 0 : Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n[2]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [2]\r\n</code>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 21:36:03','2014-07-23 21:36:03','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6171,11,'2014-07-23 21:37:03','2014-07-23 21:37:03','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/user/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n 0 : Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n[2]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [2]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n<pre>\r\nArrayFire v (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 21:37:03','2014-07-23 21:37:03','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6172,11,'2014-07-23 21:37:37','2014-07-23 21:37:37','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n 2 : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n 0 : Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n[2]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [2]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n<pre>\r\nArrayFire v (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 21:37:37','2014-07-23 21:37:37','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6173,11,'2014-07-23 22:06:25','2014-07-23 22:06:25','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n 2 : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\n 1 : Intel(R) Xeon(R) CPU           X5680  @ 3.33GHz, 11997 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/shehzan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n 0 : Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n[2]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [2]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n<pre>\r\nArrayFire v (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 22:06:25','2014-07-23 22:06:25','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6174,11,'2014-07-23 22:07:14','2014-07-23 22:07:14','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs<sup>$^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n 2 : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\n 1 : Intel(R) Xeon(R) CPU           X5680  @ 3.33GHz, 11997 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU<sup>^</sup></h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n 0 : Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\n[2]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [2]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU Graphics<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi<sup>^</sup></h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1<sup>$</sup></h4>\r\n<pre>\r\nArrayFire v (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Devices (OpenCL)<sup>^#</sup></h4>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Phones with Qualcomm Processors (OpenCL)<sup>^#</sup></h4>\r\n\r\n$: CUDA Capable\r\n^: OpenCL Capable\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-23 22:07:14','2014-07-23 22:07:14','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6175,1,'2014-07-24 15:17:53','2014-07-24 15:17:53','','Order &ndash; July 24, 2014 @ 03:17 PM','','wc-completed','open','closed','order_53d1239edf667','order-jul-24-2014-0317-pm','','','2014-07-24 15:17:55','2014-07-24 15:17:55','',0,'http://sandbox.arrayfire.com/?post_type=shop_order&#038;p=6175',0,'shop_order','',4),(6178,11,'2014-07-24 18:37:37','2014-07-24 18:37:37','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\nCode: Link Here\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Andoird Devices using Qualcomm Processors (OpenCL) <sup>#</sup></h4>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 18:37:37','2014-07-24 18:37:37','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6179,11,'2014-07-24 19:12:15','2014-07-24 19:12:15','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h3>Desktop (x86) Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/umar/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:12:15','2014-07-24 19:12:15','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6180,11,'2014-07-24 19:12:21','2014-07-24 19:12:21','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h3>Desktop(x86) Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/umar/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:12:21','2014-07-24 19:12:21','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6181,11,'2014-07-24 19:12:33','2014-07-24 19:12:33','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/umar/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:12:33','2014-07-24 19:12:33','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6182,11,'2014-07-24 19:13:33','2014-07-24 19:13:33','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/umar/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:13:33','2014-07-24 19:13:33','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6183,11,'2014-07-24 19:14:18','2014-07-24 19:14:18','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we will show examples of the various devices that ArrayFire runs using the exact same code.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#00CC66;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:14:18','2014-07-24 19:14:18','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6184,11,'2014-07-24 19:24:55','2014-07-24 19:24:55','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of af:info() from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#AA0000;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0033FF;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#006600;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra boom)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#FF3333;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:24:55','2014-07-24 19:24:55','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6186,11,'2014-07-24 19:31:44','2014-07-24 19:31:44','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af:info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#3366FF;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:31:44','2014-07-24 19:31:44','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6187,11,'2014-07-24 19:33:11','2014-07-24 19:33:11','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af:info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:33:11','2014-07-24 19:33:11','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6188,11,'2014-07-24 19:33:26','2014-07-24 19:33:26','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n\r\n#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:33:26','2014-07-24 19:33:26','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6189,11,'2014-07-24 19:46:30','2014-07-24 19:46:30','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<strong>#</strong>: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.\r\nIf you have OpenCL working on any other device and wish to try ArrayFire, contact us at <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a>.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:46:30','2014-07-24 19:46:30','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6190,11,'2014-07-24 19:46:50','2014-07-24 19:46:50','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1214.3 (VM)\r\n[0]: Tahiti, 2907 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU/CPU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<strong>#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.</strong>\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.\r\nIf you have OpenCL working on any other device and wish to try ArrayFire, contact us at <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a>.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 19:46:50','2014-07-24 19:46:50','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6192,11,'2014-07-24 20:09:32','2014-07-24 20:09:32','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPU/CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1526.3 (VM)\r\n[0]: Tahiti, 2864 MB, OpenCL Version: 1.2\r\n 1 : AMD FX(tm)-8350 Eight-Core Processor, 7953 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU (OpenCL)</h4>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<strong>#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.</strong>\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.\r\nIf you have OpenCL working on any other device and wish to try ArrayFire, contact us at <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a>.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 20:09:32','2014-07-24 20:09:32','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6193,11,'2014-07-24 21:58:16','2014-07-24 21:58:16','One of ArrayFire\'s biggest features is the ability for code to be written just once and run on a plethora of devices. In this post, we show the outputs of <strong>af::info()</strong> from various devices available to us.\r\n\r\n<h3>Desktop Processors</h3>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD GPU/CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/pavan/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1526.3 (VM)\r\n[0]: Tahiti, 2864 MB, OpenCL Version: 1.2\r\n 1 : AMD FX(tm)-8350 Eight-Core Processor, 7953 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#ed1c24;\">AMD APU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 586ef59)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: AMD Accelerated Parallel Processing, Driver: 1445.5 (VM)\r\n[0]: Spectre, 624 MB, OpenCL Version: 1.2\r\n 1 : AMD A10-7850K APU with Radeon(TM) R7 Graphics, 6885 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel CPU (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.83073\r\n[0]: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz, 7922 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel HD Graphics (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Mac OSX, build a01d9b3)\r\nLicense: Standalone (/Users/arrayfire/arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Apple, Driver: 1.2(Jun  9 2014 13:24:19)\r\n[0]: Iris Pro, 1536 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#0071c5;\">Intel Xeon Phi Coprocessor (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: Intel(R) OpenCL, Driver: 1.2.0.82248\r\n[0]: Intel(R) Many Integrated Core Acceleration Card, 11634 MB, OpenCL Version: 1.2\r\n 1 : Genuine Intel(R) CPU  @ 2.60GHz, 64372 MB, OpenCL Version: 1.2\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: CUDA toolkit 6.0, Driver: 340.21\r\n[0]: Tesla K40c, 11520 MB, CUDA Compute 3.5 \r\n 1 : Quadro K5000, 4096 MB, CUDA Compute 3.0 \r\nCompute Device: [0], Display Device: [1]\r\nMemory Usage: 11406 MB free (11520 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA GPUs (OpenCL)</h4>\r\n<pre>\r\nArrayFire v2.1 (OpenCL, 64-bit Linux, build 4b9115c)\r\nLicense: Standalone (/home/arrayfire/.arrayfire.lic)\r\nAddons: MGL4, DLA, SLA\r\nPlatform: NVIDIA CUDA, Driver: 340.21\r\n[0]: Tesla K40c, 11519 MB, OpenCL Version: 1.1\r\n 1 : Quadro K5000, 4095 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<h3>Embedded Processors</h3>\r\n\r\n<h4 style=\"color:#0084ab;\">ARM Mali GPU (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build 1971d38)\r\nLicense: Standalone (ARM Mali)\r\nAddons: MGL16, DLA, SLA\r\nPlatform: ARM Platform, Driver: 1.1\r\n[0]: Mali-T604, 1998 MB, OpenCL Version: 1.1\r\n</pre>\r\n\r\n<h4 style=\"color:#76b900;\">NVIDIA Tegra K1 (CUDA)</h4>\r\n<pre>\r\nArrayFire v2.1 (CUDA, 32-bit Linux, build 4c3c009)\r\nLicense: Standalone (Tegra)\r\nAddons: MGL16, DLA, SLA\r\nARM\r\n 0 : GK20A, 1747 MB, CUDA Compute 3.2 \r\nMemory Usage: 106 MB free (1747 MB total)\r\n</pre>\r\n\r\n<h4 style=\"color:#db272a;\">Qualcomm Snapdragon SoC (OpenCL) <sup>#</sup></h4>\r\n<pre>\r\nArrayFire v2.1  (OpenCL, 32-bit Linux, build bedc9ca)\r\nLicense: Standalone\r\nAddons: MGL16, DLA, SLA\r\n[0]: QUALCOMM Adreno(TM), 1389 MB, OpenCL Version: 1.1\r\n 1 : QUALCOMM Krait(TM), 1389 MB, OpenCL Version: 1.1\r\nCompute Device: [0]\r\n</pre>\r\n\r\n<strong>#: Experimental versions. Email <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a> for access.</strong>\r\n\r\nThe devices shown above are ones we have in-house for demonstration purposes. This is not an exhaustive list.\r\nIf you have OpenCL working on any other device and wish to try ArrayFire, contact us at <a href=\"mailto:technical@arrayfire.com\" >technical@arrayfire.com</a>.','ArrayFire: Write once, Run anywhere','','inherit','open','open','','6157-revision-v1','','','2014-07-24 21:58:16','2014-07-24 21:58:16','',6157,'http://sandbox.arrayfire.com/6157-revision-v1/',0,'revision','',0),(6194,17795,'2014-07-24 22:03:36','2014-07-24 22:03:36','','ArrayFIre ORB','','inherit','open','open','','orb_lena_arrayfire','','','2014-07-24 22:03:36','2014-07-24 22:03:36','',5885,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png',0,'attachment','image/png',0),(6195,17795,'2014-07-24 22:03:45','2014-07-24 22:03:45','','OpenCV ORB','','inherit','open','open','','orb_lena_opencv','','','2014-07-24 22:03:45','2014-07-24 22:03:45','',5885,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png',0,'attachment','image/png',0),(6196,17795,'2014-07-24 22:56:36','2014-07-24 22:56:36','In <a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a> we talked about Feature Detection. To complement the previous post, we now share some of the preliminary results Feature Description with ORB [1], along with the results for Matching these descriptors.\r\n\r\nThe hardware and software used are the same used in Part 1:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\n\r\nIn Part 1 we have shown that feature detection with FAST [2] scales according to the number of features detected. Different from FAST, the ORB descriptor extractor scales according to the number of pixels of the input image, even though it relies on FAST to detect features (note that the benchmarks for feature description also includes the process of feature detection).\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\n<h3>Descriptor Matching Samples</h3>\r\n\r\nIn this section we show two image samples, matching Lena\'s picture against itself but rotated 90 degrees counterclockwise, one using ArrayFire (top) and the other using OpenCV (bottom). There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" class=\"alignnone size-full wp-image-6194\" /></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" class=\"alignnone size-full wp-image-6195\" /></a>\r\n\r\n<h3>Discussion</h3>\r\n\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nAs said in the beginning of this post, these are preliminary values, there is still more to be done and more improvements on performance might be achieved until the new version of ArrayFire is released.\r\n\r\n<h3>References</h3>\r\n\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-24 22:56:36','2014-07-24 22:56:36','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6200,17796,'2014-07-28 21:49:04','2014-07-28 21:49:04','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\n\nThe results we show in this blog use the same hardware and software used in the previous blog:\n<ul>\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\n	<li>ArrayFire development version</li>\n	<li>OpenCV version 2.4.9</li>\n</ul>\n<h3>Feature Description and Matching Benchmarks</h3>\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB use FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\n\n&nbsp;\n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n<h3>Descriptor Matching Samples</h3>\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\n\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" /></a>\n\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\n<h3>Discussion</h3>\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\n\nAs said in the beginning of this post, these are preliminary values, there is still more to be done and more improvements on performance might be achieved until the new version of ArrayFire is released.\n<h3>References</h3>\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-autosave-v1','','','2014-07-28 21:49:04','2014-07-28 21:49:04','',5885,'http://sandbox.arrayfire.com/5885-autosave-v1/',0,'revision','',0),(6201,17796,'2014-07-28 21:42:25','2014-07-28 21:42:25','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB use FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show two image samples, matching Lena\'s picture against itself but rotated 90 degrees counterclockwise, one using ArrayFire (top) and the other using OpenCV (bottom). There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" /></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nAs said in the beginning of this post, these are preliminary values, there is still more to be done and more improvements on performance might be achieved until the new version of ArrayFire is released.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-28 21:42:25','2014-07-28 21:42:25','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6202,17796,'2014-07-28 21:50:34','2014-07-28 21:50:34','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB use FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" /></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nAs said in the beginning of this post, these are preliminary values, there is still more to be done and more improvements on performance might be achieved until the new version of ArrayFire is released.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-28 21:50:34','2014-07-28 21:50:34','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6203,17794,'2014-07-28 23:10:23','2014-07-28 23:10:23','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\n\nThe results we show in this blog use the same hardware and software used in the previous blog:\n<ul>\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\n	<li>ArrayFire development version</li>\n	<li>OpenCV version 2.4.9</li>\n</ul>\n<h3>Feature Description and Matching Benchmarks</h3>\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\n\n&nbsp;\n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n\n<h3>Descriptor Matching Samples</h3>\n\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\n\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" /></a>\n\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\n<h3>Discussion</h3>\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\n\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\n\n<h3>References</h3>\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-autosave-v1','','','2014-07-28 23:10:23','2014-07-28 23:10:23','',5885,'http://sandbox.arrayfire.com/5885-autosave-v1/',0,'revision','',0),(6204,17794,'2014-07-28 23:11:09','2014-07-28 23:11:09','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\n<h3>Descriptor Matching Samples</h3>\r\n\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFIre ORB\" width=\"1024\" height=\"512\" /></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-28 23:11:09','2014-07-28 23:11:09','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6206,17795,'2014-07-29 14:48:18','2014-07-29 14:48:18','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\n<h3>Descriptor Matching Samples</h3>\r\n\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:48:18','2014-07-29 14:48:18','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6207,17795,'2014-07-29 14:49:53','2014-07-29 14:49:53','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em><!--more--></p>\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:49:53','2014-07-29 14:49:53','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6208,17795,'2014-07-29 14:51:06','2014-07-29 14:51:06','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n&nbsp;\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em><!--more--></p>\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:51:06','2014-07-29 14:51:06','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6209,17795,'2014-07-29 14:52:34','2014-07-29 14:52:34','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" />\r\n<br><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em></br></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:52:34','2014-07-29 14:52:34','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6210,17795,'2014-07-29 14:54:13','2014-07-29 14:54:13','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n<td><nobr><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em></nobr></td>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:54:13','2014-07-29 14:54:13','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6211,17795,'2014-07-29 14:55:20','2014-07-29 14:55:20','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<td><nobr><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em></nobr></td>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:55:20','2014-07-29 14:55:20','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6212,17795,'2014-07-29 14:55:52','2014-07-29 14:55:52','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<td><nobr>\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n</nobr></td>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:55:52','2014-07-29 14:55:52','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6213,17795,'2014-07-29 14:56:23','2014-07-29 14:56:23','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n\r\n<em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a>\r\n\r\n<em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:56:23','2014-07-29 14:56:23','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6214,17795,'2014-07-29 14:57:25','2014-07-29 14:57:25','In a previous blog (<a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Computer Vision in ArrayFire - Part 1</a>) we talked about Feature Detection. In this post we share some of the preliminary results Feature Description with ORB [1] along with the results for Matching these descriptors.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST [2] scales with respect to to the number of features detected. While ORB uses FAST, in practice the ORB descriptor extractor scales based on the pixel count of the input image. The increase in the computational requirements is not due to FAST, but rather due to the additional algorithms that ORB uses.\r\n\r\n&nbsp;\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. To perform these measurements, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, separated by a factor of 10.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n<p style=\"text-align: center;\"><em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested these or other ArrayFire functions.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 14:57:25','2014-07-29 14:57:25','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6215,17728,'2014-07-29 17:03:48','2014-07-29 17:03:48','In the <a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Part 1</a> of this series, we talked about upcoming feature detection algorithms in the ArrayFire library. In this post we show case some of the preliminary results of Feature Description and matching that are under development in the ArrayFire library. Feature description is done using the ORB feature descriptor[1]. The descriptors are matched against a database of features using Hamming distance as the metric.\n\nThe results we show in this blog use the same hardware and software used in the previous blog:\n<ul>\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\n	<li>ArrayFire development version</li>\n	<li>OpenCV version 2.4.9</li>\n</ul>\n\n\n\n<h3>Feature Description and Matching Benchmarks</h3>\nIn Part 1 we showed that feature detection with FAST[2] scales with respect to to the number of features detected. While ORB uses FAST for the feature detection step, it performs additional computations to calculate Harris Corner scores as well as orientation of the features[3]. This results in ORB scaling with the number pixels (meaning it is not bottlenecked by FAST). \n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n\nThe Hamming matcher benchmarks are shown below. For benchmarking purposes, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, each step increasing by an order of magnitude.\n\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\n<h3>Descriptor Matching Samples</h3>\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\n<p style=\"text-align: center;\"><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a></p>\n<p style=\"text-align: center;\"><em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a></p>\n\n<h3>Discussion</h3>\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\n\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested in trying out our upcoming Computer Vision functions in ArrayFire.\n<h3>References</h3>\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.\n[3] http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_orb/py_orb.html','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-autosave-v1','','','2014-07-29 17:03:48','2014-07-29 17:03:48','',5885,'http://sandbox.arrayfire.com/5885-autosave-v1/',0,'revision','',0),(6216,17728,'2014-07-29 16:58:31','2014-07-29 16:58:31','In the <a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Part 1</a> of this series, we talked about upcoming feature detection algorithms in ArrayFire library. In this post we show case some of the preliminary results of Feature Description and matching that are under development in the ArrayFire library. Feature description is done using the ORB feature descriptor[1]. The descriptors are matched against a database of features using Hamming distance as the metric.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST[2] scales with respect to to the number of features detected. While ORB uses FAST for the feature detection step, it performs additional computations to calculate Harris Corner scores as well as orientation of the features[3]. This results in ORB scaling with the number pixels (meaning it is not bottlenecked by FAST). \r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. For benchmarking purposes, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, each step increasing by an order of magnitude.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n<p style=\"text-align: center;\"><em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested in trying out our upcoming Computer Vision functions in ArrayFire.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.\r\n[3] http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_orb/py_orb.html','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 16:58:31','2014-07-29 16:58:31','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6217,17728,'2014-07-29 16:58:59','2014-07-29 16:58:59','In the <a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Part 1</a> of this series, we talked about upcoming feature detection algorithms in the ArrayFire library. In this post we show case some of the preliminary results of Feature Description and matching that are under development in the ArrayFire library. Feature description is done using the ORB feature descriptor[1]. The descriptors are matched against a database of features using Hamming distance as the metric.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul>\r\n\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST[2] scales with respect to to the number of features detected. While ORB uses FAST for the feature detection step, it performs additional computations to calculate Harris Corner scores as well as orientation of the features[3]. This results in ORB scaling with the number pixels (meaning it is not bottlenecked by FAST). \r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. For benchmarking purposes, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, each step increasing by an order of magnitude.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n<p style=\"text-align: center;\"><em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested in trying out our upcoming Computer Vision functions in ArrayFire.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.\r\n[3] http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_orb/py_orb.html','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 16:58:59','2014-07-29 16:58:59','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6218,17728,'2014-07-29 17:05:48','2014-07-29 17:05:48','In the <a href=\"http://sandbox.arrayfire.com/computer-vision-arrayfire-part-1/\">Part 1</a> of this series, we talked about upcoming feature detection algorithms in ArrayFire library. In this post we show case some of the preliminary results of Feature Description and matching that are under development in the ArrayFire library. Feature description is done using the ORB feature descriptor[1]. The descriptors are matched against a database of features using Hamming distance as the metric.\r\n\r\nThe results we show in this blog use the same hardware and software used in the previous blog:\r\n<ul>\r\n	<li>Intel Sandy Bridge Xeon processor with 32 cores (for baseline OpenCV CPU implementation)</li>\r\n	<li>NVIDIA Tesla K20C (for OpenCV and ArrayFire CUDA implementations)</li>\r\n	<li>ArrayFire development version</li>\r\n	<li>OpenCV version 2.4.9</li>\r\n</ul> \r\n\r\n<h3>Feature Description and Matching Benchmarks</h3>\r\nIn Part 1 we showed that feature detection with FAST[2] scales with respect to to the number of features detected. While ORB uses FAST for the feature detection step, it performs additional computations to calculate Harris Corner scores as well as orientation of the features[3]. This results in ORB scaling with the number pixels (meaning it is not bottlenecked by FAST). \r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=303245979\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n\r\nThe Hamming matcher benchmarks are shown below. For benchmarking purposes, we used a set of 500 descriptors as test descriptors (e.g., number of descriptors extracted from an image), being matched to a database containing 500 to 5 million descriptors, each step increasing by an order of magnitude.\r\n\r\n<iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1OqbdY8B8K7z6_trW2qB1lseDREGzVe7V1OJKsPnmUC4/gviz/chartiframe?oid=1730737789\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe>\r\n<h3>Descriptor Matching Samples</h3>\r\nIn this section we show an image matching of the Lena image with a 90 degrees rotation of Lena. The top set uses ArrayFire and the bottom set uses OpenCV. There is also a green rectangle around the matched pictures, that indicated the homography of the detected object.\r\n<p style=\"text-align: center;\"><em>ORB with ArrayFire, 21.6X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\"><img class=\"alignnone size-full wp-image-6194\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_arrayfire.png\" alt=\"ArrayFire ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n<p style=\"text-align: center;\"><em>ORB with OpenCV for CUDA, 16.4X speedup over CPU code.</em>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\"><img class=\"alignnone size-full wp-image-6195\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/orb_lena_opencv.png\" alt=\"OpenCV ORB\" width=\"1024\" height=\"512\" /></a></p>\r\n\r\n<h3>Discussion</h3>\r\nWe see that there is a clear advantage using GPUs over CPUs when it comes to processing time, as stated before in Part 1. By using GPUs, it is possible to do descriptor extraction more than <strong>20 times</strong> faster than with a CPU. Similarly, we can achieve average speedup of about <strong>25 times</strong> for descriptor matching using hamming distance.\r\n\r\nThese are preliminary values. This function is still under development. Please inquire with technical@arrayfire.com if you are interested in trying out our upcoming Computer Vision functions in ArrayFire.\r\n<h3>References</h3>\r\n[1] Rosten, Edward, and Tom Drummond. “Machine learning for high-speed corner detection.” Computer Vision–ECCV 2006. Springer Berlin Heidelberg, 2006. 430-443.\r\n[2] Rublee, Ethan, et al. “ORB: an efficient alternative to SIFT or SURF.” Computer Vision (ICCV), 2011 IEEE International Conference on. IEEE, 2011.\r\n[3] http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_orb/py_orb.html','Computer Vision in ArrayFire - Part 2: Feature Description and Matching','','inherit','open','open','','5885-revision-v1','','','2014-07-29 17:05:48','2014-07-29 17:05:48','',5885,'http://sandbox.arrayfire.com/5885-revision-v1/',0,'revision','',0),(6219,17794,'2014-08-04 18:56:39','2014-08-04 18:56:39','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.2/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make something less trivial. Here are my requirements for the program:\r\n<ul>\r\n	<li>Transfer data from host to device</li>\r\n	<li>Perform an addition on two vectors and store it in a third</li>\r\n	<li>Return the data to the host</li>\r\n	<li>Print the results</li>\r\n</ul>\r\nHere is my attempt:\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n#include <algorithm>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    Context(CL_DEVICE_TYPE_DEFAULT);\r\n    static const unsigned elements = 1000;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. I also took advantage of a few C++11 features including <a href=\"http://en.cppreference.com/w/cpp/language/string_literal\">string literals</a>, and auto. This code was tested on OSX using the clang++ compiler. It should be able to run on Visual Studio 2013 and GCC with little or no changes.\r\n\r\nLets dive into the code. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>cl::Context</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and adds unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n<pre>\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe <code>copy</code> command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the <code>result</code> vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.','Quest for the Smallest OpenCL Program','','publish','open','open','','quest-for-the-smallest-opencl-program','','','2015-08-10 15:00:04','2015-08-10 15:00:04','',0,'http://sandbox.arrayfire.com/?p=6219',0,'post','',8),(6220,17794,'2014-07-31 00:32:14','2014-07-31 00:32:14','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThis is partially due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn order to get a traditional OpenCL program setup, you need to:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nThis can be a daunting task for anyone who is not familiar with the OpenCL API. I was actually surprised how long this list turned out to be. I figured it would consist of 6-7 items.\r\n\r\n&nbsp;\r\n\r\nFortunately the <a href=\"http://www.khronos.org\">Khronos</a> group provides us with a C++','Smallest/Simplest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 00:32:14','2014-07-31 00:32:14','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6221,17794,'2014-07-31 01:03:03','2014-07-31 01:03:03','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nThe simplest OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nAs a thought exercise I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website.\r\n\r\nHere are the results:\r\n\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float *const a,\r\n                    global const float *const b,\r\n                    global       float *const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    copy(c, begin(result), end(result));\r\n\r\n    copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\n','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 01:03:03','2014-07-31 01:03:03','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6223,17794,'2014-07-31 04:29:18','2014-07-31 04:29:18','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nThe simplest OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nAs a thought exercise I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website.\r\n\r\nHere are the results:\r\n\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    copy(c, begin(result), end(result));\r\n\r\n    copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API.\r\n\r\n The C++ OpenCL API provides a much cleaner interface when compared to the C counterpart.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 04:29:18','2014-07-31 04:29:18','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6224,17794,'2014-07-31 16:23:03','2014-07-31 16:23:03','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nThe simplest OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nAs a thought exercise I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n        <li>Transfer data from host to device</li>\r\n        <li>Perform an addition on two vectors and store it in a third</li>\r\n        <li>Return the data to the host</li>\r\n        <li>Print the results</li>\r\n</ul>\r\n\r\nHere are the results:\r\n\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    copy(c, begin(result), end(result));\r\n\r\n    copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API.\r\n\r\n The C++ OpenCL API provides a much cleaner interface when compared to the C counterpart.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 16:23:03','2014-07-31 16:23:03','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6225,17729,'2014-07-31 19:56:56','2014-07-31 19:56:56','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each operation are described below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will be looking at spread and pick filters in this section. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels. How the neighbor is chosen is essentially the difference between spread and pick. Both of these functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6236\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>Image with spread applied[/caption]\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6233\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>After Pick filter[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image. Therefore, giving a high `repeat` input value might result in an image that is completely different from the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6230\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>After adding hurl noise[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved using smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"text-align:left; display: inline-block\">\r\n[caption id=\"attachment_6230\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>Input image[/caption]\r\n </div>\r\n <div style=\"text-align:center; display: inline-block;\">\r\n[caption id=\"attachment_6227\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>Bilateral smoothing[/caption]\r\n </div>\r\n<div style=\"text-align:right; display: inline-block;\">\r\n[caption id=\"attachment_6237\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6237\" /></a>Bilateral with more spatial and chromatic variance[/caption]\r\n </div>\r\n</div>\r\n\r\n<p>As you can see in the above images, bilateral is not quite effective with hurl noise. Increasing spatial radius might help a little but might result in loosing features as shown in the third picture. Next, we will look at Gaussian blur.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6230\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6229\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>After applying Gaussian smoothing[/caption]\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally and the noisy pixels participate in the convolution operation. Hence, Gaussian blur might not be a right candidate always.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6230\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6232\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>After Median filter is applied[/caption]\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6234\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>Prewitt Gradient[/caption]\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6235\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>Sobel Gradient[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6236\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>Boundaries[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input Image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>Difference of Gaussians[/caption]\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','publish','open','open','','image-editing-using-arrayfire-part-2','','','2014-07-31 19:56:56','2014-07-31 19:56:56','',0,'http://sandbox.arrayfire.com/?p=6225',0,'post','',10),(6226,17729,'2014-07-31 16:58:21','2014-07-31 16:58:21','','bdry','','inherit','open','open','','bdry','','','2014-07-31 16:58:21','2014-07-31 16:58:21','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg',0,'attachment','image/jpeg',0),(6227,17729,'2014-07-31 16:58:22','2014-07-31 16:58:22','','bilateral','','inherit','open','open','','bilateral-2','','','2014-07-31 16:58:22','2014-07-31 16:58:22','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg',0,'attachment','image/jpeg',0),(6228,17729,'2014-07-31 16:58:23','2014-07-31 16:58:23','','dog','','inherit','open','open','','dog','','','2014-07-31 16:58:23','2014-07-31 16:58:23','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg',0,'attachment','image/jpeg',0),(6230,17729,'2014-07-31 16:58:25','2014-07-31 16:58:25','','hurl','','inherit','open','open','','hurl','','','2014-07-31 16:58:25','2014-07-31 16:58:25','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg',0,'attachment','image/jpeg',0),(6231,17729,'2014-07-31 16:58:26','2014-07-31 16:58:26','','lena512x512','','inherit','open','open','','lena512x512','','','2014-07-31 16:58:26','2014-07-31 16:58:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg',0,'attachment','image/jpeg',0),(6232,17729,'2014-07-31 16:58:26','2014-07-31 16:58:26','','medfilt','','inherit','open','open','','medfilt-2','','','2014-07-31 16:58:26','2014-07-31 16:58:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg',0,'attachment','image/jpeg',0),(6233,17729,'2014-07-31 16:58:27','2014-07-31 16:58:27','','pick','','inherit','open','open','','pick','','','2014-07-31 16:58:27','2014-07-31 16:58:27','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg',0,'attachment','image/jpeg',0),(6234,17729,'2014-07-31 16:58:28','2014-07-31 16:58:28','','prewitt','','inherit','open','open','','prewitt','','','2014-07-31 16:58:28','2014-07-31 16:58:28','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg',0,'attachment','image/jpeg',0),(6235,17729,'2014-07-31 16:58:29','2014-07-31 16:58:29','','sobel','','inherit','open','open','','sobel','','','2014-07-31 16:58:29','2014-07-31 16:58:29','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg',0,'attachment','image/jpeg',0),(6236,17729,'2014-07-31 16:58:30','2014-07-31 16:58:30','','spread','','inherit','open','open','','spread','','','2014-07-31 16:58:30','2014-07-31 16:58:30','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg',0,'attachment','image/jpeg',0),(6237,17729,'2014-07-31 17:22:03','2014-07-31 17:22:03','','bilateral2','','inherit','open','open','','bilateral2','','','2014-07-31 17:22:03','2014-07-31 17:22:03','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg',0,'attachment','image/jpeg',0),(6238,17729,'2014-07-31 17:24:18','2014-07-31 17:24:18','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each functionality are briefed below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will look at spread and pick filters. Both of these filters are fundamentally same, they replace each pixel in the original image with one of it\'s neighbor pixels, how the neighbor is chosen is essentially the difference between spread and pick.</p>\r\n<p>Both spread and pick functions use a common function given below to select neighbors pixels.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\" alt=\"spread\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\" alt=\"pick\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image when this noise filter is used, hence giving a high repeat input value might land you up with an image that is completely untraceable back to the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved through smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image for you.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\" alt=\"bilateral\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\" alt=\"bilateral\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see the above images, bilateral is not quite effective with hurl noise. Once may increase spatial radius to involves more neighbors in filtering operation, but that will result in loosing features as shown in the third picture. The other smoothing operations can be done using the following code stubs.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\" alt=\"gblur\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\" alt=\"medfilt\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\" alt=\"prewitt\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\" alt=\"sobel\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\" alt=\"bdry\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\" alt=\"dog\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 17:24:18','2014-07-31 17:24:18','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6239,17729,'2014-07-31 17:28:34','2014-07-31 17:28:34','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each functionality are briefed below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will look at spread and pick filters. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels, how the neighbor is chosen is essentially the difference between spread and pick.</p>\r\n<p>Both spread and pick functions use a common function given below to select neighbors pixels.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone medium-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\" alt=\"spread\" width=\"512\" height=\"512\" class=\"alignnone medium-full wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\" alt=\"pick\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image when this noise filter is used, hence giving a high repeat input value might land you up with an image that is completely untraceable back to the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved through smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image for you.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\" alt=\"bilateral\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\" alt=\"bilateral\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see the above images, bilateral is not quite effective with hurl noise. Once may increase spatial radius to involves more neighbors in filtering operation, but that will result in loosing features as shown in the third picture. The other smoothing operations can be done using the following code stubs.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\" alt=\"gblur\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\" alt=\"hurl\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\" alt=\"medfilt\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\" alt=\"prewitt\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\" alt=\"sobel\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\" alt=\"bdry\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\" alt=\"lena512x512\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\" alt=\"dog\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 17:28:34','2014-07-31 17:28:34','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6240,17729,'2014-07-31 17:34:12','2014-07-31 17:34:12','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each functionality are briefed below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will look at spread and pick filters. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels, how the neighbor is chosen is essentially the difference between spread and pick.</p>\r\n<p>Both spread and pick functions use a common function given below to select neighbors pixels.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image when this noise filter is used, hence giving a high repeat input value might land you up with an image that is completely untraceable back to the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved through smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image for you.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see the above images, bilateral is not quite effective with hurl noise. Once may increase spatial radius to involves more neighbors in filtering operation, but that will result in loosing features as shown in the third picture. The other smoothing operations can be done using the following code stubs.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 17:34:12','2014-07-31 17:34:12','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6241,17729,'2014-07-31 17:38:26','2014-07-31 17:38:26','','gblur','Gaussian Blur','inherit','open','open','','gblur','','','2014-07-31 17:38:26','2014-07-31 17:38:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg',0,'attachment','image/jpeg',0),(6242,17729,'2014-07-31 17:39:07','2014-07-31 17:39:07','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each functionality are briefed below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will look at spread and pick filters. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels, how the neighbor is chosen is essentially the difference between spread and pick. Both spread and pick functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image when this noise filter is used, hence giving a high repeat input value might land you up with an image that is completely untraceable back to the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved through smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image for you.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see the above images, bilateral is not quite effective with hurl noise. Once may increase spatial radius to involves more neighbors in filtering operation, but that will result in loosing features as shown in the third picture. The other smoothing operations can be done using the following code stubs.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 17:39:07','2014-07-31 17:39:07','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6243,17729,'2014-07-31 17:41:42','2014-07-31 17:41:42','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each functionality are briefed below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will look at spread and pick filters. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels, how the neighbor is chosen is essentially the difference between spread and pick. Both spread and pick functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image when this noise filter is used, hence giving a high repeat input value might land you up with an image that is completely untraceable back to the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved through smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image for you.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see the above images, bilateral is not quite effective with hurl noise. Once may increase spatial radius to involves more neighbors in filtering operation, but that will result in loosing features as shown in the third picture. The other smoothing operations can be done using the following code stubs.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally. More importantly, as noisy pixels also participate in the convolution operation. Hence, when the noise is too high Gaussian blur isn\'t the right candidate.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 17:41:42','2014-07-31 17:41:42','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6245,17729,'2014-07-31 18:48:53','2014-07-31 18:48:53','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each operation are described below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will be looking at spread and pick filters in this section. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels. How the neighbor is chosen is essentially the difference between spread and pick. Both of these functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image. Therefore, giving a high `repeat` input value might result in an image that is completely different from the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved using smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see in the above images, bilateral is not quite effective with hurl noise. Increasing spatial radius might help a little but might result in loosing features as shown in the third picture. Next, we will look at Gaussian blur.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally and the noisy pixels participate in the convolution operation. Hence, Gaussian blur might not be a right candidate always.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 18:48:53','2014-07-31 18:48:53','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6246,17794,'2014-07-31 18:50:29','2014-07-31 18:50:29','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nAs a thought exercise I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n        <li>Transfer data from host to device</li>\r\n        <li>Perform an addition on two vectors and store it in a third</li>\r\n        <li>Return the data to the host</li>\r\n        <li>Print the results</li>\r\n</ul>\r\n\r\nHere is my attempt:\r\n\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    copy(c, begin(result), end(result));\r\n\r\n    copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n\r\n<pre>\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe copy command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the result vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.\r\n','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 18:50:29','2014-07-31 18:50:29','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6247,17794,'2014-07-31 18:54:27','2014-07-31 18:54:27','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n        <li>Transfer data from host to device</li>\r\n        <li>Perform an addition on two vectors and store it in a third</li>\r\n        <li>Return the data to the host</li>\r\n        <li>Print the results</li>\r\n</ul>\r\n\r\nHere is my attempt:\r\n\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <algorithm>\r\n#include <iostream>\r\n#include <iterator>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\n\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n\r\n<pre>\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe copy command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the result vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.\r\n','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 18:54:27','2014-07-31 18:54:27','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6248,17794,'2014-07-31 18:59:30','2014-07-31 18:59:30','<p>A couple of weeks ago, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, I will be presenting the second part in the series <code>Image Editing using ArrayFire</code>. We will be covering the following operations:</p>\n<ul>\n<li>Image distortion<br /></li>\n<li>Noise addition<br /></li>\n<li>Noise reduction<br /></li>\n<li>Edge filters<br /></li>\n<li>Boundary extraction<br /></li>\n<li>Difference of gaussians</li>\n</ul>\n<p>Code and sample input/outputs corresponding to each operation are described below.</p>\n\n<h4 id=\"image-distortion\">Image distortion</h4>\n<p>We will be looking at spread and pick filters in this section. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels. How the neighbor is chosen is essentially the difference between spread and pick. Both of these functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\n<pre>\narray getRandomNeighbor(const array &in, int windW, int windH)\n{\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\n    array sx = seq(in.dims(0));\n    array sy = seq(in.dims(1));\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\n    array vxx = clamp(vx,0,in.dims(0));\n    array vyy = clamp(vy,0,in.dims(1));\n    array in2 = moddims(in, vx.elements(), 3);\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\n}\n</pre>\n\n<pre>\n/**\n * randomly pick neighbor from given window size and replace the\n * current pixel with the randomly chosen color.\n * No new colors are introduced, unlike hurl.\n */\narray spread(const array &in, int window_width, int window_height)\n{\n    return getRandomNeighbor(in,window_width,window_height);\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\n </div>\n</div>\n<pre>\n/**\n * randomization - controls % of total number of pixels in the image\n * that will be effected by random noise\n * repeat - # of times the process is carried out on the previous steps output\n */\narray pick(const array &in, int randomization, int repeat)\n{\n    int w = in.dims(0);\n    int h = in.dims(1);\n    float f = randomization/100.0f;\n    int dim = (int)(f*w*h);\n    array ret_val = in.copy();\n    for(int i=0;i<repeat;++i) {\n        array idxs  = (w*h)  * randu(dim);\n        array rnd   = getRandomNeighbor(ret_val,1,1);\n        array temp_src = moddims(rnd,w*h,3);\n        array temp_dst = moddims(ret_val,w*h,3);\n        temp_dst(idxs,span) = temp_src(idxs,span);\n        ret_val = moddims(temp_dst,in.dims());\n    }\n    return ret_val;\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\n </div>\n</div>\n\n<h4 id=\"noise-addition\">Noise addition</h4>\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image. Therefore, giving a high `repeat` input value might result in an image that is completely different from the original.</p>\n<pre>\n/**\n * randomization - controls % of total number of pixels in the image\n * that will be effected by random noise\n * repeat - # of times the process is carried out on the previous steps output\n */\narray hurl(const array &in, int randomization, int repeat)\n{\n    int w = in.dims(0);\n    int h = in.dims(1);\n    float f = randomization/100.0f;\n    int dim = (int)(f*w*h);\n    array ret_val = in.copy();\n    array temp = moddims(ret_val,w*h,3);\n    for(int i=0;i<repeat;++i) {\n        array idxs = (w*h)  * randu(dim);\n        array rndR = 255.0f * randu(dim);\n        array rndG = 255.0f * randu(dim);\n        array rndB = 255.0f * randu(dim);\n        temp(idxs,0) = rndR;\n        temp(idxs,1) = rndG;\n        temp(idxs,2) = rndB;\n    }\n    ret_val = moddims(temp,in.dims());\n    return ret_val;\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\n </div>\n</div>\n\n<h4 id=\"noise-reduction\">Noise reduction</h4>\n<p>Noise reduction is typically achieved using smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image.</p> \n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\n </div>\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\n </div>\n<div>\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\n </div>\n</div>\n\n<p>As you can see in the above images, bilateral is not quite effective with hurl noise. Increasing spatial radius might help a little but might result in loosing features as shown in the third picture. Next, we will look at Gaussian blur.</p>\n<pre>\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\n{\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\n    return convolve(in,g);\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\n </div>\n</div>\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally and the noisy pixels participate in the convolution operation. Hence, Gaussian blur might not be a right candidate always.\n<pre>\narray medianfilter(const array &in, int window_width, int window_height)\n{\n    array ret_val(in.dims());\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\n    return ret_val;\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\n </div>\n</div>\nMedian filter seems to do a good job for this type of noise.\n\n<h4 id=\"edge-filters\">Edge filters</h4>\n<p>We will be looking at Sobel and Prewitt filters.</p>\n<pre>\nvoid prewitt(array &mag, array &dir, const array &in)\n{\n    float h1[] = { 1, 1, 1};\n    float h2[] = {-1, 0, 1};\n\n    // Find the gradients\n    array Gy = convolve(3, h2, 3, h1, in)/6;\n    array Gx = convolve(3, h1, 3, h2, in)/6;\n\n    // Find magnitude and direction\n    mag = hypot(Gx, Gy);\n    dir = atan2(Gy, Gx);\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\n </div>\n</div>\n\n<pre>\nvoid sobel(array &mag, array &dir, const array &in)\n{\n    float h1[] = { 1, 2,  1};\n    float h2[] = { 1, 0, -1};\n\n    // Find the gradients\n    array Gy = convolve(3, h2, 3, h1, in)/8;\n    array Gx = convolve(3, h1, 3, h2, in)/8;\n\n    // Find magnitude and direction\n    mag = hypot(Gx, Gy);\n    dir = atan2(Gy, Gx);\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\n </div>\n</div>\n\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\n<pre>\n/**\n * dimensions of the mask control the thickness of the boundary that\n * will be extracted by the following function\n */\narray boundary(const array &in, const array &mask)\n{\n    array ret_val = in - erode(in,mask);\n    normalizeImage(ret_val);\n    return ret_val;\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\n </div>\n</div>\n\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\n<pre>\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\n{\n    array ret_val;\n    int w1 = 2*window_radius1+1;\n    int w2 = 2*window_radius2+1;\n    array g1 = gaussiankernel(w1,w1);\n    array g2 = gaussiankernel(w2,w2);\n    ret_val = (convolve(in,g1)-convolve(in,g2));\n    normalizeImage(ret_val);\n    return ret_val;\n}\n</pre>\n<div style = \"text-align:center\">\n <div style=\"display: inline-block; margin-right: 5px\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\n </div>\n <div style=\"display: inline-block\">\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\n </div>\n</div>\n\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\n<pre>\nvoid normalizeImage(array &in)\n{\n    float min = af::min<float>(in);\n    float max = af::max<float>(in);\n    in = 255.0f*((in-min)/(max-min));\n}\n</pre>\n\n<h4>Conclusion</h4>\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-autosave-v1','','','2014-07-31 18:59:30','2014-07-31 18:59:30','',6225,'http://sandbox.arrayfire.com/6225-autosave-v1/',0,'revision','',0),(6249,17794,'2014-07-31 19:16:45','2014-07-31 19:16:45','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n	<li>Transfer data from host to device</li>\r\n	<li>Perform an addition on two vectors and store it in a third</li>\r\n	<li>Return the data to the host</li>\r\n	<li>Print the results</li>\r\n</ul>\r\nHere is my attempt:\r\n<pre>#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include \r\n#include \r\n#include \r\n#include \r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel&lt;Buffer, Buffer, Buffer&gt;(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator(cout, \", \"));\r\n}\r\n</pre>\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_6241\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img class=\"size-medium wp-image-6241\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"Gaussian Blur\" width=\"300\" height=\"300\" /></a> Gaussian Blur[/caption]\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n<pre>    auto add = make_kernel&lt;Buffer, Buffer, Buffer&gt;(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe copy command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the result vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 19:16:45','2014-07-31 19:16:45','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6250,17794,'2014-07-31 19:18:45','2014-07-31 19:18:45','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n	<li>Transfer data from host to device</li>\r\n	<li>Perform an addition on two vectors and store it in a third</li>\r\n	<li>Return the data to the host</li>\r\n	<li>Print the results</li>\r\n</ul>\r\nHere is my attempt:\r\n<pre>#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include \r\n#include \r\n#include \r\n#include \r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 100;\r\n    vector data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel&lt;Buffer, Buffer, Buffer&gt;(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator(cout, \", \"));\r\n}\r\n</pre>\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n<pre>    auto add = make_kernel&lt;Buffer, Buffer, Buffer&gt;(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe copy command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the result vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 19:18:45','2014-07-31 19:18:45','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6251,17729,'2014-07-31 19:19:34','2014-07-31 19:19:34','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each operation are described below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will be looking at spread and pick filters in this section. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels. How the neighbor is chosen is essentially the difference between spread and pick. Both of these functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image. Therefore, giving a high `repeat` input value might result in an image that is completely different from the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved using smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see in the above images, bilateral is not quite effective with hurl noise. Increasing spatial radius might help a little but might result in loosing features as shown in the third picture. Next, we will look at Gaussian blur.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally and the noisy pixels participate in the convolution operation. Hence, Gaussian blur might not be a right candidate always.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:19:34','2014-07-31 19:19:34','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6252,17729,'2014-07-31 19:20:35','2014-07-31 19:20:35','<p>A couple of weeks back, we did a <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">post</a> on a few image editing functions using ArrayFire library. Today, we shall be doing the second post in the series <code>Image Editing using ArrayFire</code>. We will be looking at the following operations today.</p>\r\n<ul>\r\n<li>Image distortion<br /></li>\r\n<li>Noise addition<br /></li>\r\n<li>Noise reduction<br /></li>\r\n<li>Edge filters<br /></li>\r\n<li>Boundary extraction<br /></li>\r\n<li>Difference of gaussians</li>\r\n</ul>\r\n<p>Code and sample input/outputs corresponding to each operation are described below.</p>\r\n\r\n<h4 id=\"image-distortion\">Image distortion</h4>\r\n<p>We will be looking at spread and pick filters in this section. Both of these filters are fundamentally the same, they replace each pixel in the original image with one of it\'s neighboring pixels. How the neighbor is chosen is essentially the difference between spread and pick. Both of these functions use a common function `getRandomNeighbor` to select neighboring pixels. The code snippet for `getRandomNeighbor` is given below.</p>\r\n<pre>\r\narray getRandomNeighbor(const array &in, int windW, int windH)\r\n{\r\n    array rnd = 2.0f*randu(in.dims(0), in.dims(1))-1.0f;\r\n    array sx = seq(in.dims(0));\r\n    array sy = seq(in.dims(1));\r\n    array vx = tile(sx, 1, in.dims(1)) + floor(rnd*windW);\r\n    array vy = tile(sy.T(), in.dims(0), 1) + floor(rnd*windH);\r\n    array vxx = clamp(vx,0,in.dims(0));\r\n    array vyy = clamp(vy,0,in.dims(1));\r\n    array in2 = moddims(in, vx.elements(), 3);\r\n    return moddims(in2(vyy*in.dims(0)+vxx, span),in.dims());\r\n}\r\n</pre>\r\n\r\n<pre>\r\n/**\r\n * randomly pick neighbor from given window size and replace the\r\n * current pixel with the randomly chosen color.\r\n * No new colors are introduced, unlike hurl.\r\n */\r\narray spread(const array &in, int window_width, int window_height)\r\n{\r\n    return getRandomNeighbor(in,window_width,window_height);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6231\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>Input image[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6236\" class=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spread-300x300.jpg\" alt=\"spread\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6236\" /></a>Image with spread applied[/caption]\r\n </div>\r\n</div>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray pick(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs  = (w*h)  * randu(dim);\r\n        array rnd   = getRandomNeighbor(ret_val,1,1);\r\n        array temp_src = moddims(rnd,w*h,3);\r\n        array temp_dst = moddims(ret_val,w*h,3);\r\n        temp_dst(idxs,span) = temp_src(idxs,span);\r\n        ret_val = moddims(temp_dst,in.dims());\r\n    }\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/pick-300x300.jpg\" alt=\"pick\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6233\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-addition\">Noise addition</h4>\r\n<p>We will at look hurl noise now. Despite the fancy name, what the filter essentially does is replace some of the pixels of the image with random color. New colors are introduced into the resulting image. Therefore, giving a high `repeat` input value might result in an image that is completely different from the original.</p>\r\n<pre>\r\n/**\r\n * randomization - controls % of total number of pixels in the image\r\n * that will be effected by random noise\r\n * repeat - # of times the process is carried out on the previous steps output\r\n */\r\narray hurl(const array &in, int randomization, int repeat)\r\n{\r\n    int w = in.dims(0);\r\n    int h = in.dims(1);\r\n    float f = randomization/100.0f;\r\n    int dim = (int)(f*w*h);\r\n    array ret_val = in.copy();\r\n    array temp = moddims(ret_val,w*h,3);\r\n    for(int i=0;i<repeat;++i) {\r\n        array idxs = (w*h)  * randu(dim);\r\n        array rndR = 255.0f * randu(dim);\r\n        array rndG = 255.0f * randu(dim);\r\n        array rndB = 255.0f * randu(dim);\r\n        temp(idxs,0) = rndR;\r\n        temp(idxs,1) = rndG;\r\n        temp(idxs,2) = rndB;\r\n    }\r\n    ret_val = moddims(temp,in.dims());\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"noise-reduction\">Noise reduction</h4>\r\n<p>Noise reduction is typically achieved using smoothing filters. We will look at bilateral, median and Gaussian blur filters today. Our library has a built-in function(<a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__bilateral.htm\">af::bilateral</a>) that readily does bilateral filtering on an image.</p> \r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n<div>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bilateral2-300x300.jpg\" alt=\"bilateral\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6227\" /></a>\r\n </div>\r\n</div>\r\n\r\n<p>As you can see in the above images, bilateral is not quite effective with hurl noise. Increasing spatial radius might help a little but might result in loosing features as shown in the third picture. Next, we will look at Gaussian blur.</p>\r\n<pre>\r\narray gaussianblur(const array &in, int window_width, int window_height, int sigma)\r\n{\r\n    array g = gaussiankernel(window_width,window_height,sigma,sigma);\r\n    return convolve(in,g);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-mediuml wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/gblur-300x300.jpg\" alt=\"gblur\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6229\" /></a>\r\n </div>\r\n</div>\r\nGaussian blur was able to remove noise to certain extent, but it is blurring out all important features equally and the noisy pixels participate in the convolution operation. Hence, Gaussian blur might not be a right candidate always.\r\n<pre>\r\narray medianfilter(const array &in, int window_width, int window_height)\r\n{\r\n    array ret_val(in.dims());\r\n    ret_val(span,span,0) = medfilt(in(span,span,0),window_width,window_height);\r\n    ret_val(span,span,1) = medfilt(in(span,span,1),window_width,window_height);\r\n    ret_val(span,span,2) = medfilt(in(span,span,2),window_width,window_height);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hurl-300x300.jpg\" alt=\"hurl\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6230\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/medfilt-300x300.jpg\" alt=\"medfilt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6232\" /></a>\r\n </div>\r\n</div>\r\nMedian filter seems to do a good job for this type of noise.\r\n\r\n<h4 id=\"edge-filters\">Edge filters</h4>\r\n<p>We will be looking at Sobel and Prewitt filters.</p>\r\n<pre>\r\nvoid prewitt(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 1, 1};\r\n    float h2[] = {-1, 0, 1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/6;\r\n    array Gx = convolve(3, h1, 3, h2, in)/6;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/prewitt-300x300.jpg\" alt=\"prewitt\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6234\" /></a>\r\n </div>\r\n</div>\r\n\r\n<pre>\r\nvoid sobel(array &mag, array &dir, const array &in)\r\n{\r\n    float h1[] = { 1, 2,  1};\r\n    float h2[] = { 1, 0, -1};\r\n\r\n    // Find the gradients\r\n    array Gy = convolve(3, h2, 3, h1, in)/8;\r\n    array Gx = convolve(3, h1, 3, h2, in)/8;\r\n\r\n    // Find magnitude and direction\r\n    mag = hypot(Gx, Gy);\r\n    dir = atan2(Gy, Gx);\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sobel-300x300.jpg\" alt=\"sobel\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6235\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"boundary-extraction\">Boundary extraction</h4>\r\n<p>The following code snippet extracts boundaries in an image using erosion morphological operator.</p>\r\n<pre>\r\n/**\r\n * dimensions of the mask control the thickness of the boundary that\r\n * will be extracted by the following function\r\n */\r\narray boundary(const array &in, const array &mask)\r\n{\r\n    array ret_val = in - erode(in,mask);\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bdry-300x300.jpg\" alt=\"bdry\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6226\" /></a>\r\n </div>\r\n</div>\r\n\r\n<h4 id=\"difference-of-gaussians\">Difference of gaussians</h4>\r\n<pre>\r\narray diffOfGaussians(const array &in, int window_radius1, int window_radius2)\r\n{\r\n    array ret_val;\r\n    int w1 = 2*window_radius1+1;\r\n    int w2 = 2*window_radius2+1;\r\n    array g1 = gaussiankernel(w1,w1);\r\n    array g2 = gaussiankernel(w2,w2);\r\n    ret_val = (convolve(in,g1)-convolve(in,g2));\r\n    normalizeImage(ret_val);\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/lena512x512-300x300.jpg\" alt=\"lena512x512\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6231\" /></a>\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/dog-300x300.jpg\" alt=\"dog\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-6228\" /></a>\r\n </div>\r\n</div>\r\n\r\nLast two sections use a utility function `normalizeImage` that basically re-scales the pixels values to [0-255] range.\r\n<pre>\r\nvoid normalizeImage(array &in)\r\n{\r\n    float min = af::min<float>(in);\r\n    float max = af::max<float>(in);\r\n    in = 255.0f*((in-min)/(max-min));\r\n}\r\n</pre>\r\n\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>. Hope, you guys are enjoying this series.','Image editing using ArrayFire: Part 2','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:20:35','2014-07-31 19:20:35','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6253,17794,'2014-07-31 19:22:29','2014-07-31 19:22:29','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n	<li>Transfer data from host to device</li>\r\n	<li>Perform an addition on two vectors and store it in a third</li>\r\n	<li>Return the data to the host</li>\r\n	<li>Print the results</li>\r\n</ul>\r\nHere is my attempt:\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n#include <algorithm>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 1000;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n<pre>\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe copy command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the result vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 19:22:29','2014-07-31 19:22:29','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6254,17794,'2014-07-31 19:23:28','2014-07-31 19:23:28','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\r\n\r\nThe verbosity is due to the low level nature of OpenCL. It is written in the C programming language; the <a href=\"http://joelonsoftware.com/articles/CollegeAdvice.html\">lingua franca</a> of programming languages. While this allows you to run an OpenCL program on virtually any platform, it has some disadvantages.\r\n\r\nIn a typical OpenCL program must perform:\r\n<ol>\r\n	<li>Query for the platform</li>\r\n	<li>Get the device IDs from the platform</li>\r\n	<li>Create a context from a set of device IDs</li>\r\n	<li>Create a command queue from the context</li>\r\n	<li>Create buffer objects for your data</li>\r\n	<li>Transfer the data to the buffer</li>\r\n	<li>Create and build a program from source</li>\r\n	<li>Extract the kernels</li>\r\n	<li>Launch the kernels</li>\r\n	<li>Transfer the data to the host</li>\r\n</ol>\r\nWow that was longer than I thought it would be. As you can imagine this can be a daunting task for anyone who is not familiar with the OpenCL API.\r\n\r\nFor kicks and giggles I decided to create the smallest OpenCL program with a focus on simplicity and readability. I am going to make use of the excellent <a title=\"OpenCL C++ header\" href=\"http://www.khronos.org/registry/cl/api/1.1/cl.hpp\" target=\"_blank\">C++ API</a> from the <a title=\"Khronos Website\" href=\"http://www.khronos.org\">Khronos</a> website. Technically you can create a program that transfers to and from the device but I wanted to make it less trivial. Here were my requirements for the program:\r\n<ul>\r\n	<li>Transfer data from host to device</li>\r\n	<li>Perform an addition on two vectors and store it in a third</li>\r\n	<li>Return the data to the host</li>\r\n	<li>Print the results</li>\r\n</ul>\r\nHere is my attempt:\r\n<pre>\r\n#define __CL_ENABLE_EXCEPTIONS\r\n#include \"cl.hpp\"\r\n#include <vector>\r\n#include <iostream>\r\n#include <iterator>\r\n#include <algorithm>\r\n\r\nusing namespace cl;\r\nusing namespace std;\r\n\r\nint main(int argc, char* argv[]) {\r\n    clCreateContextFromType({0}, CL_DEVICE_TYPE_DEFAULT, nullptr, nullptr, nullptr);\r\n    static const unsigned elements = 1000;\r\n    vector<float> data(elements, 5);\r\n    Buffer a(begin(data), end(data), true, false);\r\n    Buffer b(begin(data), end(data), true, false);\r\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\r\n\r\n    Program addProg(R\"d(\r\n        kernel\r\n        void add(   global const float * restrict const a,\r\n                    global const float * restrict const b,\r\n                    global       float * restrict const c) {\r\n            unsigned idx = get_global_id(0);\r\n            c[idx] = a[idx] + b[idx];\r\n        }\r\n    )d\", true);\r\n\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n\r\n    vector<float> result(elements);\r\n    cl::copy(c, begin(result), end(result));\r\n\r\n    std::copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\r\n}\r\n</pre>\r\nNot bad eh? The biggest savings were realized by making use of the default platform, context, command queue objects in the C++ API. A default context can be created by passing <code>CL_DEVICE_TYPE_DEFAULT</code> to the <code>clCreateContextFromType</code> function. This allows you to call several OpenCL functions without specifying a context. In many cases managing a context is not necessary and add unnecessary overhead to the code.\r\n\r\nI am also taking advantage of the special <code>Buffer</code> constructors in the C++ API which take iterators as inputs. This allows you to allocate the correct amount of memory and transfer the data with one call.\r\n\r\nI especially like the <code>make_kernel</code> function in the C++ API. It is a function which creates a functor(an object which overloads the parenthesis operator). Lets take a look at how it is used.\r\n<pre>\r\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\r\n    add(EnqueueArgs(elements), a, b, c);\r\n</pre>\r\n<code>make_kernel</code> is a template function which takes the program object and the name of the kernel as arguments. The template parameters are the type of the input parameters of the kernel. This function returns a functor which takes an <code>EnqueueArgs</code> object as well as three <code>Buffer</code> objects. The <code>EnqueueArgs</code> object can be used to set the launch configuration of the kernel. In this case I took advantage of the default command queue but that can also be set using the <code>EnqueueArgs</code> object.\r\n\r\nThe <code>copy</code> command can be used to transfer the data to and from the device. In this case it transfers the data from the <code>c</code> buffer into the <code>result</code> vector.\r\n\r\nThe C++ OpenCL API provides numerous abstractions over the C counterpart. It is also easy to mix the C and C++ interface in the same program. I have yet to find a functionality which is missing from the C++ API. I would encourage everyone to check out the <a href=\"http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf\">C++ Wrapper API</a> for OpenCL.','Quest for the Smallest OpenCL Program','','inherit','open','open','','6219-revision-v1','','','2014-07-31 19:23:28','2014-07-31 19:23:28','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),