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; }