Huitième: Morphological Operations

Hi reader! It’s been a long while since my last blog entry; I have been busy with my other courses and it also it took me a while to figure out the next activity. Anyway, the topic for this entry is all about morphological operations. This is an entirely new topic so we won’t be using the Fourier transform for this part; nevertheless, it would be as useful as the latter. I hope that I could give this topic justice with my discussions.

Morphology refers to the shape or structure of an object or an image for our case; thus morphological operations would be the processes done on images (usually binary) to improve its quality for further processing and extraction of information. For this study, we will focus on dilation and erosion.

The dilation of A by a structuring element B denoted by A dilation B is symbolically defined as:

dil

which means that the resulting set involves all z’s which are translations of a reflected B then when intersected with A is not an empty set. By doing this, we would see A expanding in the shape of B. On the other hand, the erosion of A by B is given by:

eromeaning that the result is the set of all points z such that B translated by z is contained in A. To better understand the concept of the two operations, I drew four shapes: 1) a 5×5 square, 2) a triangle with base = 4 and height = 3, 3) a hollow 10×10 square with 2 boxes width and 4) a plus sign, one box thick and 5 boxes along each line and then dilated and eroded it with the following structural elements:

SE
Figure 1. Structuring elements used for dilation and erosion

The results are displayed in the figures below. The order for the following figures would be (from left to right) the original image, then the dilation and erosion with the structuring elements in the same order as in figure 1. For easier comparison of the two operations, I performed both on the same figure: the diagonal lines indicate the added area after dilation with the respective structuring element and the cross marks indicate the subtracted area after erosion.

Square
Figure 2. Dilation and erosion of a square
Triangle
Figure 3. Dilation and erosion of a triangle
Hollow Square
Figure 4. Dilation and erosion of a hollow square
Untitled
Figure 5. Dilation and erosion of a cross

To verify if what I did was correct, I simulated both operations in Scilab using CreateStructureElement(), ErodeImage() and DilateImage(). The results are shown in the figure below, and I apologize for the poor quality of the images, since its original size is less than 20 pixels and I had to stretch it here.

dilateP1
Figure 6. Dilation of a square
erodeP1
Figure 7. Erosion of a square
dilateP2
Figure 8. Dilation of a triangle
erodeP2
Figure 9. Erosion of a triangle
dilateP3
Figure 10. Dilation of a hollow square
erodeP3
Figure 11. Erosion of a hollow square
dilateP4
Figure 12. Dilation of a cross
erodeP4
Figure 13. Erosion of a cross

It turned out that all of my predictions were correct after all! I can say that the operations are quite easy to implement, may it be manual or by programming. I will not discuss each image individually since it can easily be done with intuition; instead, I will summarize my observations with the two operations. First, from my drawing, it can be seen that the two operations are complement of each other – if the erosion of a given image causes the reduction of one side to a certain degree, it would follow that the dilation of the similar image would be an expansion on the opposite side with a similar degree. Second, with a structural element of enough size, it is possible to close any gaps in the image given that its size is smaller than the structuring element. Lastly, it is also possible to erase an image by erosion if the width of the structuring element is bigger than the width of the image.

Applications

Let us now apply this operations to an actual image:

 

circle
Figure 14. Normal-sized cells

 

cancircle
Figure 15. Combination of normal and cancer cells

We have a set of normal-sized cells from figure 14 where we can determine the average size of the normal cells and use that data to filter the cancel cells which are of greater size. First, I obtained the histogram of figure 14 to determine the threshold grayscale value that would separate the background and the cells:

histo orig
Figure 16. Histogram of figure 14, the normal-sized cells

The histogram peaks between 0.6-0.8, meaning that the background which constitutes majority of the image, has grayscale values from this range. Next, I used SegmentByThreshold() to separate the cells and I got:

cleaned
Figure 17. Thresholded image of figure 14

I studied three more morphological operators to further clean the image. The first one is the OpenImage(), which is an erosion of an image followed by dilation [2]. Since the cells are of circular shape, I chose a circle of radius 10 pixels as a structuring element . The result is shown below:

open
Figure 18. OpenImage() applied on figure 17

With my first try, I was lucky enough to clean the image of isolated pixels and holes in the cells. Since I chose a structuring element of greater size than the holes and the isolated pixels, the erosion part of the OpenImage() took care of this and then brought the remaining cells back to its original size using the dilation part.

Let us still look at the two remaining operators for they may be useful in some future studies. Second one is the CloseImage() operator, which is, as you may have guessed, a dilation followed by erosion. The result is shown in figure 19

close
Figure 19. CloseImage() applied on figure 17

The CloseImage() operator, as can be seen from the result connected the nearby cells and also removed their holes. However, the isolated pixels were enlarged instead of being removed. Clearly, this will not be useful for this application.

Last is the TopHat() operator, which is the difference between the original image and the OpenImage() of the original image. Essentially, what we could get from this operator are the added parts on the original image if the OpenImage() operator was used on it. Since I used a single structuring element on all the three operations, we can use this operator to further observe the effects of the OpenImage() operator.

The result is shown in figure 20 below. What surprised my was the sheer amount of normal-sized cells that were removed after opening the image. Majority of these cells lie in the middle part of the image. It is also evident that most of the normal cells removed are the ones that appear to have merged together; and though normally we want to preserve every cell, these ones are not so important since the area that could be obtained from them are larger than usual.

top
Figure 20. TopHat() applied on figure 17

Now that we are able to separate the cells from the background and clean them, we can now get the average size of the cells. First, we get six random portions of the image and then stitch them together as shown in figure 20. This is done to obtain a more accurate mean size of the cells.

circlez
Figure 21. Six random areas from figure 17 stiched together

 

Next we threshold the image and the apply OpenImage() using again a circle of radius 10 as a structuring element:

open2
Figure 22. Cleaned image of figure 21

 

Next, I used SearchBlobs() to label and count all the individual cells in the figure. Using CreateSizeHistogram(), I obtained a histogram of the areas of each cells shown in the figure below. The area obtained is this part is the actual pixel count of each labelled blob. For the stitched image above, there were a total of 63 blobs.

histo ples
Figure 23. Histogram of the areas of the cells in figure 22.

Since there were cells that are too close with each other even upon the use of OpenImage(), the SearchBlobs() command have labelled such cells as a single blob causing some discrepancies in the area measured. I took the areas below 611 as the size range of a normal cell and used these values to obtain the mean size of a normal cell and the standard deviation of the values.

I obtained an average area of 440.97 pixels and a standard deviation of 59.8, and therefore a normal cell would have a size ranging from 381.17 – 500.77 pixels. This has an radius equivalent of 11.01 – 12.62. Now that we have this data, let us not filter the cancer cells.

Again, we threshold and open the image first:

cancleaned
Figure 25. Cleaned version of figure 15

Now how do I filter this thing? Since I have the range of area and radius a normal cell has, I could use this to do the filtering. I asked Gio for some suggestions as to how I should approach this and he suggested that I use the command FilterBySize(). I studied it and learned that I can use it in conjunction with the SearchBlobs(). What it does is that it removes blobs that have less pixels than the lower bound and more pixels than the upper bound.

So the steps I should take are:

  1. Use the FilterBySize() command with bounds (381.17, 500.77)
  2. Check the output and change the image values to only 0’s and 1’s; this will serve as my filter
  3. Subtract my filter from figure 25

But as I was finalizing these steps, I remembered one of my conclusions on the first part of the activity: it is possible to erase an image by erosion if the width of the structuring element is bigger than the width of the image. There!!! Now I have an easier and faster way of filtering the cancer cells!

I then created a structuring element equal to 12.65; 0.003 pixels higher than the maximum radius I have obtained from the earlier part. I then eroded figure 25, and I obtained:

fuckcancer
Figure 26. Erosion of figure 25 with a circle of radius 12.65

There we still some normal sized cells (at least from my vision) so I increased the radius of my structuring element to 13:

 

fuckcancer2
Figure 26. Erosion of figure 25 with a circle of radius 13

 

There we have it, a successful and quick way of filtering cells!! TADAAA!

I would not have done this activity without the generous help of my professors, Ms. Jing Soriano and Ms. Eloisa Ventura. I would also like to acknowledge Gio Jubilo for his aid and insights that have greatly helped me finish this activity.

I believe that I have clearly understood all the important concepts in morphological operations allowing me to produce all the necessary output for the activity and with that, I will give myself a score of 10/10. I would also think of a good application of the techniques I learned so *hopefully* I’ll be adding another section in a few more days.

Reference:

  1. Soriano, M., “Activity 7 – Image Segmentation 2014.”
  2. “Opening”, Retrieved from: http://homepages.inf.ed.ac.uk/rbf/HIPR2/open.htm
  3. “Closing”, Retrieved from: http://homepages.inf.ed.ac.uk/rbf/HIPR2/close.htm
  4. “More Morphology Operations”, Retrieved from: http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html

Leave a comment