Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.
* <a href="http://sandbox.arrayfire.com/image-editing-using-arrayfire/">Part 1</a>
* <a href="http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/">Part 2</a>

In this post, we will be looking at the following operations.
<ul>
<li>Image Histogram</li>
<li>Simple Binary Theshold</li>
<li>Otsu Threshold</li>
<li>Iterative Threshold</li>
<li>Adaptive Binary Threshold</li>
<li>Emboss Filter</li>
</ul>

Today's post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.

<h4>Image Histogram</h4>
We 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>.
<div style = "text-align:center">
 <div style="vertical-align: top">
[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]
 </div>
 <div style="vertical-align: bottom">
<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>
 </div>
</div>

<h4>Simple Binary Threshold</h4>
<pre>
array threshold(const array &in, float thresholdValue)
{
    int channels = in.dims(2);
    array ret_val= in.copy();
    if (channels>1)
        ret_val = colorspace(in,af_gray,af_rgb);
    ret_val = (ret_val<thresholdValue)*0.0f + 255.0f*(ret_val>thresholdValue);
    return ret_val;
}
</pre>
<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<h4>Otsu Threshold</h4>
The 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.
<pre>
array otsu(const array& in)
{
    array gray = colorspace(in,af_gray,af_rgb);
    unsigned total = gray.elements();
    array hist = histogram(gray,256,0.0f,255.0f);
    float *h_hist = hist.host<float>();

    float sum = 0.0f;
    for (int i = 1; i < 256; ++i)
        sum += i * h_hist[i];
    float sumB = 0.0f;
    float wB = 0.0f;
    float wF = 0.0f;
    float mB;
    float mF;
    float max = 0.0f;
    float between = 0.0f;
    float threshold1 = 0.0f;
    float threshold2 = 0.0f;
    for (int i = 0; i < 256; ++i) {
        wB += h_hist[i];
        if (wB == 0)
            continue;
        wF = total - wB;
        if (wF == 0)
            break;
        sumB += i * h_hist[i];
        mB = sumB / wB;
        mF = (sum - sumB) / wF;
        between = wB * wF * pow(mB - mF, 2);
        if ( between >= max ) {
            threshold1 = i;
            if ( between > max ) {
                threshold2 = i;
            }
            max = between;
        }
    }
    array::free(h_hist);
    return threshold(gray,(threshold1+threshold2)/2.0f);
}
</pre>
<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<h4>Iterative Threshold</h4>
This 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.
<pre>
array iterativeThreshold(const array &in)
{
    array ret_val = colorspace(in,af_gray,af_rgb);
    float T = mean<float>(ret_val);
    while(true) {
        array region1 = (ret_val > T)*ret_val;
        array region2 = (ret_val <= T)*ret_val;
        float r1_avg  = mean<float>(region1);
        float r2_avg  = mean<float>(region2);
        float tempT = (r1_avg+r2_avg)/2.0f;
        if (abs(tempT-T)<0.01f) {
            break;
        }
        T = tempT;
    }
    return threshold(ret_val,T);
}
</pre>
<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<h4>Adaptive Binary Threshold</h4>
Threshold 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.
<pre>
typedef enum {
    MEAN=0,
    MEDIAN,
    MINMAX_AVG
} LocalThresholdType;

array adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)
{
    int wr = window_size;
    array ret_val = colorspace(in,af_gray,af_rgb);
    if (kind==MEAN) {
        array wind = constant(1,wr,wr)/(wr*wr);
        array mean = convolve(ret_val,wind);
        array diff = mean - ret_val;
        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);
    } else if (kind==MEDIAN) {
        array medf = medfilt(ret_val,wr,wr);
        array diff = medf - ret_val;
        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);
    } else if (kind==MINMAX_AVG) {
        array minf = minfilt(ret_val,wr,wr);
        array maxf = maxfilt(ret_val,wr,wr);
        array mean = (minf+maxf)/2.0f;
        array diff = mean - ret_val;
        ret_val    = (diff<constnt)*0.f + 255.f*(diff>constnt);
    }
    ret_val = 255.f - ret_val;
    return ret_val;
}
</pre>
<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>
<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>


<h4>Emboss Filter</h4>
The 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.
<pre>
/**
 * azimuth range is [0-360]
 * elevation range is [0-180]
 * depth range is [1-100]
 * Note: this function has been tailored after
 * the emboss implementation in GIMP editor
 **/
array emboss(const array &input, float azimuth, float elevation, float depth)
{
    if (depth<1 || depth>100) {
        printf("Depth should be in the range of 1-100");
        return input;
    }
    static float x[3] = {-1,0,1};
    static array hg(3,x);
    static array vg = hg.T();

    array in = input;
    if (in.dims(2)>1)
        in = colorspace(input,af_gray,af_rgb);
    else
        in = input;

    // convert angles to radians
    float phi   = elevation*af::Pi/180.0f;
    float theta = azimuth*af::Pi/180.0f;

    // compute light pos in cartesian coordinates
    // and scale with maximum intensity
    // phi will effect the amount of we intend to put
    // on a pixel
    float pos[3];
    pos[0] = 255.99f * cos(phi)*cos(theta);
    pos[1] = 255.99f * cos(phi)*sin(theta);
    pos[2] = 255.99f * sin(phi);

    // compute gradient vector
    array gx = filter(in,vg);
    array gy = filter(in,hg);

    // create a array from depth value which 
    // is of same dimensions as gradient vector array
    float pxlz  = (6*255.0f)/depth;
    array zdepth= constant(pxlz,gx.dims());
    // dot product of light position vector and gradient vector
    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];
    // divide dot product by gradient vector magnitude to
    // calculate scalar projection value
    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);
    // compute shading condition
    array outwd = vdot < 0.0f;
    // choose shading color based on the above condition
    array color = outwd * 0.0f + (1-outwd) * norm;
    return color;
}
</pre>
<div style = "text-align:center">
[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]
</div>

<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<div style = "text-align:center">
 <div style="display: inline-block; margin-right: 5px">
[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]
 </div>
 <div style="display: inline-block">
[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]
 </div>
</div>

<h4>Conclusion</h4>
All the functions from this post are updated and available through github repository located <a href="https://github.com/9prady9/wildfire">here</a>.