cv::Mat connectedComponentsFilter(cv::Mat& curFrame, cv::Mat& img) {

    if (!img.isContinuous()) {
        throwError("Parammeter 'img' in 'connectedComponentsFilter' must be continuous");
    }

    //morphology_(img);

    maskContours.clear();

    // Отрисовать найденные области обратно в маску
    cv::Mat result(img.size(), img.type());
    result.setTo(0);

    cv::findContours(img, maskContours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    size_t i = 0;

    while (i < maskContours.size()) {
        Contour& contour = maskContours[i];

        cv::Mat contourMat(contour, false);
        double len = cv::arcLength(contourMat, true);

        if (len * PERIM_SCALE < img.size().height + img.size().width) {
            // Отбрасываем контуры со слишком маленьким периметром.
            maskContours.erase(maskContours.begin() + i);
        } else {
            // Достаточно большие контуры аппроксимируем указанным методом.
            Contour newContour;

            // Методы аппроксимации.
            //cv::approxPolyDP(contourMat, newContour, CHAIN_APPROX_SIMPLE, true);
            cv::convexHull(contourMat, newContour, true);

            cv::Mat newContourMat(newContour, false);
            Rect boundingRect = cv::boundingRect(newContourMat);
            cv::rectangle(curFrame, boundingRect, cv::Scalar(255));

            maskContours[i] = newContour;

            i++;

            //points.push_back(CvPoint(boundingRect.x + boundingRect.width / 2, boundingRect.y + boundingRect.height / 2));
        }
    }


    if (!maskContours.empty()) { // Обходим баг OpenCV 2.1.0; в 2.3.1 он уже исправлен.
        cv::drawContours(result, maskContours, -1, cv::Scalar(255), FILLED);

    }
    return result;
}
bool closeSurface(  fwVertexPosition &_vertex, fwVertexIndex &_vertexIndex )
{
    typedef std::pair< int, int  >  Edge;
    typedef std::vector< Edge > Contour; // at Border
    typedef std::vector< Contour> Contours;

    Contours contours;
    findBorderEdges( _vertexIndex , contours);
    bool closurePerformed = !contours.empty() ;
    // close each hole
    for ( Contours::iterator contour=contours.begin();  contour != contours.end(); ++contour )
    {
        int newVertexIndex = _vertex.size() ;
        // create gravity point & insert new triangle
        std::vector< float > massCenter(3,0);
        for ( Contour::iterator edge =contour->begin();  edge != contour->end(); ++edge )
        {
            for (int i=0; i<3; ++i )
            {
                massCenter[i]  += _vertex[edge->first][i];
                massCenter[i]  += _vertex[edge->second][i];
            }
            // create new Triangle
            std::vector< int > triangleIndex(3);
            triangleIndex[0] =  edge->first;
            triangleIndex[1] =  edge->second;
            triangleIndex[2] =  newVertexIndex;
            _vertexIndex.push_back( triangleIndex ); // TEST
        }
        for (int i=0; i<3; ++i )
        {
            massCenter[i] /= contour->size()*2;
        }
        _vertex.push_back( massCenter ); // normalize barycenter
    }
    return closurePerformed;
}