graph_00 |
graph_01 |
graph_02 |
Step 0
Read the images(graph_00~graph_02) and convert 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
Binarize the image.
cv::Mat binary; cv::threshold(image, binary, 140, 255, cv::THRESH_BINARY);
Step 2
Remove small objects and noise.
auto const structure = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); cv::Mat fore_ground; cv::erode(binary, fore_ground, structure, cv::Point(-1, -1), 4);
We severely erode the images in order to retain only pixels belonging to the foreground.
Step 3
Some of the objects can't removed by erosion, so we find out the contours of the image and remove unimportant objects from the images in order to get the foreground(255), they will be considered to correspond to objects of interest.
std::vector<std::vector<cv::Point>> contours; cv::findContours(fore_ground, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); OCV::remove_contours(contours, 8000, 50000); fore_ground.setTo(0); cv::drawContours(fore_ground, contours, -1, cv::Scalar(255), CV_FILLED);
remove_contours was explained in the previous post.
graph_03 |
graph_04 |
graph_05 |
Step 4
Mark the background as 128 and mark unknown pixels(neither foreground nor background) as 0.
cv::Mat back_ground; cv::dilate(binary, back_ground, structure, cv::Point(-1, -1), 4); cv::threshold(back_ground, back_ground, 1, 128, cv::THRESH_BINARY_INV);
graph_06 |
graph_07 |
graph_08 |
Step 5
Combined foreground and background to get marker and use the marker to get the mask we need.
cv::Mat markers = back_ground + fore_ground; cv::Mat mask; markers.convertTo(mask, CV_32S); cv::watershed(color_image, mask); mask.convertTo(mask, CV_8U); cv::threshold(mask, mask, 150, 255, CV_THRESH_BINARY);
graph_09 |
graph_10 |
graph_11 |
Step 6
Generate final result.
cv::Mat result; color_image.copyTo(result, mask);
graph_12 |
graph_13 |
graph_14 |
Next post of Recognize leaf by openCV2