OpenCV image recognition from zero to proficient------diffuse water filling, seed filling, area growth, hole filling

Source: Internet
Author: User
Tags scalar


It can be said that from the beginning of this article, the end of the basic image recognition, came to the second stage of learning. In peacetime processing two value image, in addition to some of the morphology of the operation, there is a section of the contour connected area perimeter mark, there is one of the most common is the filling of the hole, OpenCV here become diffuse water filled, in fact, can also be called seed filling, or regional growth, the basic principle is the same, But when applied, it is important to note that the seed fills with recursive methods, backtracking algorithms, and diffuse water fills using stacks to improve efficiency while also providing a way to scan rows. Often used to fill holes, now take a concrete look.


Diffuse water filling : That is, with a certain color to fill the Unicom area, by setting the upper and lower limits of the connected pixels and connectivity to achieve different filling effect; Diffuse fill is often used to mark or detach portions of an image for further processing or analysis, or to obtain a mask area from an input image , the mask accelerates the process, or only the pixel points specified by the mask, and the result of the operation is always a contiguous area. To put it simply, select Point Seedpoint, then select the dots around it that have little difference in color and change their values to newval. If the selected point encounters a mask mask, discard the

The seed filling algorithm, the seed filling algorithm, starts from a point inside the polygon area, which is where all the pixels within the region are found. The boundary definition used by the seed fill algorithm is that all pixels on the area boundary have a particular color value, and all pixels inside the region do not take this particular color, while pixels outside the boundary can have the same color value as the boundary.

Specific algorithm steps:

    • The pixel point of the marker seed (x, y);
    • Detect the color of the point, if he and the boundary color and fill color are different, fill the point with fill color, otherwise not filled;
    • Detects adjacent positions and continues 2. This process continues until all pixels within the bounds of the detected area have been examined.
    • Of course, there are two ways to detect neighboring pixels when searching: four-way connectivity and eight-direction connectivity. Four-direction communication is from the point of the region, through four square up, down, left and right to retrieve. The eight-way connection adds the upper left, lower left, upper right, and lower right four directions. This algorithm is a bit of a simple algorithm, easy to implement, can also be filled with the inner hole of the plane area. However, the algorithm needs more storage space to implement the stack structure, the same pixel multiple times into the stack and out of the stack, inefficient and computationally large.

Scan line seed fill algorithm: the algorithm belongs to the seed filling algorithm, which is operated on the segment of the scan line. The so-called section is a collection of several internal pixels connected to a scanning line. Scanning line seed filling algorithm idea: First fill the current scan line in a section of a given region, and then determine whether the section adjacent to the upper and lower lines in the region where there is a need to fill the new section, if present, then save them, repeat the process until the saved sections are filled.

<span style= "FONT-SIZE:18PX;" >floodfill function C + +: int FloodFill (inputoutputarray image, Inputoutputarray mask, point                 seedpoint, Scalar newval, Re  ct* rect=0, scalar lodiff=scalar (), scalar updiff=scalar (), int flags=4);  Inputoutputarray: Input and output images.  Mask:            the input mask image.   Seedpoint:      The starting position where the algorithm begins processing. NewVal:         All points in the image that are selected by the algorithm are populated with this value.      rect: The            minimum bounding matrix. Lodiff:         The difference between the maximum low brightness.      Updiff:         The difference between the maximum high brightness. Flag:           Select the algorithm connection method. </span>

Look at a basic application based on the above function

<span style= "FONT-SIZE:18PX;" > #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream>using namespace cv;using namespace Std; Mat g_srcimage, G_dstimage, g_grayimage, g_maskimage;int g_nfillmode = 1;int g_nlowdifference = $, g_nUpDifference = 20;i NT g_nconnectivity = 4;int G_biscolor = True;bool G_busemask = false;int g_nnewmaskval = 255;static void onMouse (int even t, int x, int y, int, void*) {if (event! = Event_lbuttondown) return; Point seed = Point (x, y); int lowdifference = G_nfillmode = = 0? 0:g_nlowdifference;int Updifference = G_nfillmode = = 0? 0:g_nupdifference;int flags = g_nconnectivity + (g_nnewmaskval << 8) + (G_nfillmode = = 1?) floodfill_fixed_range:0); int b = (unsigned) therng () & 255;int g = (unsigned) therng () & 255;int R = (unsigned) the RNG () & 255; Rect Ccomp; Scalar newval = G_biscolor? Scalar (b, G, R): scalar (r*0.299 + g*0.587 + b*0.114); Mat DST = G_biscolor? g_dstimage:g_grayimage;//Assignment int for target graph Area;if (G_busemask) {threshold (G_maskimage, g_maskimage, 1, N, thresh_binary); area = FloodFill (DST, g_maskimage, seed , newval, &ccomp, scalar (lowdifference, lowdifference, lowdifference), scalar (updifference, updifference, updifference), flags); Imshow ("Mask", G_maskimage);} Else{area = FloodFill (DST, Seed, newval, &ccomp, scalar (lowdifference, lowdifference, lowdifference), scalar ( Updifference, Updifference, updifference), flags);} Imshow ("", DST); cout << area << "Pixels are redrawn \ n";} int main (int argc, char** argv) {g_srcimage = Imread ("lena.jpg", 1), if (!g_srcimage.data) {printf ("read picture IMAGE0 Error ~! \ n "); return false; } g_srcimage.copyto (G_dstimage); Cvtcolor (G_srcimage, G_grayimage, Color_bgr2gray); G_maskimage.create (g_ Srcimage.rows+2, g_srcimage.cols+2, CV_8UC1) Namedwindow ("", window_autosize); Createtrackbar ("Negative difference maximum", "", &g_ Nlowdifference, 255, 0); Createtrackbar ("Positive difference maximum", "" ", &g_nupdifference, 255, 0); Setmousecallback (" ", Onmouse, 0); WH Ile (1) {//Show Imshow First ("", G_biscolor?" G_dstimage:g_grayimage);//get keyboard keys int c = waitkey (0);//Determine if ESC is pressed and exit if ((c & 255) = =) {cout << program exits ... ... \ n "; break;} Depending on the key, do a variety of operations switch ((char) c) {//If the keyboard "1" is pressed, in grayscale, color map between case ' 1 ': if (g_biscolor)//Johurai color, to grayscale, The mask mask all elements are set to 0{cout << "keyboard" 1 "is pressed to toggle color/Grayscale mode, the current operation is to switch" color mode "to" grayscale mode "\ n"; Cvtcolor (G_srcimage, G_grayimage, Color_bgr2gray); g_maskimage = Scalar::all (0);//Set mask all elements to 0g_biscolor = false;//Sets the identifier to false, indicating that the current image is not color, but grayscale}else/ /Johurai for grayscale, the original color map IMAGE0 copied to the image again, and the mask mask all elements are set to 0{cout << "keyboard" 1 "is pressed to toggle the color/grayscale mode, the current operation is" color mode "switch to" grayscale mode "\ n"; g_ Srcimage.copyto (g_dstimage); g_maskimage = Scalar::all (0); G_biscolor = true;//Set the identifier to true to indicate that the current image mode is color}break;//if the keyboard key "2" is pressed to show/hide Mask window case ' 2 ': if (g_busemask) {DestroyWindow ("mask"); g_busemask = false;} Else{namedwindow ("Mask", 0); g_maskimage = Scalar::all (0); Imshow ("Mask", g_maskimage); g_busemask = true;} break;//If the keyboard key "3" is pressed, restore the original image case ' 3 ': cout << "key" 3 "is pressed to restore the original image \ n"; G_srcimage.copyto (g_dstimage); CVTColor (G_dstimage, G_grayimage, color_bgr2gray); g_maskimage = Scalar::all (0); break;//If the keyboard key "4" is pressed, use an empty range of diffuse water to fill case ' 4 ' : cout << "key" 4 "pressed, using an empty range of diffuse water to fill \ n"; g_nfillmode = 0;break;//If the keyboard key "5" is pressed, use a gradient, fixed range of diffuse water fill case ' 5 ': cout << "Key" 5 "pressed, using a gradient, a fixed range of diffuse water filling \ n"; g_nfillmode = 1;break;//If the keyboard key "6" is pressed, use gradient, floating range of diffuse water fill case ' 6 ': cout << "key 6" is pressed, using gradients, Floating range of diffuse water filled \ n "; g_nfillmode = 2;break;//If the keyboard key" 7 "is pressed, the operating marker low eight bits use 4-bit connection mode case ' 7 ': cout <<" key "7" is pressed, The low eight bits of the action marker use the 4-bit connection mode \ n "; g_nconnectivity = 4;break;//If the keyboard key" 8 "is pressed, the lower eight bits of the action marker use 8-bit connection mode case ' 8 ': cout <<" key "8" is pressed, The low eight bits of the action marker use the 8-bit connection mode \ n "; g_nconnectivity = 8;break;}} return 0;} </span>

Take a look at the application of the diffuse water filling in the filling hole

 #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\  Imgproc.hpp>using namespace std;using namespace CV;      void Chao_fillhole (const cv::mat srcimage, Cv::mat &dstimage) {Size m_size = srcimage.size ();       Mat temimage = Mat::zeros (M_size.height + 2, M_size.width + 2, Srcimage.type ());      Srcimage.copyto (Temimage (range (1, m_size.height + 1), range (1, m_size.width + 1));      FloodFill (temimage, point (0, 0), Scalar (255));    Mat cutimg;      Temimage (Range (1, m_size.height + 1), range (1, m_size.width + 1)). CopyTo (CUTIMG); Dstimage = Srcimage |  (~CUTIMG); } int main () {Mat src=imread ("111.png");   Mat DST;   Chao_fillhole (SRC, DST);   Imshow ("Tianchong", DST);   Waitkey (0);  return 0;} 


Matlab

<span style= "FONT-SIZE:18PX;" >i=imread (' tire.tif '); Figure,imshow (i) Bw=imfill (i); Figure,imshow (BW) </span>


Image recognition algorithm Communication QQ Group: 145076161, welcome image recognition and image algorithm, mutual learning and communication


OpenCV image recognition from zero to proficient------diffuse water filling, seed filling, area growth, hole filling

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.