<h2 id="image-editing-operations-using-arrayfire">Image editing operations using ArrayFire</h2>
<p>In this post, we will be looking at the following simple image editing operations using the ArrayFire library.</p>
<ul>
<li>contrast modification<br /></li>
<li>brightness modification<br /></li>
<li>translation<br /></li>
<li>digital zoom<br /></li>
<li>alpha blending<br /></li>
<li>unsharp mask</li>
</ul>
<p>Code required to do each operation and the corresponding input/output sample are given below in their corresponding sections.<br />All the operations are built using some existing image manipulation functions and the awesome element-wise operations enabled in ArrayFire.<br />If you are not aware of what the JIT feature in ArrayFire lets you do, please refer to one of our previous post here.</p>
<h3 id="contrast-modification">Contrast modification</h3>

<pre>
/**
 * contrast value should be in the range [-1,1]
 **/
void changeContrast(array &in, const float contrast)
{
    float scale     = tan((contrast+1)*Pi/4);
    in = ((in/255.0f - 0.5f) * scale + 0.5f) * 255.0f;
}
</pre>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/07/man.jpg" alt="man" width="226" height="300" class="alignnone size-full wp-image-6108" style="float:left"/></a>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/07/highcon.jpg" alt="highcon" width="226" height="300" class="alignnone size-full wp-image-6106" style="float:right"/></a>
<h3 id="brightness-modification">Brightness modification</h3>
<pre>
/**
 * brightness value should be in the range [0,1]
 **/
void changeBrightness(array &in, const float brightness, const float channelMax=255.0f)
{
    float factor = brightness*channelMax;
    return (in + factor);
}
</pre>
<p>You may add an additional step to the above function that clamps each pixel value to [0,255] range. Clamping can be easily achieved by the following line of code.</p>
<pre>
image = (image<0.0f)*0.0f + (image>255.0f)*255.0f + (image>=0.0f && image<=255.0f)*image;
</pre>
or a more generalized thresholding operation would like as below.
<pre>
array clamp(const array &in, float min=0.0f, float max=255.0f)
{
    return ((in<min)*0.0f + (in>max)*255.0f + (in>=min && in <=max)*in);
}
</pre>

<h3 id="image-translation">Image translation</h3>
<p>This operation can be achieved directly by a function in our library <code>translate</code>.</p>
<h3 id="digital-zoom">Digital Zoom</h3>
<pre>
array digZoom(const array &in, int x, int y, int width, int height)
{
    array cropped = in(seq(height)+x,seq(width)+y,span);
    return resize((unsigned)in.dims(0),(unsigned)in.dims(1),cropped);
}
</pre>
<h3 id="alpha-blending">Alpha Blending</h3>
<pre>
array alphaBlend(const array &foreground, const array &background, const array &mask)
{
    array tiledMask;
    if (mask.dims(2)!=foreground.dims(2))
        tiledMask = tile(mask,1,1,foreground.dims(2));
    return foreground*tiledMask+(1.0f-tiledMask)*background;
}
</pre>
<p>For the purpose of this example, a very simple mask was created using this single line of code <code>array mask = clamp(intensity,10.0f,255.0f)&gt;0.0f;</code>. A more detailed and accurate mask would deliver more appropiate blending.</p>
<h3 id="unsharpmask">Unsharpmask</h3>
<pre>
/**
 * radius effects the level of details that will effected during sharpening process
 * amount value should be in the range [0,1] or [1,]
 * note: value of 1.0 for amount results unsharp masking
 *       values > 1.0 results in highboost filter effect
 **/
array usm(const array &in, float radius, float amount)
{
    int gKernelLen  = 2*radius + 1;
    array blurKernel= gaussiankernel(gKernelLen,gKernelLen);
    array blur  = convolve(in,blurKernel);
    return (in + amount*(in - blur));
}
</pre>