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);
        }
    }
}
Example #2
0
std::pair<vector<Point>, std::pair<Point,double>> Detect::operator() (Mat& frame, Mat& raw, int count)
{
    vector<Point> tips;

    // first find the curves in the image
    vector<vector<Point>> polyCurves = getPolyCurves(frame);

    //std::cout << polyCurves.size() << std::endl;

    // Find max inscribed circle for the 0th polycurve and draw it.
    std::pair<Point, double> maxCircle = findMaxInscribedCircle(polyCurves, raw);

    circle(raw, maxCircle.first, maxCircle.second, cv::Scalar(220,75,20), 1, CV_AA);

    // Good PolyCurve is with 3.5 * max inscribed radius
    vector<vector<Point>> goodPolyCurves;
    getRegionOfInterest(goodPolyCurves, polyCurves, maxCircle);

    // draw good poly curve
    drawContours(raw,goodPolyCurves, -1 , cv::Scalar(0,255,0), 2);

    // Find min enclosing circle on goodPolyCurve and draw it
    std::pair<Point2f, double> minCircle = findMinEnclosingCircle(goodPolyCurves);
    circle(raw, minCircle.first, minCircle.second, cv::Scalar(220,75,20), 1, CV_AA);

    // now find the convex hull for each polyCurve
    if (goodPolyCurves.size() < 1) {
        return std::pair<vector<Point>, std::pair<Point, double>>(tips, maxCircle);
    }

    // Get convex hulls
    vector<vector<int>> hullIndices = getConvexHulls(goodPolyCurves);

    vector<vector<Point>> hullPoints;
    for(int i = 0; i < goodPolyCurves.size(); i++) {
        if (goodPolyCurves[i].size() > 0) {
            vector<Point> hullPoint;
            convexHull(goodPolyCurves[i], hullPoint);
            hullPoints.push_back(hullPoint);
        }
    }

    // Draw the convex hulls
    drawContours(raw, hullPoints, -1, cv::Scalar(255, 0, 0), 2);

    
    for (int i = 0; i < 1; ++i)
    {
        vector<Vec4i> defects;
        
        // find convexity defects for each poly curve and draw them
        convexityDefects(goodPolyCurves[i], hullIndices[i], defects);

        defects = filterDefects(defects);
        vector<Point> defectEnds;

        for (int j = 0; j < defects.size(); ++j) {
            Vec4i& defect = defects[j];

            int startIdx = defect[0];
            int endIdx = defect[1];
            int farIdx = defect[2];

            Point start = goodPolyCurves[i][startIdx];
            Point end = goodPolyCurves[i][endIdx];
            Point far = goodPolyCurves[i][farIdx];
            if(euclideanDist(far, start) > maxCircle.second) {
                defectEnds.push_back(start);
                defectEnds.push_back(end);
            }
        }

        tips = findFingerTips(defectEnds, maxCircle, raw);
    }

    flip(raw, raw, 1);
    imshow("hand", raw);

    // movie code (we should return the frame to HandMade and put movie code there with the others.)
    if(makeMoviesD) {
	    char buffer[30];
	    sprintf(buffer, "detected/detected_%03d.jpg", count++);
	    imwrite(buffer, raw);
	}

    return std::pair<vector<Point>, std::pair<Point, double>>(tips, maxCircle);
}