## Friday, 27 September 2013

### Segmenting leaf by openCV2--00 : By threshold and findContours

These series of post will try to cut the leaf from the images(graph_00~graph_02) with different solutions.The first solution is based on threshold and contours.

 graph_00
 graph_01
 graph_02

Step 0

read the image and covert it to gray image

```cv::Mat color_image = cv::imread(Folder + "leaf" + num + ".png");
if(color_image.empty()){
std::cerr<<"input is empty"<<std::endl;
return -1;
}

cv::Mat image;
cv::cvtColor(color_image, image, CV_BGR2GRAY);```
Step 1

Apply threshold.

```cv::Mat binary;
cv::threshold(image, binary, 140, 255, cv::THRESH_BINARY);```
 graph_03
 graph_04
 graph_05

Step 2

Use morphology operations(erosion and close) to remove discontinuous region(erosion) and close the holes(close).

```auto const structure = cv::getStructuringElement(cv::MORPH_ELLIPSE,
cv::Size(5, 5));
cv::erode(binary, binary, structure);
cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, structure);
```
 graph_06
 graph_07
 graph_08
Step 3
find contours of the images.
```std::vector<std::vector<cv::Point>> contours;
cv::findContours(binary, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);```
 graph_09
 graph_10
 graph_11
Step 4

From step 3, we could see that graph_09~graph_11 still contains a lot of undesired blobs, we could remove them by the area of contours(the pixels in the contours).

```void remove_contours(std::vector<std::vector<cv::Point>>&contours,
double cmin, double cmax)
{
auto it = std::partition(std::begin(contours), std::end(contours),
[=](std::vector const &data)
{
auto const size = cv::contourArea(data);
return !(size < cmin || size > cmax);
});
contours.erase(it, std::end(contours));
} ```
After that, we invert the mask(change 0 to 255, 255 to 0).

 graph_12
 graph_13
 graph_14
Final results

Use the masks(graph_12~graph_14) to locate the region of interset, we get the results.

 graph_15
 graph_16
 graph_17