Mat fillHoleInBinary(Mat bwImage) {
    vector<vector<Point> > contours, onlyContours(1);
    vector<Vec4i> hierarchy;
    
    findContours( bwImage.clone(), contours, hierarchy,
                 CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    
    Mat mask(bwImage.size(),CV_8UC1,Scalar::all(0));
    
    drawContours(mask, contours, -1, Scalar(255), CV_FILLED);
    
    return mask;
    
}
Mat fillConvexHulls(Mat bwImage) {
    vector<vector<Point> > contours, onlyContours(1);
    vector<Vec4i> hierarchy;
    
    findContours( bwImage.clone(), contours, hierarchy,
                 CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
    
    // Find the convex hull object for each contour
    vector<vector<Point> >hull( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
    {
        convexHull( Mat(contours[i]), hull[i], false );
    }
    
    Mat drawing = Mat::zeros( bwImage.size(), CV_8UC1 );
    for( int i = 0; i< contours.size(); i++ )
    {
        drawContours(drawing, contours, i, Scalar(255), CV_FILLED);
        drawContours( drawing, hull, i, Scalar(255), CV_FILLED);
    }

    return drawing;
}
Mat removeSmallBlobs(Mat bwImage) {
    vector<vector<Point> > contours, onlyContours(1);
    vector<Vec4i> hierarchy;
    
    findContours( bwImage.clone(), contours, hierarchy,
                 CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    vector<double> areas(contours.size());
    if (contours.size() >0 ){
        for(size_t i= 0 ; i < contours.size() ; i ++) {
            areas[i] = contourArea(contours[i]);
            //        cout<<areas[i]<<",";
        }
        
        long biggestIndex = distance(areas.begin(), max_element(areas.begin(),areas.end()));
        //    cout<<biggestIndex<<":"<<areas[biggestIndex]<<endl;
        onlyContours[0] =contours[biggestIndex];
        Mat mask(bwImage.size(),CV_8UC1,Scalar::all(0));
        
        drawContours(mask, onlyContours, -1, Scalar(255), CV_FILLED);
        return mask;
    }
    return bwImage;
}
Point2f findMassCenter_BinaryBiggestBlob(const Mat& bw_img) {
    Mat full_bw_img = removeSmallBlobs(bw_img);
    threshold(bw_img, bw_img, 254, 255, CV_THRESH_BINARY);
    
    vector<vector<Point> > contours,onlyContours(1);
    
    vector<Vec4i> hierarchy;
    
    findContours( bw_img.clone(), contours, hierarchy,
                 CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    
    if (contours.size() >0) {
        vector<int> areas(contours.size());
        for(size_t i= 0 ; i < contours.size() ; i ++) {
            areas[i] = contourArea(contours[i]);
            //        cout<<areas[i]<<",";
        }
        
        long biggestIndex = distance(areas.begin(), max_element(areas.begin(),areas.end()));
        //    cout<<biggestIndex<<":"<<areas[biggestIndex]<<endl;
        onlyContours[0] =contours[biggestIndex];
        
        /// Get the moments
        vector<Moments> mu(contours.size() );
        for( int i = 0; i < contours.size(); i++ )
        { mu[i] = moments( contours[i], false ); }
        
        ///  Get the mass centers:
        vector<Point2f> mc( contours.size() );
        for( int i = 0; i < contours.size(); i++ )
        { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
        
        return mc[0];
    } else
        return Point(0,0);
}