(6255,17729,'2014-07-31 19:31:36','2014-07-31 19:31:36','<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=\"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; margin-right: 5px\">\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>\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>[/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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:31:36','2014-07-31 19:31:36','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6256,17729,'2014-07-31 19:32:36','2014-07-31 19:32:36','<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=\"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; margin-right: 5px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:32:36','2014-07-31 19:32:36','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6257,17794,'2014-07-31 19:32:40','2014-07-31 19:32:40','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 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>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:32:40','2014-07-31 19:32:40','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6258,17729,'2014-07-31 19:33:55','2014-07-31 19:33:55','<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=\"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<br/>\r\n <div style=\"display: inline-block; margin-right: 5px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:33:55','2014-07-31 19:33:55','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6259,17729,'2014-07-31 19:34:32','2014-07-31 19:34:32','<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=\"display: inline-block; margin-right: 1px\">\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; margin-right: 1px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:34:32','2014-07-31 19:34:32','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6260,17729,'2014-07-31 19:35:16','2014-07-31 19:35:16','<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=\"display: inline-block; margin-right: 1px\">\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; margin-right: 10px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:35:16','2014-07-31 19:35:16','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6261,17729,'2014-07-31 19:35:33','2014-07-31 19:35:33','<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=\"display: inline-block; margin-right: 1px\">\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; margin-right: 100px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:35:33','2014-07-31 19:35:33','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6262,17729,'2014-07-31 19:36:23','2014-07-31 19:36:23','<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=\"display: inline-block; margin-right: 1px\">\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; margin-right: 1px\">\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>\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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:36:23','2014-07-31 19:36:23','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6263,17729,'2014-07-31 19:37:45','2014-07-31 19:37:45','<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>Difference of Gaussians[/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>[/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>[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:37:45','2014-07-31 19:37:45','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6264,17729,'2014-07-31 19:40:31','2014-07-31 19:40:31','<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>Difference of Gaussians[/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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:40:31','2014-07-31 19:40:31','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6265,17729,'2014-07-31 19:41:05','2014-07-31 19:41:05','<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','','inherit','open','open','','6225-revision-v1','','','2014-07-31 19:41:05','2014-07-31 19:41:05','',6225,'http://sandbox.arrayfire.com/6225-revision-v1/',0,'revision','',0),(6269,17796,'2014-08-08 17:31:04','2014-08-08 17:31:04','Every so often people come up to us and ask, \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\" While compilers have made massive progress in the last two decades, they are still nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a \"one-size-fits-all\" solution that needs to be able to deal with any and all input, whereas HPC programmers can be thought of as a designer-fitted solution. Application expertise brings a lot to the table that compilers cannot compete with:\r\n<ul>\r\n	<li>Our past experiences have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithms used for social network analysis have random memory access patterns that compilers cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on when or if loop unrolling is necessary, if SIMD would be beneficial, selecting the number of threads that should be used (which can be directly related to the memory footprint) and much more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allowes the application designer to decide what parallel granularity and which scheduler should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads—this does not ensure load-balancing as various iterations of the loop may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall that each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing computational library, check out ArrayFire!','Domain Expertise Vs. Compilers','','publish','open','open','','domain-expertise-vs-compilers','','','2014-08-08 18:27:09','2014-08-08 18:27:09','',0,'http://sandbox.arrayfire.com/?p=6269',0,'post','',2),(6270,17796,'2014-08-04 13:19:30','2014-08-04 13:19:30','Every so often people come up to us and ask: \"Aren\'t you guys concerned that compilers will put you of business?\" or \"Can\'t a compiler do the same thing that you guys are doing?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC specialists can be thought of as designer-fitted solution.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-04 13:19:30','2014-08-04 13:19:30','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6271,17796,'2014-08-04 13:24:45','2014-08-04 13:24:45','Every so often people come up to us and ask: \"Aren\'t you guys concerned that compilers will put you of business?\" or \"Can\'t a compiler do the same thing that you guys are doing?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC specialists can be thought of as designer-fitted solution. <del>What this really means is that we can tailor a  high performing solution for your specific problem. </del>\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-04 13:24:45','2014-08-04 13:24:45','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6272,17796,'2014-08-04 13:53:08','2014-08-04 13:53:08','Every so often people come up to us and ask: \"Aren\'t you guys concerned that compilers will put you of business?\" or \"Can\'t a compiler do the same thing that you guys are doing?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC specialists can be thought of as designer-fitted solution. <del>What this really means is that we can tailor a  high performing solution for your specific problem. </del>\r\n\r\nAn application expert brings a lot to the table that a compiler simply cannot\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-04 13:53:08','2014-08-04 13:53:08','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6275,17796,'2014-08-04 17:34:33','2014-08-04 17:34:33','Every so often people come up to us and ask: \"Aren\'t you guys concerned that compilers will put you of business?\" or \"Can\'t a compiler do the same thing that you guys are doing?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC specialists can be thought of as designer-fitted solution.\r\n\r\nApplication experts bring a lot to the table that a compiler cannot compete with:\r\n<ul>\r\n	<li>Memory access patterns - while some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random access patterns.</li>\r\n	<li>Data familiarity - a basic understanding of the data set which can help in deciding if 1) a loop should be unrolled, 2) SIMD instructions should be used, 3) number of threads that should be used and more.</li>\r\n	<li>Load balancing - APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the type of scheduler to use. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue.</li>\r\n	<li>The increase in the number of architectures has increased the number of programming languages and models. Each system requires a different set of optimizations and the there simply are not enough compiler people to support all the necessary changes to achieve maximal system utilization.</li>\r\n	<li>As compilers</li>\r\n</ul>\r\nThis blog by no means discourages past or future compiler advances. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-04 17:34:33','2014-08-04 17:34:33','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6277,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.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 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>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-08-04 18:56:39','2014-08-04 18:56:39','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6278,17728,'2014-08-05 05:51:48','2014-08-05 05:51:48','I have heard many complaints about the verbosity of the OpenCL API. This claim in not unwarranted.\n\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.\n\nIn a typical OpenCL program must:\n<ol>\n	<li>Query for the platform</li>\n	<li>Get the device IDs from the platform</li>\n	<li>Create a context from a set of device IDs</li>\n	<li>Create a command queue from the context</li>\n	<li>Create buffer objects for your data</li>\n	<li>Transfer the data to the buffer</li>\n	<li>Create and build a program from source</li>\n	<li>Extract the kernels</li>\n	<li>Launch the kernels</li>\n	<li>Transfer the data to the host</li>\n</ol>\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.\n\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 something less trivial. Here are my requirements for the program:\n<ul>\n	<li>Transfer data from host to device</li>\n	<li>Perform an addition on two vectors and store it in a third</li>\n	<li>Return the data to the host</li>\n	<li>Print the results</li>\n</ul>\nHere is my attempt:\n<pre>\n#define __CL_ENABLE_EXCEPTIONS\n#include \"cl.hpp\"\n#include <vector>\n#include <iostream>\n#include <iterator>\n#include <algorithm>\n\nusing namespace cl;\nusing namespace std;\n\nint main(int argc, char* argv[]) {\n    Context(CL_DEVICE_TYPE_DEFAULT);\n    static const unsigned elements = 1000;\n    vector<float> data(elements, 5);\n    Buffer a(begin(data), end(data), true, false);\n    Buffer b(begin(data), end(data), true, false);\n    Buffer c(CL_MEM_READ_WRITE, elements * sizeof(float));\n\n    Program addProg(R\"d(\n        kernel\n        void add(   global const float * restrict const a,\n                    global const float * restrict const b,\n                    global       float * restrict const c) {\n            unsigned idx = get_global_id(0);\n            c[idx] = a[idx] + b[idx];\n        }\n    )d\", true);\n\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\n    add(EnqueueArgs(elements), a, b, c);\n\n    vector<float> result(elements);\n    cl::copy(c, begin(result), end(result));\n\n    std::copy(begin(result), end(result), ostream_iterator<float>(cout, \", \"));\n}\n</pre>\n\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.\n\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.\n\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.\n\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.\n<pre>\n    auto add = make_kernel<Buffer, Buffer, Buffer>(addProg, \"add\");\n    add(EnqueueArgs(elements), a, b, c);\n</pre>\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.\n\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.\n\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-autosave-v1','','','2014-08-05 05:51:48','2014-08-05 05:51:48','',6219,'http://sandbox.arrayfire.com/6219-autosave-v1/',0,'revision','',0),(6279,17728,'2014-08-05 05:51:51','2014-08-05 05:51:51','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.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 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','','inherit','open','open','','6219-revision-v1','','','2014-08-05 05:51:51','2014-08-05 05:51:51','',6219,'http://sandbox.arrayfire.com/6219-revision-v1/',0,'revision','',0),(6281,17796,'2014-08-05 17:01:24','2014-08-05 17:01:24','Every so often people come up to us and ask: \"Aren\'t you guys concerned that compilers will put you of business?\" or \"Can\'t a compiler do the same thing that you guys are doing?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with:\r\n<ul>\r\n	<li>Memory access patterns - while some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Data familiarity - a basic understanding of the data set which can help in decide on different optimizations 1) loop unrolling, 2) SIMD usage, 3) number of threads that should be used, 4) memory footprint and more.</li>\r\n	<li>Load balancing - APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the type of scheduler to use. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue.</li>\r\n	<li>The increase in the number of architectures has increased the number of programming languages and models. Each system requires a different set of optimizations and the there simply are not enough compiler people to support all the necessary changes to achieve maximal system utilization. Further, application expertise can help decide the right system for the problem at hand.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing OpenCL package, ArrayFire is your solution!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-05 17:01:24','2014-08-05 17:01:24','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6282,17796,'2014-08-05 17:12:46','2014-08-05 17:12:46','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough to replaces HPC programmers?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with:\r\n<ul>\r\n	<li>Memory access patterns - while some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Data familiarity - a basic understanding of the data set which can help in decide on different optimizations 1) loop unrolling, 2) SIMD usage, 3) number of threads that should be used, 4) memory footprint and more.</li>\r\n	<li>Load balancing - APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the type of scheduler to use. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue.</li>\r\n	<li>The increase in the number of architectures has increased the number of programming languages and models. Each system requires a different set of optimizations and the there simply are not enough compiler people to support all the necessary changes to achieve maximal system utilization. Further, application expertise can help decide the right system for the problem at hand.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.  So if you are looking for a high performing (OpenCL --&gt; GPGPU ?) package, ArrayFire is your solution!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-05 17:12:46','2014-08-05 17:12:46','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6283,17796,'2014-08-05 17:25:57','2014-08-05 17:25:57','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough to replaces HPC programmers?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.  So if you are looking for a high performing (OpenCL --&gt; GPGPU ?) package, ArrayFire is your solution!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-05 17:25:57','2014-08-05 17:25:57','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6284,17796,'2014-08-05 17:26:23','2014-08-05 17:26:23','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough to replaces HPC programmers?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.\r\n\r\nSo if you are looking for a high performing (OpenCL --&gt; GPGPU ?) package, ArrayFire is your solution!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-05 17:26:23','2014-08-05 17:26:23','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6285,17728,'2014-08-07 20:20:58','2014-08-07 20:20:58','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.\r\n\r\nSo if you are looking for a high performing computational library, check out ArrayFire!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-autosave-v1','','','2014-08-07 20:20:58','2014-08-07 20:20:58','',6269,'http://sandbox.arrayfire.com/6269-autosave-v1/',0,'revision','',0),(6286,17728,'2014-08-05 17:57:34','2014-08-05 17:57:34','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.\r\n\r\nSo if you are looking for a high performing (OpenCL --&gt; GPGPU ?) package, ArrayFire is your solution!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-05 17:57:34','2014-08-05 17:57:34','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6287,17796,'2014-08-05 18:48:36','2014-08-05 18:48:36','<blockquote>\"The library approach is the simplest and works by calling functions in a library that has been accelerated by someone else. Many of the latest math libraries belong to this category. As long as most of the computation takes place inside the library code, this approach is very successful. It allows a few expert library writers to enable the acceleration of a large number of applications.\" -http://www.hpcwire.com/2014/01/09/future-accelerator-programming/</blockquote>\r\nSince it is trivial to use, programmers will employ the library approach whenever possible. However, this hinges on the availability of appropriate library functions, which are easy to provide in well-defined and mature domains such as standard matrix operations (BLAS) but hard to do for emerging areas or unstructured computations.','Library Approach','','inherit','open','open','','4690-autosave-v1','','','2014-08-05 18:48:36','2014-08-05 18:48:36','',4690,'http://sandbox.arrayfire.com/4690-autosave-v1/',0,'revision','',0),(6288,17728,'2014-08-07 20:21:03','2014-08-07 20:21:03','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". Fortunately for us and a lot of the people in high-performance computing the answer is simply \"NO\".  While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.\r\n\r\nSo if you are looking for a high performing computational library, check out ArrayFire!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-07 20:21:03','2014-08-07 20:21:03','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6289,17796,'2014-08-07 20:28:09','2014-08-07 20:28:09','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". While compilers have made massive progress in the last two decades, they are nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a one-size-fits-all solution that need to deal with any and all input, whereas HPC programmers can be thought of as designer-fitted solution.\r\n\r\nApplication expertise brings a lot to the table that a compiler cannot compete with.\r\n<ul>\r\n	<li>Our past experience have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithm used for social network analysis have random memory access patterns that a compiler cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on using loop unrolling, SIMD usage, selection of the number of threads that should be used (which can be directly related to the memory footprint) and more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allow the program designer to decide on the parallel granularity and the scheduler which should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as each iteration of the thread may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog is not to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise.\r\n\r\nSo if you are looking for a high performing computational library, check out ArrayFire!\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-07 20:28:09','2014-08-07 20:28:09','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6290,17796,'2014-08-08 17:58:06','2014-08-08 17:58:06','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". While compilers have made massive progress in the last two decades, they are still nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a \"one-size-fits-all\" solution that needs to be able to deal with any and all input, whereas HPC programmers can be thought of as a designer-fitted solution. Application expertise brings a lot to the table that compilers cannot compete with:\n<ul>\n	<li>Our past experiences have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithms used for social network analysis have random memory access patterns that compilers cannot optimize.</li>\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on when or if loop unrolling is necessary, if SIMD would be beneficial, selecting the number of threads that should be used (which can be directly related to the memory footprint) and much more.</li>\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allowes the application designer to decide what parallel granularity and which scheduler should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as various iterations of the loop may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall that each system requires a different set of optimizations.</li>\n</ul>\nBy no means is the purpose of this blog to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing computational library, check out ArrayFire!','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-autosave-v1','','','2014-08-08 17:58:06','2014-08-08 17:58:06','',6269,'http://sandbox.arrayfire.com/6269-autosave-v1/',0,'revision','',0),(6291,17796,'2014-08-08 17:58:24','2014-08-08 17:58:24','Every so often people come up to us and ask: \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\". While compilers have made massive progress in the last two decades, they are still nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a \"one-size-fits-all\" solution that needs to be able to deal with any and all input, whereas HPC programmers can be thought of as a designer-fitted solution. Application expertise brings a lot to the table that compilers cannot compete with:\r\n<ul>\r\n	<li>Our past experiences have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithms used for social network analysis have random memory access patterns that compilers cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on when or if loop unrolling is necessary, if SIMD would be beneficial, selecting the number of threads that should be used (which can be directly related to the memory footprint) and much more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allowes the application designer to decide what parallel granularity and which scheduler should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads - this does not ensure load-balancing as various iterations of the loop may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall that each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing computational library, check out ArrayFire!','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-08 17:58:24','2014-08-08 17:58:24','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6292,7,'2014-08-08 18:26:11','2014-08-08 18:26:11','Every so often people come up to us and ask, \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\" While compilers have made massive progress in the last two decades, they are still nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a \"one-size-fits-all\" solution that needs to be able to deal with any and all input, whereas HPC programmers can be thought of as a designer-fitted solution. Application expertise brings a lot to the table that compilers cannot compete with:\n<ul>\n	<li>Our past experiences have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithms used for social network analysis have random memory access patterns that compilers cannot optimize.</li>\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on when or if loop unrolling is necessary, if SIMD would be beneficial, selecting the number of threads that should be used (which can be directly related to the memory footprint) and much more.</li>\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allowes the application designer to decide what parallel granularity and which scheduler should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads—this does not ensure load-balancing as various iterations of the loop may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall that each system requires a different set of optimizations.</li>\n</ul>\nBy no means is the purpose of this blog to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing computational library, check out ArrayFire!','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-autosave-v1','','','2014-08-08 18:26:11','2014-08-08 18:26:11','',6269,'http://sandbox.arrayfire.com/6269-autosave-v1/',0,'revision','',0),(6293,7,'2014-08-08 18:27:09','2014-08-08 18:27:09','Every so often people come up to us and ask, \"Aren\'t compilers and compiler directives good enough for HPC applications?\" or \"Won\'t a compiler accomplish that for us?\" While compilers have made massive progress in the last two decades, they are still nowhere near the point of putting us and many other HPC programmers out of business. Compilers are still a \"one-size-fits-all\" solution that needs to be able to deal with any and all input, whereas HPC programmers can be thought of as a designer-fitted solution. Application expertise brings a lot to the table that compilers cannot compete with:\r\n<ul>\r\n	<li>Our past experiences have helped us optimize applications that have irregular memory access patterns. While some applications such as matrix applications have regular and simple memory access patterns, other applications such as graph algorithms used for social network analysis have random memory access patterns that compilers cannot optimize.</li>\r\n	<li>Our familiarity with data set at hand can help us with the optimizing the application and find algorithmic bottlenecks. Our knowledge can help us decide on when or if loop unrolling is necessary, if SIMD would be beneficial, selecting the number of threads that should be used (which can be directly related to the memory footprint) and much more.</li>\r\n	<li>Our knowledge on the work required by the algorithm(s) can help us in load balancing. APIs such as OpenMP offer directives that allowes the application designer to decide what parallel granularity and which scheduler should be used. The static scheduler offers a straightforward and simple partitioning of the loop across the threads—this does not ensure load-balancing as various iterations of the loop may require a different amount of work. The dynamic scheduler on the other hand allows finer grain partitioning of the work; in practice this scheduler has limited scalability due the nature of multiple threads trying to access the same work queue. A domain expert can help decide which scheduler should be used or how to partition the work equally. A domain expert can design an online load-balancing mechanism that will decide on the partitioning scheme based on the input data.</li>\r\n	<li>Our awareness of the increasing number of architectures helps us fit the right solution to the right system. Recall that each system requires a different set of optimizations.</li>\r\n</ul>\r\nBy no means is the purpose of this blog to reduce the significance or impact that compilers have had on the computing. Rather this blog focuses on the reason that compilers simply cannot offer a high enough level of system utilization that domain expertise does offer! ArrayFire was designed by people with domain expertise. So if you are looking for a high performing computational library, check out ArrayFire!','Domain Expertise Vs. Compilers','','inherit','open','open','','6269-revision-v1','','','2014-08-08 18:27:09','2014-08-08 18:27:09','',6269,'http://sandbox.arrayfire.com/6269-revision-v1/',0,'revision','',0),(6297,18132,'2014-08-13 17:49:27','2014-08-13 17:49:27','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>. Note that you can have gcc include these libraries statically by including the flags, <code>-static-libgcc</code> and <code>-static-libstdc++</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\r\n\r\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','publish','open','open','','cross-compile-to-windows-from-linux','','','2014-08-18 10:29:36','2014-08-18 10:29:36','',0,'http://sandbox.arrayfire.com/?p=6297',0,'post','',7),(6298,18132,'2014-08-09 15:09:55','2014-08-09 15:09:55','On Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello.exe\r\n</pre>\r\n<img src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile for Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:09:55','2014-08-09 15:09:55','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6299,18132,'2014-08-09 15:12:24','2014-08-09 15:12:24','On Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n<img src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:12:24','2014-08-09 15:12:24','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6300,18132,'2014-08-09 15:14:39','2014-08-09 15:14:39','On Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n\r\nFrom, <a title=\"cross compiling tinc for windows 64\" href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/</a>.\r\n</pre>\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:14:39','2014-08-09 15:14:39','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6301,18132,'2014-08-09 15:15:51','2014-08-09 15:15:51','On Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:15:51','2014-08-09 15:15:51','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6302,18132,'2014-08-09 15:16:40','2014-08-09 15:16:40','On Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n<br>\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:16:40','2014-08-09 15:16:40','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6303,18132,'2014-08-09 15:17:07','2014-08-09 15:17:07','On Debian and variants,\r\n\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:17:07','2014-08-09 15:17:07','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6304,18132,'2014-08-09 15:17:22','2014-08-09 15:17:22','On Debian and variants,\r\n\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<br><br>\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:17:22','2014-08-09 15:17:22','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6305,18132,'2014-08-09 15:17:41','2014-08-09 15:17:41','On Debian and variants,\r\n\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:17:41','2014-08-09 15:17:41','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6306,18132,'2014-08-09 15:17:54','2014-08-09 15:17:54','On Debian and variants,\r\n\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<br><br>\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n\r\nIn any case, I hope this is helpful. I\'m going back under my rock, now.','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:17:54','2014-08-09 15:17:54','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6307,18132,'2014-08-09 15:45:58','2014-08-09 15:45:58','On Debian and variants,\r\n\r\n<pre>sudo apt-get install mingw-w64\r\ni686-w64-mingw32-gcc hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<br><br>\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver.\r\n','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-09 15:45:58','2014-08-09 15:45:58','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6308,17729,'2014-08-10 18:54:52','2014-08-10 18:54:52','','adapmean','Adaptive Threshold with Mean as local operator','inherit','open','open','','adapmean','','','2014-08-10 18:54:52','2014-08-10 18:54:52','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg',0,'attachment','image/jpeg',0),(6309,17729,'2014-08-10 18:54:53','2014-08-10 18:54:53','','adapmed','Adaptive Threshold with Median as local operator','inherit','open','open','','adapmed','','','2014-08-10 18:54:53','2014-08-10 18:54:53','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg',0,'attachment','image/jpeg',0),(6310,17729,'2014-08-10 18:54:54','2014-08-10 18:54:54','','adapmma','Adaptive Threshold with Minimum & Maximum as local operator','inherit','open','open','','adapmma','','','2014-08-10 18:54:54','2014-08-10 18:54:54','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg',0,'attachment','image/jpeg',0),(6311,17729,'2014-08-10 18:54:55','2014-08-10 18:54:55','','arrow','Input','inherit','open','open','','arrow','','','2014-08-10 18:54:55','2014-08-10 18:54:55','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg',0,'attachment','image/jpeg',0),(6312,17729,'2014-08-10 18:54:58','2014-08-10 18:54:58','','bimodal','Input image with Bimodal histogram','inherit','open','open','','bimodal','','','2014-08-10 18:54:58','2014-08-10 18:54:58','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg',0,'attachment','image/jpeg',0),(6313,17729,'2014-08-10 18:54:59','2014-08-10 18:54:59','','binary','Simple binary threshold','inherit','open','open','','binary','','','2014-08-10 18:54:59','2014-08-10 18:54:59','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg',0,'attachment','image/jpeg',0),(6314,17729,'2014-08-10 18:55:00','2014-08-10 18:55:00','','emboss_haz','Emboss with high azimuth angle','inherit','open','open','','emboss_haz','','','2014-08-10 18:55:00','2014-08-10 18:55:00','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg',0,'attachment','image/jpeg',0),(6315,17729,'2014-08-10 18:55:03','2014-08-10 18:55:03','','emboss_hdepth','Emboss with high depth value','inherit','open','open','','emboss_hdepth','','','2014-08-10 18:55:03','2014-08-10 18:55:03','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg',0,'attachment','image/jpeg',0),(6316,17729,'2014-08-10 18:55:06','2014-08-10 18:55:06','','emboss_hel','Emboss with high elevation value','inherit','open','open','','emboss_hel','','','2014-08-10 18:55:06','2014-08-10 18:55:06','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg',0,'attachment','image/jpeg',0),(6317,17729,'2014-08-10 18:55:09','2014-08-10 18:55:09','','emboss_laz','Emboss with low azimuth angle','inherit','open','open','','emboss_laz','','','2014-08-10 18:55:09','2014-08-10 18:55:09','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg',0,'attachment','image/jpeg',0),(6318,17729,'2014-08-10 18:55:12','2014-08-10 18:55:12','','emboss_ldepth','Emboss with low depth value','inherit','open','open','','emboss_ldepth','','','2014-08-10 18:55:12','2014-08-10 18:55:12','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg',0,'attachment','image/jpeg',0),(6319,17729,'2014-08-10 18:55:15','2014-08-10 18:55:15','','emboss_lel','Emboss with low elevation angle','inherit','open','open','','emboss_lel','','','2014-08-10 18:55:15','2014-08-10 18:55:15','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg',0,'attachment','image/jpeg',0),(6320,17729,'2014-08-10 18:55:18','2014-08-10 18:55:18','','hou_adap','Adaptive Threshold with Mean local operator','inherit','open','open','','hou_adap','','','2014-08-10 18:55:18','2014-08-10 18:55:18','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hou_adap.jpg',0,'attachment','image/jpeg',0),(6321,17729,'2014-08-10 18:55:19','2014-08-10 18:55:19','','hou_otsu','Otsu threshold','inherit','open','open','','hou_otsu','','','2014-08-10 18:55:19','2014-08-10 18:55:19','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/hou_otsu.jpg',0,'attachment','image/jpeg',0),(6322,17729,'2014-08-10 18:55:20','2014-08-10 18:55:20','','house','Input','inherit','open','open','','house','','','2014-08-10 18:55:20','2014-08-10 18:55:20','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg',0,'attachment','image/jpeg',0),(6323,17729,'2014-08-10 18:55:20','2014-08-10 18:55:20','','iterative','Iterative Threshold','inherit','open','open','','iterative','','','2014-08-10 18:55:20','2014-08-10 18:55:20','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/iterative.jpg',0,'attachment','image/jpeg',0),(6326,17729,'2014-08-10 18:55:23','2014-08-10 18:55:23','','spider','Input','inherit','open','open','','spider','','','2014-08-10 18:55:23','2014-08-10 18:55:23','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg',0,'attachment','image/jpeg',0),(6327,17729,'2014-08-10 18:55:24','2014-08-10 18:55:24','','spi_iter','Iterative threshold','inherit','open','open','','spi_iter','','','2014-08-10 18:55:24','2014-08-10 18:55:24','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg',0,'attachment','image/jpeg',0),(6328,17729,'2014-08-10 18:55:25','2014-08-10 18:55:25','','spi_otsu','Otsu threhsold','inherit','open','open','','spi_otsu','','','2014-08-10 18:55:25','2014-08-10 18:55:25','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg',0,'attachment','image/jpeg',0),(6329,17729,'2014-08-10 18:55:26','2014-08-10 18:55:26','','sudoku','Input','inherit','open','open','','sudoku','','','2014-08-10 18:55:26','2014-08-10 18:55:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg',0,'attachment','image/jpeg',0),(6332,17729,'2014-08-10 19:20:26','2014-08-10 19:20:26','','bimodalBinary','Otsu threshold','inherit','open','open','','bimodalbinary','','','2014-08-10 19:20:26','2014-08-10 19:20:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg',0,'attachment','image/jpeg',0),(6333,17729,'2014-08-10 19:20:26','2014-08-10 19:20:26','','simpleBinary','Simple binary threshold','inherit','open','open','','simplebinary','','','2014-08-10 19:20:26','2014-08-10 19:20:26','',6225,'http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg',0,'attachment','image/jpeg',0),(6334,17729,'2014-08-11 19:32:09','2014-08-11 19:32:09','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array &in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar<float>() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.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\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','publish','open','open','','image-editing-using-arrayfire-part-3-2','','http://sandbox.arrayfire.com/image-editing-using-arrayfire/\nhttp://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/','2014-08-13 19:02:58','2014-08-13 19:02:58','',0,'http://sandbox.arrayfire.com/?p=6334',0,'post','',1),(6335,17729,'2014-08-10 19:33:39','2014-08-10 19:33:39','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Thesholding</li>\r\n<li>Otsu\'s Thresholding</li>\r\n<li>Iterative Thresholding</li>\r\n<li>Adaptive Binary Thresholding</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of thresholding operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Thesholding</h4>\r\n\r\n<p><code>c\r\nbinary threshold\r\n</code></p>\r\n\r\n<h4>Otsu\'s Thresholding</h4>\r\n\r\n<p>The famous Otus\'s thersholding method is very reliable in the case of images with bi-modal histograms. Below given is a comparision of simple binary thresholding and Otus\'s thresholding for your reference.\r\n<code>c\r\nOtsu\r\n</code></p>\r\n\r\n<h4>Iterative Thresholding</h4>\r\n\r\n<p>This is another type of global thresholing method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteratation, the threshold value is selected randomly. When the difference between two succesive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<code>c\r\nIterative thresholing\r\n</code></p>\r\n\r\n<h4>Adaptive Binary Thresholding</h4>\r\n\r\n<p>Thresholding methods are usually categorized into two types: global and variable. Global thresholding methods have a single threshold value that helps classify the image pixels into two classes. Variable thresholding is where local neighbor-hood properties of the current pixel are usedf to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implemenation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Thresholding output for each local operator mentioned above are provided below for your reference.\r\n<code>c\r\n</code></p>\r\n\r\n<h4>Emboss Filter</h4>\r\n\r\n<p>The emboss function is tailored after the emboss filter provided in GIMP, image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<code>c\r\nemnboss code\r\n</code></p>','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 19:33:39','2014-08-10 19:33:39','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0);
INSERT INTO `wp_posts` VALUES (6336,17729,'2014-08-10 19:35:23','2014-08-10 19:35:23','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Thesholding</li>\r\n<li>Otsu\'s Thresholding</li>\r\n<li>Iterative Thresholding</li>\r\n<li>Adaptive Binary Thresholding</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of thresholding operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Thesholding</h4>\r\n\r\n<p><code>c\r\nbinary threshold\r\n</code></p>\r\n\r\n<h4>Otsu\'s Thresholding</h4>\r\n\r\n<p>The famous Otus\'s thersholding method is very reliable in the case of images with bi-modal histograms. Below given is a comparision of simple binary thresholding and Otus\'s thresholding for your reference.\r\n<code>c\r\nOtsu\r\n</code></p>\r\n\r\n<h4>Iterative Thresholding</h4>\r\n\r\n<p>This is another type of global thresholing method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteratation, the threshold value is selected randomly. When the difference between two succesive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<code>c\r\nIterative thresholing\r\n</code></p>\r\n\r\n<h4>Adaptive Binary Thresholding</h4>\r\n\r\n<p>Thresholding methods are usually categorized into two types: global and variable. Global thresholding methods have a single threshold value that helps classify the image pixels into two classes. Variable thresholding is where local neighbor-hood properties of the current pixel are usedf to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implemenation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Thresholding output for each local operator mentioned above are provided below for your reference.\r\n<code>c\r\n</code></p>\r\n\r\n<h4>Emboss Filter</h4>\r\n\r\n<p>The emboss function is tailored after the emboss filter provided in GIMP, image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<code>c\r\nemnboss code\r\n</code></p>','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 19:35:23','2014-08-10 19:35:23','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6337,17729,'2014-08-10 19:54:59','2014-08-10 19:54:59','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu\'s Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighbor-hood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Conclusion</h4>','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 19:54:59','2014-08-10 19:54:59','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6338,17729,'2014-08-10 20:00:51','2014-08-10 20:00:51','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu\'s Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighbor-hood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:00:51','2014-08-10 20:00:51','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6339,17729,'2014-08-10 20:06:29','2014-08-10 20:06:29','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:06:29','2014-08-10 20:06:29','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6340,17729,'2014-08-10 20:47:15','2014-08-10 20:47:15','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold-ed the image using the threshold computed by Otsu method. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:47:15','2014-08-10 20:47:15','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6341,17729,'2014-08-10 20:52:17','2014-08-10 20:52:17','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:52:17','2014-08-10 20:52:17','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6342,17729,'2014-08-10 20:55:14','2014-08-10 20:55:14','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    bool isContinue = true;\r\n    while(isContinue) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:55:14','2014-08-10 20:55:14','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6343,17729,'2014-08-10 20:57:40','2014-08-10 20:57:40','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    array outwd = vdot < 0.0f;\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 20:57:40','2014-08-10 20:57:40','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6344,17729,'2014-08-10 21:01:41','2014-08-10 21:01:41','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\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_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 21:01:41','2014-08-10 21:01:41','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6345,17729,'2014-08-10 21:14:43','2014-08-10 21:14:43','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLets go through whats going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that we set the pixels that are less than(<em>(ret_val<thresholdValue)*0.0f<em>) threshold to 0.0f and the rest(<em>255.0f*(ret_val>thresholdValue)</em>) of them to 255.\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 21:14:43','2014-08-10 21:14:43','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6346,17729,'2014-08-10 21:16:09','2014-08-10 21:16:09','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLets go through whats going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that we set the pixels that are less than(<code>(ret_val<thresholdValue)*0.0f<code>) threshold to 0.0f and the rest(<code>255.0f*(ret_val>thresholdValue)</code>) of them to 255.\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 21:16:09','2014-08-10 21:16:09','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6347,17729,'2014-08-10 21:16:51','2014-08-10 21:16:51','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLets go through whats going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that we set the pixels that are less than(<code>(ret_val<thresholdValue)*0.0f</code>) threshold to 0.0f and the rest(<code>255.0f*(ret_val>thresholdValue)</code>) of them to 255.\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 21:16:51','2014-08-10 21:16:51','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6348,17729,'2014-08-10 21:18:40','2014-08-10 21:18:40','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n<li>Image Histogram</li>\r\n<li>Simple Binary Theshold</li>\r\n<li>Otsu Threshold</li>\r\n<li>Iterative Threshold</li>\r\n<li>Adaptive Binary Threshold</li>\r\n<li>Emboss Filter</li>\r\n</ul>\r\n\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n\r\n<h4>Image Histogram</h4>\r\nWe have built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>.\r\n<div style = \"text-align:center\">\r\n <div style=\"vertical-align: top\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"vertical-align: bottom\">\r\n<iframe height=371 width=600 src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" seamless frameborder=0 scrolling=no></iframe>\r\n </div>\r\n</div>\r\n\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>\r\narray threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLets go through whats going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that we set the pixels that are less than of them to 255.\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6322\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6313\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>\r\narray otsu(const array& in)\r\n{\r\n    array gray = colorspace(in,af_gray,af_rgb);\r\n    unsigned total = gray.elements();\r\n    array hist = histogram(gray,256,0.0f,255.0f);\r\n    float *h_hist = hist.host<float>();\r\n\r\n    float sum = 0.0f;\r\n    for (int i = 1; i < 256; ++i)\r\n        sum += i * h_hist[i];\r\n    float sumB = 0.0f;\r\n    float wB = 0.0f;\r\n    float wF = 0.0f;\r\n    float mB;\r\n    float mF;\r\n    float max = 0.0f;\r\n    float between = 0.0f;\r\n    float threshold1 = 0.0f;\r\n    float threshold2 = 0.0f;\r\n    for (int i = 0; i < 256; ++i) {\r\n        wB += h_hist[i];\r\n        if (wB == 0)\r\n            continue;\r\n        wF = total - wB;\r\n        if (wF == 0)\r\n            break;\r\n        sumB += i * h_hist[i];\r\n        mB = sumB / wB;\r\n        mF = (sum - sumB) / wF;\r\n        between = wB * wF * pow(mB - mF, 2);\r\n        if ( between >= max ) {\r\n            threshold1 = i;\r\n            if ( between > max ) {\r\n                threshold2 = i;\r\n            }\r\n            max = between;\r\n        }\r\n    }\r\n    array::free(h_hist);\r\n    return threshold(gray,(threshold1+threshold2)/2.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[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6312\" /></a> Input image with Bimodal histogram[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6333\" /></a> Simple binary threshold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6332\" /></a> Otsu threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively threshold-ed. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>\r\narray iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean<float>(ret_val);\r\n    while(true) {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean<float>(region1);\r\n        float r2_avg  = mean<float>(region2);\r\n        float tempT = (r1_avg+r2_avg)/2.0f;\r\n        if (abs(tempT-T)<0.01f) {\r\n            break;\r\n        }\r\n        T = tempT;\r\n    }\r\n    return threshold(ret_val,T);\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_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6326\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6328\" /></a> Otsu threhsold[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" class=\"size-thumbnail wp-image-6327\" /></a> Iterative threshold[/caption]\r\n </div>\r\n</div>\r\n\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is threshold-ed using a threshold value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference.\r\n<pre>\r\ntypedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - 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_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6329\" /></a> Input[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6309\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n </div>\r\n</div>\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6310\" /></a> Adaptive Threshold with Minimum & Maximum as local operator[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" class=\"size-medium wp-image-6308\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n </div>\r\n</div>\r\n\r\n\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on it\'s three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>\r\n/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth<1 || depth>100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = outwd * 0.0f + (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style = \"text-align:center\">\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6311\" /></a> Input[/caption]\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6319\" /></a> Emboss with low elevation angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6316\" /></a> Emboss with high elevation value[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6317\" /></a> Emboss with low azimuth angle[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6314\" /></a> Emboss with high azimuth angle[/caption]\r\n </div>\r\n</div>\r\n\r\n<div style = \"text-align:center\">\r\n <div style=\"display: inline-block; margin-right: 5px\">\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6318\" /></a> Emboss with low depth value[/caption]\r\n </div>\r\n <div style=\"display: inline-block\">\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" class=\"size-medium wp-image-6315\" /></a> Emboss with high depth value[/caption]\r\n </div>\r\n</div>\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>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-10 21:18:40','2014-08-10 21:18:40','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),