Sunday, 15 September 2013

Morphological operations and openCV2--00 : dilation and erosion

  There are many explanations about "what is morphological operations", the most intuitive explanation I like come from the book Learning OpenCV by Bradski and Kaehler

  A set of operations that process images based on shapes.
    Clean and easy to understand.More precisely, morphological operations would use the predefined shape(we call it structuring element) to slipped through all of the pixels of the image and replace the anchor pixel(most of the times, it is center) by minimum(erosion) or maximum(dilation) value.

    In morphological, the convention is to have fore-ground as white and background as black. The examples in this post also follow this convention.

Example :

These examples neglect boundary, only process the red pixels of input;green pixel is the anchor pixel, pink pixels are the pixels being changed.

Dilation

0 0 1 1 1 1 1 1                    1 1 1                                            0 0 1 1 1 1 1 1
0 1 1 1 0 1 0 0                    1 1 1                                            0 1 1 1 1 1 1 0     
0 0 0 0 0 1 1 1                    1 1 1                                            0 0 0 0 0 1 1 1

     input                            structuring element                             output


Erosion

0 0 1 1 1 1 1 1                    1 1 1                                            0 0 1 1 1 1 1 1
0 1 1 1 0 1 0 0                    1 1 1                                            0 0 0 0 0 0 0 0     
0 0 0 0 0 1 1 1                    1 1 1                                            0 0 0 0 0 1 1 1

     input                  structuring element                                      output

  You could defined any shape you like(ex : diamond, cross, circle and so on).The effects of dilation and erosion are grow or shrink the shapes.Dilation would grow the white region, shrink the dark region;Erosion would grow the dark region, shrink the white region.

 

 
graph_00(original image)

  I select binary image to process because it is 
  1. easier to understand
  2. most of the times, morphological filters work on binary images

  First, apply Otsu threshold on graph_00

cv::cvtColor(input, input, CV_BGR2GRAY);
cv::threshold(input, input, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);  


 graph_01(graph_00 after binarize)


  get the image after dilation
  
cv::Mat dilation(cv::Mat const &input)
{
    cv::Mat dilation_result = input.clone();
    //get the structuring of rectangle, size is 5 * 5
    cv::Mat const shape = cv::getStructuringElement
                  (cv::MORPH_RECT, cv::Size(5, 5));
    cv::dilate(input, dilation_result, shape);

    return dilation_result;
}
graph_02(dilation)
get the image after erosion

cv::Mat erosion(cv::Mat const &input)
{
    cv::Mat erosion_result = input.clone();
    //get the structuring of rectangle, size is 5 * 5
    cv::Mat const shape = cv::getStructuringElement(
                  cv::MORPH_RECT, cv::Size(5, 5));
    cv::erode(input, erosion_result, shape);

    return erosion_result;
}
graph_03(erosion)

If you dilate or erode it again, the effect would become more obvious.

graph_04(dilate two times)
graph_05(erode two times)

  From graph_02~graph_05, we can find out that dilation could grow the edges of white region;erosion can grow the edges of black region. You could treat dilation and erosion as some sort of filter, dilation will remove any black region which smaller than the structuring element;erosion will remove any white region which smaller than the structuring element.

As usual, the codes can download from github