# Image editing using ArrayFire: Part 3

Pradeep Garigipati 1 Comment

Today, we will be doing the third post in our series Image editing using ArrayFire. References to old posts are available below.
* Part 1
* Part 2

In this post, we will be looking at the following operations.

• Image Histogram
• Simple Binary Theshold
• Otsu Threshold
• Iterative Threshold
• Adaptive Binary Threshold
• Emboss Filter

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

#### Image Histogram

We have a built-in function in ArrayFire that creates a histogram. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.

In case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.

#### Simple Binary Threshold

A 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.

Let'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 `255.0f*(ret_val>thresholdValue)`. 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 here.

#### Otsu Threshold

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.

#### Iterative Threshold

This 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.

#### Adaptive Binary Threshold

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 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 & 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

1. Convert image to gray scale if required
2. Convolve the gray scale image using the local operator
3. Take a difference between the convolved image and gray scale image
4. Threshold the difference image using constant
5. Invert the thresholded image and return the result

#### Emboss Filter

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 its three input parameters: azimuth, elevation & depth. The code and the sample outputs of emboss function are provided below.

#### Conclusion

All the functions from this post are updated and available through github repository located here.