[10] morphological image processing (1): Expansion and Corrosion

Source: Internet
Author: User


This series of articles is produced by @ simple ink _ Mao yunxing. Please indicate the source for reprinting.

Article: http://blog.csdn.net/poem_qianmo/article/details/23710721

Author: Mao yunxing (light ink) mailbox: happylifemxy@163.com

The OpenCV version used to write the current blog: 2.4.8



In this article, we explore the most basic morphological operations in image processing-expansion and corrosion. At the beginning of the article, the simple ink reminds you that the effect of using the photos of the characters for corrosion and expansion of the material image will be more thrilling, destroying the three views, we do not recommend that you try ..........


OK. Let's get started. Put one first:





I. Explanation of theories and concepts-from phenomena to nature



1.1 morphological Overview

 

The word morphology usually represents a branch of biology that studies the morphology and structure of animals and plants. The morphology of the middle finger in image processing often represents mathematical morphology. Let's take a look at the concept of mathematical morphology.

Mathematical morphology is a subject of Image Analysis Based on Lattice Theory and topology. It is the basic theory of Mathematical morphology image processing. Its basic operations include: binary corrosion and expansion, binary open and closed operation, skeleton extraction, ultimate corrosion, tumble-blow transformation, morphological gradient, Top-hat transformation, particle analysis, Watershed Transformation, gray-value corrosion and expansion, gray value opening/closing, gray value morphological gradient, etc.

 

In short, morphological operations are a series of shape-based image processing operations. OpenCV provides quick and convenient functions for morphological transformation of images. There are two basic morphological operations: Expansion and corrosion (Dilation and Erosion ).

Expansion and corrosion can achieve a variety of functions, mainly as follows:

  • Eliminate noise
  • Isolate generates independent image elements and joins Adjacent Elements in the image.
  • Find the obvious maximum area or minimum area in the image
  • Find the gradient of the image

 


Here we will give the original figure of the "light Ink" used to compare expansion and corrosion operations:

 

Before explaining corrosion and expansion, note that corrosion and expansion are for the white part (highlighted part), not the black part. Expansion is the expansion of the highlight part of the image, and the "field expansion", with a greater highlight area than the original image. Corrosion is the corrosion of the highlighted part in the source image. The field is eroded and the highlighted area is smaller than the source image.

 





1.2 Expansion

 

In fact, expansion is the operation of finding the local maximum value.

In terms of mathematics, expansion or corrosion operations involve convolution of an image (or A part of an image, which we call A) and A core (we call B.

A core can be of any shape or size. It has a defined reference point called anchorpoint ). In most cases, the core is a small center with a reference point and a solid square or disc. In fact, we can regard the core as a template or mask.

 

Expansion is the operation of finding the local maximum value. The kernel B is convolutionalized with the graph, that is, the maximum value of the pixel in the area covered by kernel B is calculated, and the maximum value is assigned to the pixel specified by the reference point. This will gradually increase the highlighted area in the image. As shown in, this is the original intention of the expansion operation.



Mathematical Expression of expansion:


Expansion (Mao Bi ):

 

Photo expansion:


 



Corrosion 1.3


Let's take a look at the corrosion. We should know that expansion and corrosion are a good friend, and they are a pair of operations on the contrary. Therefore, corrosion is the operation to obtain the local minimum value.

We usually understand and learn about corrosion and expansion. As you can see below, the prototype of the two functions is basically the same.

 

Schematic:

 

Mathematical Expression of corrosion:

 

Corrosion (Brush words ):


Photo corrosion:

 

Light ink indicates that this dog is cute: D

 

 



Ii. In-depth analysis and tracing of OpenCV source code

 


Go directly to the source code... The first line in the \ opencv \ sources \ modules \ imgproc \ src \ morph. cpp path is the source code of the erode (corrosive) function, and the 1,353rd act is the source code of the dilate (expansion) function.

// ----------------------------------- [Erode () function Chinese comments version source code] ---------------------------- // note: the following code is the official source code from the open-source computer visual library OpenCV // OpenCV source code version: 2.4.8 // source code path :... \ Opencv \ sources \ modules \ imgproc \ src \ morph. cpp // the starting line of the following code in the source file: 1353 rows // Chinese comment by light ink // invalid void cv: erode (InputArray src, OutputArraydst, InputArray kernel, Point anchor, int iterations, int borderType, constScalar & borderValue) {// call the morphOp function and set the identifier to MORPH_ERODE morphOp (MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );}

// ----------------------------------- [Diate () function Chinese comments version source code] ---------------------------- // note: the following code is the official source code from the computer open-source visual library OpenCV // OpenCV source code version: 2.4.8 // source code path :... \ Opencv \ sources \ modules \ imgproc \ src \ morph. cpp // the starting line of the following code in the source file: 1361 rows // Chinese comment by light ink // invalid void cv: dilate (InputArray src, OutputArray dst, InputArray kernel, Point anchor, int iterations, int borderType, constScalar & borderValue) {// call the morphOp function and set the identifier to MORPH_DILATE morphOp (MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );}


It can be found that the erode and dilate functions call the morphOp internally, but when they call the morphOp, the first parameter identifier is different, one is MORPH_ERODE (corrosion ), one is MORPH_DILATE (expansion ).

The source code of the morphOp function is... The first line in \ opencv \ sources \ modules \ imgproc \ src \ morph. cpp can be studied by interested friends. It takes no time and effort to analyze it.

 

 

 

3. Simple introduction-Quick Start to API functions

 



3.1 morphological expansion-dilate Function

 


The erode function expands an image by using the local maximum operator in the pixel neighborhood, which is input from src and output from dst. Supports in-place operations.

Function prototype:

C++: void dilate(InputArray src,OutputArray dst,InputArray kernel,Point anchor=Point(-1,-1),int iterations=1,int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue() );

Parameters:

  • The first parameter is "src" of the InputArray type. Enter the input image, that is, the source image. Enter the object of the Mat class. The number of image channels can be arbitrary, but the image depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
  • The second parameter is OutputArray type dst, that is, the target image, which must have the same size and type as the source image.
  • The third parameter is the InputArray-type kernel, which is the kernel of the expansion operation. If it is NULL, it indicates that the reference point is located in the core of the Center 3x3.

We generally use the getStructuringElement function in combination with this parameter. The getStructuringElement function returns the structure elements (kernel matrix) of the specified shape and size ).

The first parameter of the getStructuringElement function represents the kernel shape. We can choose one of the following three shapes:

    • Rectangle: MORPH_RECT
    • Crossover: MORPH_CROSS
    • Elliptical: MORPH_ELLIPSE

The second and third parameters of the getStructuringElement function are the kernel size and the position of the anchor.

Before calling the erode and dilate functions, we usually define a Mat-type variable to obtain the return value of the getStructuringElement function. The default value of Point (-1,-1) indicates that the anchor is located in the center. Note that the cross-shaped element shape is only dependent on the position of the anchor. In other cases, the anchor only affects the offset of the morphological operation result.

Sample Code for calling the getStructuringElement function is as follows:

Int g_nStructElementSize = 3; // size of the structure element (kernel matrix) // obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, size (2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point (g_nStructElementSize, g_nStructElementSize ));


After this is called, we can fill in the Mat type variable that saves the returned value of getStructuringElement when calling the erode or dilate function. The above example is to fill in the element variable.


  • The fourth parameter is anchor of the Point type. The default value (-1,-1) indicates that the anchor is located in the center.
  • The fifth parameter, int type iterations, indicates the number of times the erode () function is used for iteration. The default value is 1.
  • The sixth parameter, borderType of the int type, is used to infer a certain boundary pattern of the image's external pixels. Note that it has the default value BORDER_DEFAULT.
  • The seventh parameter is const Scalar & borderValue of the type. When the boundary is constant, the boundary value has the default value morphologyDefaultBorderValue (). Generally, we don't need to worry about it. When you need to use it, you can refer to the createMorphologyFilter () function in the official documentation for a more detailed explanation.
  •  

When using the erode function, we generally only need to fill in the first three parameters, and all the following four parameters have default values. It is often used together with getStructuringElement.

Call example:

// Load the original image Mat image = imread ("1.jpg"); // obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, Size (15, 15); Mat out; // perform the expansion operation (image, out, element );

Complete program code that is shelved with the core code above:

 

// ------------------------------------- [Header file portion] --------------------------------------- // Description: contains the header file on which the program depends. // optional # include <opencv2/core. hpp> # include <opencv2/highgui. hpp> # include <opencv2/imgproc. hpp> # include <iostream> // ----------------------------------- [namespace declaration part] contains // Description: contains the namespace used by the program // using namespace std; using namespace cv; // ----------------------------------- [main () function] ---------------------------------------------- // Description: The portal function of the console application. Our program starts from here // calls int main () {// load the source image Mat image = imread ("1.jpg"); // create a window namedWindow (" [original image] expansion operation "); namedWindow (" [] expansion operation "); // display the original image imshow ("[original image] expansion operation", image); // obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, Size (15, 15 )); mat out; // perform the expansion operation (image, out, element); // display imshow ("[] expansion operation", out); waitKey (0 ); return 0 ;}

Run:



 

 

 

3.2 morphological Corrosion-erode Function



The erode function uses the local extremely small operator in the pixel neighborhood to corrode an image, which is input from src and output from dst. Supports in-place operations.

 

Let's take a look at the function prototype:

C++: void erode(InputArray src,OutputArray dst,InputArray kernel,Point anchor=Point(-1,-1),int iterations=1,int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue() );

Parameters:

  • The first parameter is "src" of the InputArray type. Enter the input image, that is, the source image. Enter the object of the Mat class. The number of image channels can be arbitrary, but the image depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
  • The second parameter is OutputArray type dst, that is, the target image, which must have the same size and type as the source image.
  • The third parameter is InputArray-type kernel, which is used to corrode the operating kernel. If it is NULL, it indicates that the reference point is located in the core of the Center 3x3. We generally use the getStructuringElement function in combination with this parameter. The getStructuringElement function returns the structure elements (kernel matrix) of the specified shape and size ). (For details, refer to the third parameter description section of the dilate function)
  • The fourth parameter is the anchor of the Point type. The default value (-1,-1) indicates that the anchor is located in the center of the unit (element.
  • The fifth parameter, int type iterations, indicates the number of times the erode () function is used for iteration. The default value is 1.
  • The sixth parameter, borderType of the int type, is used to infer a certain boundary pattern of the image's external pixels. Note that it has the default value BORDER_DEFAULT.
  • The seventh parameter is const Scalar & borderValue of the type. When the boundary is constant, the boundary value has the default value morphologyDefaultBorderValue (). Generally, we don't need to worry about it. When you need to use it, you can refer to the createMorphologyFilter () function in the official documentation for a more detailed explanation.

Similarly, when using the erode function, we generally only need to fill in the first three parameters, and the next four parameters have default values. It is often used together with getStructuringElement.

Call example:

// Load the original image Mat image = imread ("1.jpg"); // obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, Size (15, 15); Mat out; // perform the corrosion operation erode (image, out, element );

Complete program code that is shelved with the core code above:

 

// ------------------------------------- [Header file portion] --------------------------------------- // Description: contains the header file on which the program depends. // optional # include <opencv2/core. hpp> # include <opencv2/highgui. hpp> # include <opencv2/imgproc. hpp> # include <iostream> // ----------------------------------- [namespace declaration part] contains // Description: contains the namespace used by the program // using namespace std; using namespace cv; // ----------------------------------- [main () function] ---------------------------------------------- // Description: The portal function of the console application. Our program starts from here // calls int main () {// load the original Matimage = imread ("1.jpg"); // create the namedWindow (" [original image] corrosion operation "); namedWindow (" [] corrosion operation "); // display the original image imshow ("[original image] corrosion operation", image); // obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, Size (15, 15 )); mat out; // perform the corrosion operation erode (image, out, element); // display imshow ("[] corrosion operation", out); waitKey (0 ); return 0 ;}


Running result:

 

 

 

 

Iv. comprehensive example-proven in practice

 

 

Still, every article will assign you a detailed annotated blog supporting example program, which will show the knowledge points introduced in this article to you as the Code carrier.

The window in this example has two scroll bars. As the name suggests, the first scroll bar "Corrosion/expansion" is used for switching between corrosion/expansion; the second scroll bar "kernel size" is used to adjust the kernel size during morphological operations to obtain images with different effects, which has certain playability. Let's talk about the Code:

// ------------------------------------- [Program description] -------------------------------------------- // program name: [10] morphological image processing (1 ): bloat and corrosion blog supporting source code // IDE version used for development: Visual Studio 2010 // OpenCV version used for development: 2.4.8 // Create by Shimo on April 9, April 14, 2014 // Weibo: @ light mo_mao yunxing // --------------------------------------- [header file contents ]----------------------- ---------------- // Description: contains the header file on which the program depends // dependencies # include <opencv2/opencv. hpp> # include <opencv2/highgui. hpp> # include <opencv2/imgproc. hpp> # include <iostream> // ----------------------------------- [namespace declaration part] ------------------------------------- // Description: contains the namespace used by the Program/namespaces //----------------------------------------- Using namespace std; using namespace cv; // ----------------------------------- [global variable declaration part] else // Description: global variable declaration // using Mat g_srcImage, g_dstImage; // original graph and int g_nTrackbarNumer = 0; // 0 indicates corrosion of erode, 1 indicates expansion of dilateint g_nStructElementSize = 3; // Size of the structure element (kernel matrix) // ----------------------------------- [global function declaration part] ------------------------------------ // Description: global function declaration // ----------------------------------------------------------------------------------------------- void Process (); // void on_TrackbarNumChange (int, void *); // callback function void on_ElementSizeChange (int, void *); // callback function // ------------------------------------- [main () function ]----------------------- --------------------- // Description: Portal function of the console application. Our program starts from here // using int main () {// change the console font color system ("color5E "); // load the original g_srcImage = imread ("1.jpg"); if (! G_srcImage.data) {printf ("Oh, no, error reading srcImage ~! \ N "); return false;} // display the original graph namedWindow (" [original graph] "); imshow (" [original graph] ", g_srcImage ); // perform initial corrosion and display namedWindow ("[]"); // obtain the custom kernel Matelement = getStructuringElement (MORPH_RECT, size (2 * Records + 1, 2 * g_nStructElementSize + 1), Point (g_nStructElementSize, g_nStructElementSize); erode (g_srcImage, g_dstImage, element); imshow ("[]", g_dstImage ); // create a trajectory bar createTrackbar ("Corrosion/expansion", "[]", & g_nTrackbarNumer, 1, on_TrackbarNumChange); createTrackbar ("kernel size", "[]", & g_nStructElementSize, 21, on_ElementSizeChange ); // output some help information, cout <endl <"\ t. Operation successful. Please adjust the scroll bar to observe the image effect ~ \ N "<" \ t press the "q" key, the program exits ~! \ N "<" \ n \ t \ tby light Ink "; // obtain the key information by polling. If the q key is down, program exited while (char (waitKey (1 ))! = 'Q') {} return 0;} // ----------------------------- [Process () function] ------------------------------------ // Description: Perform custom corrosion and expansion operations // ----------------------------------------------------------------------------------------- void Process () {// obtain the custom kernel Mat element = getStructuringElement (MORPH_RECT, Size (2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point (g_nStructElementSize, g_nStructElementSize )); // perform the corrosion or expansion operation if (g_nTrackbarNumer = 0) {erode (g_srcImage, g_dstImage, element);} else {dilate (g_srcImage, g_dstImage, element );} // display imshow ("[]", g_dstImage);} // ----------------------------- [on_TrackbarNumChange () function] ---------------------------------------- // description: callback Function for switching between corrosion and expansion // ----------------------------------------------------------------------------------------------------- void on_TrackbarNumChange (int, void *) {// The effect between corrosion and expansion has been switched. The callback function must call the Process function once, make the changed effect take effect immediately and display Process ();} // ------------------------------- [on_ElementSizeChange () function] ------------------------------------- // description: callback function when the kernel of the corrosion and expansion operations changes // ----------------------------------------------------------------------------------------------------- void on_ElementSizeChange (int, void *) {// The kernel size has changed. The callback function must call the Process function once, make the changed effect take effect immediately and display Process ();}


 

Let's release some. Original graph:

 


Expansion:

 






Corrosion:







The images produced by corrosion and expansion have a special sense of joy, but the original image looks better:



OK. Let's just release these. For more running effects, you can download the sample program and go back to play.


This article is almost over here, and finally releases the package of the example program supporting the article.

 

For the source code of this article, click here to download:


[10 tutorials for simple ink OpenCV] source code download

 


OK. This is probably the content of today. For the next article, see :)




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.