Example #1
0
void HandDetection::detectHands(Mat& depthImage, Mat& color) {
    vector<Point> manoI, manoD;
    vector<vector<Point> > contornos;
    vector<Vec4i> hierarchy;
    vector<int> phull1, phull2;
    vector<CvConvexityDefect> fingerTips1, fingerTips2;
    vector<Point> curva1, curva2;
    Point ref(0, ROWS/2);
    vector<Point> palm2;
    int distancia1;// distancia2;
    distancia1 = 2000;
//    distancia2 = 2000;

    cv::findContours(depthImage, contornos, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
    for(size_t i=0; i<contornos.size(); i++) {
        double aux = contourArea(Mat(contornos[i]));

        if(aux > 0 && aux >= 1000 && aux <= 35000) {//35000
//          Comparar cada blob en base a la distancia con su punto de "tracking"
            Rect r = boundingRect(Mat(contornos[i]));
            Point punto = Utils::getRectCenter(r);
            int d = (int)Utils::OXDistance(punto, ref);
            int aux1 = (int)Utils::OXDistance(punto, m_left_hand->getEstimatedPoint());
//            int aux2 = (int)Utils::OXDistance(punto, m_right_hand->getEstimatedPoint());
            bool isleft = false;
            if(d < COLS/2 ){//&& area > _leftHand->getArea()
                manoI = contornos[i];
                m_left_hand->setContour(manoI);
                m_left_hand->setCenter(punto);
                m_left_hand->setWhich(LEFT_HAND);
                isleft = true;
                distancia1 = aux1;
            }
            if(d >= COLS/2){
                manoD = contornos[i];
                m_right_hand->setContour(manoD);
                m_right_hand->setCenter(punto);
                m_right_hand->setWhich(RIGHT_HAND);
            }
        }
    }

    m_left_hand->trackObject(color);//tienes q ver que pasa si lefhand vale lo mismo q antes
//    m_right_hand->trackObject(color);
    Point p = m_right_hand->getCenter();
    circle(color, p, 10, Scalar(200,200,200), 5, -1);

    //Calculamos los poligonos de Hull (convex Hull)
    if(manoD.size() > 0){
        Rect r1 = boundingRect(Mat(manoD));
        rectangle(color, r1, Scalar(0,0,255), 3);
        Mat matriz1(manoD);
        if(matriz1.rows > 0 && matriz1.cols > 0){
            //Calculamos el poligono convexo que recubre la mano
            //Simplificamos, primero, el contorno.
            approxPolyDP(matriz1, curva1, APPROX_POLY_SIDES, true);//20
            Mat curvi(curva1);
            convexHull(curvi, phull1, CV_CLOCKWISE);
            vector<Point> poly;
            for(int i=0; i<(int)phull1.size(); i++){
                poly.push_back(curva1[phull1[i]]);
            }

            //Ahora dibujamos los defectos de convexidad
            vector<CvConvexityDefect> defects;
            findConvexityDefects(curva1, phull1, defects);//pasar curva2 a int*

            //De todos los start y end, te quedas con los que coincidan del poligono aproximado
            findFingerTips(curva1, defects, fingerTips1);
            int fingersCount = (int)fingerTips1.size();
            m_right_hand->setFingers(fingersCount);
        }
    }

    if(manoI.size() > 0){
        Rect r2 = boundingRect(Mat(manoI));
        rectangle(color, r2, Scalar(255,0,0), 3);
        Mat matriz2(manoI);
        if(matriz2.rows > 0 && matriz2.cols > 0){
            //Calculamos el poligono convexo que recubre la mano
            //Simplificamos, primero, el contorno.
            approxPolyDP(matriz2, curva2, APPROX_POLY_SIDES, true);//20
            Mat curvi(curva2);
            convexHull(curvi, phull2, CV_CLOCKWISE);
            vector<Point> poly;
            for(int i=0; i<(int)phull2.size(); i++){
                poly.push_back(curva2[phull2[i]]);
            }

            //Ahora dibujamos los defectos de convexidad
            vector<CvConvexityDefect> defects;
            findConvexityDefects(curva2, phull2, defects);//pasar curva2 a int*

            //De todos los start y end, te quedas con los que coincidan del poligono aproximado
            findFingerTips(curva2, defects, fingerTips2);

            //Analizamos la informacion de los supuestos dedos
            for(int i=0; i<(int)fingerTips2.size(); i++){
                CvPoint cvp1 = *(fingerTips2.at(i).start);
                CvPoint cvp2 = *(fingerTips2.at(i).end);
                CvPoint cvdef = *(fingerTips2.at(i).depth_point);
                Point p1(cvp1.x, cvp1.y);
                Point p2(cvp2.x, cvp2.y);
                Point p3(cvdef.x, cvdef.y);
                line(color, p1, p3, Scalar(0, 255, 0), 1, CV_AA);
                line(color, p2, p3, Scalar(0, 255, 0), 1, CV_AA);
                cv::circle(color, p1, 10, Scalar(200,200,200), -1, CV_AA);
                cv::circle(color, p3, 10, Scalar(0,0,0), 2, CV_AA);
                palm2.push_back(p3);
            }
            //Obtenemos el centro de la palma
//            if(palm2.size() > 0){
//                minEnclosingCircle(Mat(palm2), center2, radius2);
//                cv::circle(color, center2, radius2, Scalar(255,255,255), -1, CV_AA);
//            }
            int fingersCount = (int)fingerTips2.size();
            m_left_hand->setFingers(fingersCount);
        }
    }
}
int ConvexityClassifier::Convexity_Computing(Mat &segmentedHand) {
    
    Mat out;
    vector<Point> contours,polygon;
    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours_points;
    Scalar color(rand()&255, rand()&255, rand()&255);
    
    //cout << "FIND_CONTOURS_POINTS" << endl;
    /*Looking for Contours Points*/
    findContours( segmentedHand, contours_points, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
    
    //cout << "BIGGEST_CONTOURS" << endl;
    /*Convert vector<vector<Point>> to vector<Point> and find the biggest contours*/
    contours = BiggestContour (contours_points);
    
    /*Approximation of Hands Contours by Polygon*/
    //cout << "POLY_APPROX" << endl;
    approxPolyDP(contours,polygon,15,true);
    contours = polygon;
    
    /*Finding the center of palm*/
    //cout << "MIN_AREA_RECT" << endl;
    RotatedRect Palm = minAreaRect(contours);
    float Palm_Radius;
    if( Palm.size.height <= Palm.size.width )
        Palm_Radius = Palm.size.height / 2;
    else
        Palm_Radius = Palm.size.width / 2;
        
    vector<int> index_hull_points(contours_points.size());
    vector<Point> convexityDefects(contours_points.size());
    vector<Point> Concave_points;
    vector<int> Convex_points;
    //cout << "CONVEX_HULL" << endl;
    convexHull(contours,index_hull_points,false,false); //Find the index of Convex points
    
    /*Convexity Adapt from OpenCV [C versions]*/
    vector<Point>& contour = contours;
    vector<Point>& convexDefects = convexityDefects;
    vector<int>& hull = index_hull_points;
    //cout << "FIND_CONVEXITY_DEFECTS" << endl;
    findConvexityDefects(contour,hull,convexDefects);
    
    /*Controling Result*/
    //cout << "ALL Concave points: " << convexDefects.size() << endl;
    //cout << "ALL Convex points: " << hull.size() << endl;
    
    /*Filtering Concave points*/
    //cout << "FILTERING_CONCAVE_POINTS" << endl;
    Concave_points = Filtering_Concave_Point( convexDefects , Palm );
       
    /*Filtering Convex points*/
    //cout << "FILTERING_CONVEX_POINTS" << endl;
    Convex_points = Filtering_Convex_Point( hull , contour , Palm );
    
    //cout << "First Filter Convex points: " << Convex_points.size() << endl;
       
    vector<int> tmp;
    /*Isolating the interesting convex points*/
    //cout << "ISOLATING_CONVEX_POINTS" << endl;
    tmp = Isolating_Convex_Point( Convex_points , contour );
    
    //cout << "Second Filter Convex points: " << tmp.size() << endl;
    
    vector<int> result;
    float min_distance = Palm.center.y - Palm_Radius;
    /*Isolating convex_points by the Average Radius of the palm**/
    //cout << "ISOLATING_BY_AVERAGE" << endl;
    result = Isolating_Convex_Point_byAverage( contour , Concave_points , min_distance , tmp );
    
    //cout << "Convex points: " << result.size() << endl;
    
    //cout << "Concave points: " << Concave_points.size() << endl;
    
    float min_distance2 = Palm.center.y - (Palm_Radius * 2);
    /*Compute result*/
    float result_digital_numbers;
    //cout << "COMPUTE_RESULT" << endl;
    result_digital_numbers = Compute_Result( contour , Concave_points , result , min_distance2 );
    //cout<< "********************************" << endl;
    //cout<< "SIZE: " << segmentedHand.size() << endl;
    //cout<< "********************************" << endl;
    
    /*Drawing Convex of polygon*/
    for(int i = 0; i < contours_points.size() ; i++)
    {
        drawContours( segmentedHand, contours_points, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
    }
    
    /*Affichage*/
//    imshow("contour",segmentedHand);
  //  waitKey(0);
    
    return result_digital_numbers;
}