Threshold Image
Threshold:
Threshold follows the same concept as in basic electronics, here it is used to convert the grayscale image to black and white(binary image, consisting of 0's and 1's as pixel values.)
Threshold for an image can be set in the following ways:
Threshold for an image can be set in the following ways:
- Brute force : .5 times the maximum pixel intensity, which will be 127 in most of the images.
- Otsu's method : Based on a paper published in 1979 (IEEE Link), this method makes use of the histogram shape to find the threshold for the image. This gives a good enough performance but there are a few drawbacks when we run on entire image. There are a few regions that miss out as it will not consider the local neighborhood of the image. So, I prefer to use block based processing as this splits the image into smaller blocks and this can help us in getting the good idea in neighborhood for calculating threshold.
The Matlab code is given below:
clc;clear all;close all;
%Local Function Definitions:
fun = @(block_struct) thresher(block_struct.data);
I1= imread('rice.png');
f1 = figure(1);
imshow(I1);
title('Actual image');
brute = im2bw(I1,0.5);
brute = bwareaopen(brute,50);
imshow(brute);
title('Brute force Threshold image');
imwrite(brute,'brute.jpg','jpeg');
pause();
Brute Force |
thresh = graythresh(I1);
otsu_full_image = im2bw(I1,thresh);
otsu_full_image = bwareaopen(otsu_full_image,30);
imshow(otsu_full_image);
title('Otsu`s Threshold on Full Image');
imwrite(otsu_full_image,'otsu_full_image.jpg','jpeg');
pause();
Otsu's Threshold (Full Image) |
block_otsu = blockproc(I1,[32,32],fun);
block_otsu = bwareaopen(block_otsu,30);
imshow(block_otsu);
title('Otsu`s Threshold on block Image');
imwrite(block_otsu,'block_otsu.jpg','jpeg');
pause();
Otsu's Threshold (Block Processing) |
thresher.m (Function used during block processing)
function [ out ] = thresher(in)
thresh = graythresh(in);
out = im2bw(in,thresh);
imshow(out);
end
Now let's see what is block processing using the 2 lines that define it.
fun = @(block_struct) thresher(block_struct.data);
block_otsu = blockproc(I1,[32,32],fun);
Here we define that we should split the image I1 into smaller blocks of 32X32 image and then run the function 'fun' on it. This 'fun' was defined in the second line of the program that it has to send the data under process to the 'thresher' function. The thresher function calculates the Otsu's threshold for that 32X32 image and returns a 32X32 binary image calculated with threshold value calculated for that block. Thus we have used the ability of 32X32 neighborhood processing.Note: If block size is smaller it can take more time to run and too small block size may not always produce good results. So, its a trade-off.
In blockproc 'UseParallel',true can help sometimes if you have Parallel Computing Toolbox.