A particularly important monadic operation is referred to as thresholding.
Consider the two images here. The first one is a grey scale image and the second image you can see is much more contrasty; in fact, the pixels have only got two values—they are either black or white.
Now what we have done here is made a logical decision on every input value. If the input value is less than the threshold, referred to by the symbol T, then the result is false and we represent that by a black pixel in the output image.
If the input pixel is greater than and equal to T, then we say the result is true and the resulting pixel is displayed as white.
If we display this function graphically, we can see that it is very, very non-linear. The output is 0 up until we reach the input value of T, and then the output value becomes true.
In MATLAB when we display a pixel value that has got a value of false, it shows as black, and when we display a pixel that has a value of true it is displayed as white.
MATLAB supports a number of what we call logical operators. That is the way to compare two numeric quantities. Just in the example before we looked at the >= operator, and we also looked at the < operator. MATLAB has the ability to determine whether two values are equal; or not equal; greater than; less than; and so on.
The result of any of these logical operators is a logical value; it is either true or false. Now MATLAB represents the concepts of true and false as numeric values. True is represented by 1 and false is represented by 0.
MATLAB also has some special constants that are built in, and they have got the names true and false.
Let’s start with something really simple. We will ask the question ‘is 2 greater than 1?’, and we know that the outcome of this must be true.
And MATLAB has given us a value of 1. Now we will note that we have created a new variable in the workspace called ans. Ans is an automatic variable that MATLAB uses to hold always the result of the last operation or command that has been given.
It is of logical type, which means it can only have values of true or false.
So the answer that we got to this question is 1, and 1 is the numerical value that MATLAB uses to represent the concept of true.
Similarly, if we ask the question ‘is 1 greater than 2?’, and we know that this is false, MATLAB has returned as a numerical value of 0. It is how MATLAB represents the concept of false.
MATLAB has got a couple of built in variables to represent these values. We can ask it the value of true. The equivalent numerical value is 1. And false, the equivalent numerical value is 0.
We can also do an equality test, so we can say ‘is 1 equal to 2?’. It is not; it is false.
‘Is 2 equal to 2?’ Yes that is true.
We can, of course, assign illogical tests to variables, so I can say ‘is a equal to 2 equals 3?’. We created a new logical variable in that workspace called a, and it has a value of 0, or false.
Earlier we looked at the concept of vectorization when we performing arithmetic between a matrix and a scalar. Well the logical operators can also be used in a vectorized form. What happens in this case is that the logical test is done between every element in the input matrix, and the scalar, and the result is a matrix with the same size as the input matrix in which every element is a logical value. The elements in the output matrix are either true or false.
Let’s show a concrete example of this. I am going to create a matrix m and it is going to contain random integer elements between 1 and 10. The matrix is going to be 4 by 4. There we have it.
Now if I apply a logical test to this matrix, what MATLAB is going to do is to compare every element of the matrix with 5. It is going to apply the >5 test to each element. And so what we can see in this result: wherever there are ones, this indicates an element that is greater than 5.
You can also see that this result is a matrix of logical type; that is, every element in this matrix is a logical value which can only be true or false, represented by the numeric values 1 or 0 respectively.
I can apply an equality test to this matrix as well, and I can look for all of the elements that are equal to 3. And what I find now is a matrix where the two ones indicate the elements of the original matrix that were equal to 3.
What we are going to do is create a new variable; in this case it is going to be called b. What I am going to do is to apply a logical test to every pixel in the image im, which is the image of the penguin sign you can see above. And I am going to compare all of these pixel values to the numeric value 0.45, and it is going to create a new variable in my workspace and we can see that it is of type logical.
We see it has the same dimensions as the original image im. It has got 730 rows and 1047 columns. It is of type logical. Each element in this new matrix has got a value of either false or true.
Now let’s display this logical image.
Here we go, and what we see now is an image where the pixel values are quite crisp; they are either black or white. The black values — I click on here — have got a value of 0, they’re false. That means that they don’t pass the test — they are less than 0.45. Where a pixel here has a value of 1, it does pass the test — it is greater than 0.45.
Now, the question you might ask is where does this number of 0.45 come from. Well I chose it based on the histogram, because the histogram indicates to me quite clearly that there is a bunch of pixels with a value less then around 0.45, which are the dark ones corresponding to the background. And then there is a set of bright pixels generally bigger then 0.45, which comprise the foreground or the objects of interest, the icons and the characters on that sign.
Now I can choose a different value for the threshold. I can choose, for instance, I can choose to make the threshold a little bigger. I can maybe choose say 0.6, and I can display that new image and we see now that the results are somewhat similar. The small writing at the top of that sign has disintegrated and that often happens as you change the threshold, some objects will start to fragment and disappear.
Rather than do this in a kind of clumsy trial and error fashion, we can use the toolbox function ithresh. We parse in the image that we are interested in — im in this case — and what we have is a slider. Up the top we see an indicator of the current threshold value. It defaults to 0.5. If I come down here and grab the slider bar I can increase the threshold, now it is 0.54. I can make it bigger, and we can see that progressively as I raise the threshold. Fewer and fewer pixels have a value greater than the threshold and the result is increasingly a black image.
Similarly, if I reduce the threshold down here to say something like 0.41, we certainly see that all the letters appear there quite completely. As I reduce the threshold even further what we will see is some bright parts of the background starting to become true when we apply the threshold test and eventually the result is not quite so clear cut. So when you choose a threshold there is generally a sweet spot. Too low the result is all white, too high and the result is all black. There is a sweet spot in the middle.
Now choosing a threshold is a difficult thing; requires a bit of skill, but primarily we should be informed by the histogram which tells us something about how the grey scale values are distributed within an image. And we use that to make an intelligent, first choice of the threshold.
Imagine a scene with bright objects against a dark background. Thresholding is a very common monadic operation which transforms the image into one where the pixels have two possible values: true or false which correspond to foreground or background. It can be performed with a single vectorized MATLAB operation.
This content assumes an understanding of high school level mathematics; for example, trigonometry, algebra, calculus, physics (optics) and experience with MATLAB command line and programming, for example workspace, variables, arrays, types, functions and classes.
Thank you for this amazing video