void FaceDetector::detectFaces(const cv::Mat &frame)
{
    if(faceClassifier.empty())
    {
        return;
    }

    vector<Rect> lastRects = getAreas();
    try
    {
        if(!(optimalSubregionDetect && lastRects.size() > 0))
        {
            vector<Rect> tempRects;
            runFaceDetect(frame, tempRects);
            hasUpdates = setAreas(tempRects);
        }
        else
        {
            detectFacesInROI(lastRects, frame);
        }

    }
    catch (Exception& exc)
    {
        return;
    }
}
void VertexBasedSegmenter::loadMesh(){

    openMeshFile(this->filename);
    cout<<"Loading "<<this->filename<<endl;
    this->centerMesh = centerCoordinate();

    faceAreas = new float[mesh.getTopSimplexesNum()];
    clusterIndex = new int[mesh.getNumVertex()];
    cout<<"found center"<<endl;

    for(unsigned int ii=0; ii<mesh.getTopSimplexesNum(); ii++){
        Triangle T = mesh.getTopSimplex(ii);
        Normals n = Normals(mesh.getVertex(T.TV(0)), mesh.getVertex(T.TV(1)), mesh.getVertex(T.TV(2)));
        norms.push_back(n);
    }
    cout<<"set normals"<<endl;
    setAreas();
    getBBDiagonal();
    cout<<"Diag "<<this->BBDiagonal<<endl;

    double auxRad = sqrt(mesh.MArea()/(NCluster*M_PI));
    this->maxD = auxRad/BBDiagonal;

    openCurvatureFile(fieldfilename);
    cout<<"Loaded function"<<endl;

    for(int ii=0; ii<mesh.getNumVertex(); ii++)
        clusterIndex[ii]=-1;

    cout<<"Before vertices"<<endl;
    vertexDistances = buildVertexDistances();
    cout<<"Vrtices built"<<endl;
    functionVDistances = buildFunctionVDistances();
    cout<<"function built"<<endl;
    buildGlobalDistances();
    cout<<"global built"<<endl;

    vertexDistances.erase(vertexDistances.begin(), vertexDistances.end());
    functionVDistances.erase(functionVDistances.begin(), functionVDistances.end());

    cout<<"All built, "<<mesh.getNumVertex()<<" vertices and "<<mesh.getTopSimplexesNum()<<" triangles"<<endl;

    //startSeg();
}
// bardziej optymalne wykrywanie dla mniejszych regionów
void FaceDetector::detectFacesInROI(vector<Rect>& lastRects, const Mat& frame)
{
    vector<Rect> newRects;
    for(vector<Rect>::iterator i = lastRects.begin(); i != lastRects.end(); ++i)
    {
        vector<Rect> tempRects;
        if(	i->x < 0 || i->y < 0 || i->width < 2 || i->height < 2)
        {
            continue;
        }

        // openCV wykrywa prostokąt, stąd wystarczy tylko szerokość
        int adjustFactor = max((static_cast<int>(i->width * roiScaleFactor) - i->width) / 2, 35);

        // ustawia region na poprzednią klatkę
        Mat roiFrame = frame(*i);

        // poszerza klatkę
        roiFrame.adjustROI(adjustFactor*1.10, adjustFactor*1.10, adjustFactor, adjustFactor);

        // wykrycie na mniejszej klatce
        runFaceDetect(roiFrame, tempRects);

        // dodanie do rezultatów wektora newRects
        for(vector<Rect>::iterator iRect = tempRects.begin(); iRect != tempRects.end(); ++iRect)
        {
            iRect->x += i->x - adjustFactor;
            iRect->y += i->y - adjustFactor;
            newRects.push_back(*iRect);
        }
    }

    // jeśli nie znaleziono twarzy, skanujemy całą klatkę
    if(newRects.empty())
    {
        runFaceDetect(frame, newRects);
    }

    // aktualizacja resultatów
    setAreas(newRects);
}