Detect multiple similar objects in a bunch of still images

asked 2013-09-28 10:58:41 -0600

stereomatching gravatar image

updated 2020-10-01 23:16:59 -0600

00 01 02

How could I separate the whole leaf into 5 independent leaf(blob)?The ultimate purpose is collect the BGR value of each leaf(leaf1, leaf2, leaf3, leaf4 and so on).

I am a newbie of computer vision, there are tons of algorithms I haven't learned yet. Any algorithms are possible to solve this problem?

Edit : According to the suggestion of GilLevi(thanks), i use houghLinesP to draw the lines on the image after segmentation.

//remove contours size which smaller than cmin or bigger than cmax
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<cv::Point> const &data)
    {
       auto const size = cv::contourArea(data);
       return !(size < cmin || size > cmax);
    });
    contours.erase(it, std::end(contours));
}

void cut_to_single_leaf(cv::Mat const &input)
{    
    cv::Mat fore_ground_edge;
    cv::cvtColor(input, fore_ground_edge, CV_BGR2GRAY);
    cv::Canny(fore_ground_edge, fore_ground_edge, 100, 350);        

    cv::Mat result = input.clone();
    std::vector<cv::Vec4i> lines;
    cv::HoughLinesP(fore_ground_edge, lines, 1, CV_PI/180, 80, 0, 40);
    for( auto const &line : lines){
        cv::line(result, cv::Point(line[0], line[1]),
                cv::Point(line[2], line[3]), cv::Scalar(0,0,0), 2, 8);
    }

    cv::Mat binary_result;
    cv::cvtColor(result, binary_result, CV_BGR2GRAY);
    ContoursType contours;
    cv::findContours(binary_result, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    gray_result.setTo(0);
    OCV::remove_contours(contours, 500, 50000);
    std::cout<<contours.size()<<std::endl;
    cv::drawContours(binary_result, contours, -1, cv::Scalar(255), 2);         

    cv::waitKey();
}

The results(use first image as an example)

hough lines binary results

The results are far from perfect. The leftmost leaf are separated to two leafs. The center leaf are glue as one leaf.

Question 1 : Any good idea to find out which contours should merge together? ex : leftmost contours should apply dilation since it is splited to two leafts

Question 2 : How could I open the leaf of center? try erosion and open, but the results are not good, hard to predict

Question 3 : Any other algorithms are good to detect multiple similar objects in a still image? just study SIFT and SURF, they could not detect multiple objects in a still image. I can not separate the image into different ROI and apply SIFT or SURF, because the orientation of the leafs are different in the images.

edit retag flag offensive close merge delete

Comments

Perhaps by finding contours and looking for Hough lines. I would try to search for four almost parallel lines that separate the leaves.

GilLevi gravatar imageGilLevi ( 2013-09-29 10:28:43 -0600 )edit

Perhaps you measure the width of each "suggested leaf" and use voting to find the width that most lines agree on. Since the leafs are almost identical, they should have the same width.

Once you have the width of the leaf, divide the total width by the leaf width, thus obtaining the number of leafs.

GilLevi gravatar imageGilLevi ( 2013-09-30 16:58:31 -0600 )edit

@GilLevi : I need to collect the BGR value of each leaf too.

stereomatching gravatar imagestereomatching ( 2013-10-01 01:34:32 -0600 )edit

If you have the width and the lines in the border of the leafs, you can draw a box around each leaf and extract it's RGB values.

GilLevi gravatar imageGilLevi ( 2013-10-01 07:16:06 -0600 )edit