In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains "how to achieve OpenCV image segmentation and watershed algorithm in C++", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "how to achieve OpenCV image segmentation and watershed algorithm in C++"!
Watershed algorithm is a kind of image region segmentation method, in the process of segmentation, it will take the similarity with adjacent pixels as an important reference basis. Thus, the pixels with similar spatial position and similar gray values are connected to each other to form a closed contour. Closeness is an important feature of the watershed algorithm.
API introduction
Void watershed (InputArray image, InputOutputArray markers)
Parameter description:
Image: must be a 8bit 3-channel color image matrix sequence
Markers: before executing the watershed function watershed, the second parameter markers must be processed. It should contain the contours of different regions, each with its own unique number. The location of the contour can be achieved through the findContours method in Opencv, which is the requirement before the watershed is implemented. The algorithm will use the contours introduced by markers as seeds (that is, the so-called water injection points), judge the other pixels in the image according to the watershed algorithm rules, and delimit the regional attribution of each pixel until all the pixels on the image are processed. The value at the boundary between regions is set to "- 1" to make a distinction.
We will give an example of how to use distance transformation and watershed to segment objects in contact with each other.
Consider the coin image below, which touches each other. Even if you de-threshold it, it will touch each other.
Let's start by finding the approximate value of the coin. For this reason, we can make use of the binarization of Otsu.
# include#includeusing namespace std;using namespace cv;int main () {Mat gray, thresh; Mat img = imread ("coins.jpg"); cvtColor (img, gray, COLOR_BGR2GRAY); threshold (gray, thresh, 0,255, THRESH_BINARY_INV+CV_THRESH_OTSU); imshow ("Otst threshold Image", thresh); waitKey (0); return 0;}
The image after the threshold is as follows:
Now you need to remove any tiny white noise from the image. To do this, we can use the morphological open operation. In order to remove any small holes in the object, we can use the shape closure operation. So now what we can confirm is that the area near the center of the object is the foreground and the area away from the object is the background. The only area we are not sure about is the boundary area of the coin.
So we need to extract the area that we determined to be a coin. Erosion removes boundary pixels. So no matter how much is left, we can be sure it's a coin. If objects don't touch each other, that's fine. But because they come into contact with each other, another good option is to find the distance transformation and apply the appropriate threshold. Next we need to find the area where we are sure it is not a coin. To this end, we extend the results. Expansion adds the boundary of the object to the background. In this way, we can ensure that any background area in the result is the real background, because the boundary area.
The rest of the area is what we don't know, whether it's the coin or the background. The watershed algorithm should be able to find it. These areas usually surround the boundary of the coin, where the foreground and background meet (or even where two different coins meet). We call it the boundary. The sure_fg area minus the sure_bg area can be obtained.
Mat opening; Mat sure_bg;Mat sure_fg; Mat unknow;Mat dist_transform;double maxValue;// noise removalMat kernel = Mat::ones (3,3, CV_8U); morphologyEx (thresh, opening, MORPH_OPEN, kernel); / / sure background areadilate (opening, sure_bg, kernel, Point (- 1,-1), 3); / / Finding sure foreground areadistanceTransform (opening, dist_transform, DIST_L2, 5); minMaxLoc (dist_transform, 0, & maxValue, 0,0) Threshold (dist_transform, sure_fg, 0.7*maxValue, 255,0); / / Finding unknown regionsure_fg.convertTo (sure_fg, CV_8U); subtract (sure_bg, sure_fg, unknow)
See the results. In the threshold image, we get coins in some areas, and we make sure that these coins are independent. (in some cases, you may only be interested in foreground segmentation, but not in the segmentation of objects that touch each other. In this case, you don't need to use distance transformation, just erosion is enough. Erosion is just another way to extract the foreground area, that's all.)
Now we can determine which are coin areas, which are backgrounds, and so on. So we created marker (an array of the same size as the original image, but using the int32 data type) and marked the region in it. The areas we determine (whether foreground or background) are marked as any positive integers, but different integers, while our uncertain areas are left at 0. To do this, we used connectedComponents (). It marks the background of the image with 0, and then marks other objects with an integer starting at 1.
But we know that if you mark the background as 0 century watershed, you will think it is an unknown area. So we have to mark it with different integers. Instead, we will mark the unknown area, defined by unknown, as 0.
/ / Marker labellingMat markers;connectedComponents (sure_fg, markers); / / Add one to all labels so that sure background is not 0, but 1markers = markers + 1 unknow / Now, mark the region of unknown with zeromarkers.setTo (0, unknow)
Now our tag image is ready. At the last step, apply the watershed. Then modify the tag image. The boundary area is marked-1.
Mat marker;Mat mask;watershed (img, markers); compare (markers,-1, mask, CMP_EQ); img.setTo (Scalar (0,0,255), mask)
See the results below. For some coins, the area they touch is divided correctly, while for others, they are not divided.
At this point, I believe you have a deeper understanding of "how to achieve OpenCV image segmentation and watershed algorithm in C++". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 286
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.