void MyGesture::removeRedundantEndPoints(vector<Vec4i> newDefects, MyInputImgStruct *m){ /*** * DOC: */ Vec4i Temp; int startidx, endidx, faridx, startidx2, endidx2; float Tolerance = bRect_Width/6; for(int i=0; i<newDefects.size(); i++) { for(int j=i; j<newDefects.size(); j++) { startidx = newDefects[i][0]; Point ptStart(contours[cIdx][startidx]); endidx = newDefects[i][1]; Point ptEnd(contours[cIdx][endidx]); startidx2 = newDefects[j][0]; Point ptStart2(contours[cIdx][startidx2]); endidx2 = newDefects[j][1]; Point ptEnd2(contours[cIdx][endidx2]); if(distanceP2P(ptStart, ptEnd2) < Tolerance) { contours[cIdx][startidx] = ptEnd2; break; } if(distanceP2P(ptEnd, ptStart2) < Tolerance) { contours[cIdx][startidx2] = ptEnd; } } } }//ENDOF Method: removeRedundantEndPoints(newDefects, *m)
double GraphMatching::PosDistOf2Subgraph(SubGraph& sub1, SubGraph& sub2){ sub1.reorganizeGraph(); sub2.reorganizeGraph(); int num1 = sub1._edges.size(); int num2 = sub2._edges.size(); double dist = 0; vector<double> vec_sub1,vec_sub2;//记录中心node与adjacent nodes之间的方向vector cos thea FacNode node1 = sub1._centerNode; FacNode node2 = sub2._centerNode; #if 0 //previous diatance measure for(int i=0;i<sub1._edges.size();i++){ Point vec1 = sub1._edges[i]._node2._position - node1._position; Point vec2 = sub2._edges[i]._node2._position - node1._position; //夹角差 double thea1 = acos (calcAngleOf2Vec(vec1,Point(1,0)))/PI; double thea2 = acos (calcAngleOf2Vec(vec2,Point(1,0)))/PI; double posdist = distanceP2P(sub1._edges[i]._node2._position,sub2._edges[i]._node2._position) /sqrt(pow(sub1._centerNode._srcImg.rows,2)+pow(sub1._centerNode._srcImg.cols,2)); dist += abs(thea1 - thea2) + posdist; //bounding box double thresh_neighbor = 0.4; dist += thresh_neighbor*abs(sub1._edges[i]._node2._WslashH - sub2._edges[i]._node2._WslashH); dist += thresh_neighbor*(abs(boundingRect(sub1._edges[i]._node2._contour).width - boundingRect(sub2._edges[i]._node2._contour).width) +abs(boundingRect(sub1._edges[i]._node2._contour).height - boundingRect(sub2._edges[i]._node2._contour).height))/2; } //distance of 2 center node dist += distanceP2P(sub1._centerNode._position,sub2._centerNode._position); ///sqrt(pow(sub1._centerNode._srcImg.rows,2)+pow(sub1._centerNode._srcImg.cols,2)); //distance of geometry W/H dist += abs(sub1._centerNode._WslashH - sub2._centerNode._WslashH); //distance of geometry width&height of boundingbox dist += (abs(boundingRect(sub1._centerNode._contour).width - boundingRect(sub2._centerNode._contour).width) +abs(boundingRect(sub1._centerNode._contour).height - boundingRect(sub2._centerNode._contour).height))/2; #endif #if 1 if(num1 != num2){ std::cout<<"PosDistOf2Subgraph(): 2 subgraph does not have same size"<<endl; return INF; } for(int i=0;i<sub1._edges.size();i++){ dist += disOfTwoNodes(sub1._edges[i]._node2,sub2._edges[i]._node2); } dist += disOfTwoNodes(sub1._centerNode,sub2._centerNode); #endif return dist; }
float MyGesture::getAngle(Point s, Point f, Point e){ /*** * DOC: takes 3 points and return the angle between them **/ float LineFS = distanceP2P(f, s); float LineFE = distanceP2P(f, e); float delTheta = (s.x - f.x)*(e.x - f.x) + (s.y - f.y)*(e.y - f.y); float theta = acos(delTheta / (LineFS * LineFE)); theta = theta*180/PI; return theta; } //ENDOF Method: getAngle()
vector<double> FacEdge::calcSpatialFeature(){ vector<double> feature; feature.resize(5); feature[0] = _node1._box.tl().x - _node2._box.tl().x; feature[1] = _node1._box.br().x - _node2._box.br().x; feature[2] = distanceP2P(_node1._position,_node2._position); double unionNN = countUnion(_node1,_node2); feature[3] = unionNN/contourArea(_node1._contour); feature[4] = unionNN/contourArea(_node2._contour); return feature; }
void MyGesture::eleminateDefects(MyInputImgStruct *m){ /*** * @DOC: Takes all the defect points into vector d. Loops through d and * measures the P2P distance between the Defect Points and decides whether * the Point will be dismissed or kept based on l>0.4lbb and Theta>85' **/ int tolerance = bRect_Height/5; float angleTol = 95; vector<Vec4i> newDefects; int startidx, endidx, faridx; vector<Vec4i>::iterator d = Defects[cIdx].begin(); while(d != Defects[cIdx].end()) { Vec4i& v = (*d); startidx = v[0]; Point ptStart(contours[cIdx][startidx]); endidx = v[1]; Point ptEnd(contours[cIdx][endidx]); faridx = v[2]; Point ptFar(contours[cIdx][faridx]); if((distanceP2P(ptStart, ptFar) > tolerance) && (distanceP2P(ptEnd, ptFar) > tolerance) && (getAngle(ptStart, ptFar, ptEnd) < angleTol)){ if(ptEnd.y > (bRect.y + bRect.height - bRect.height/4)) {/*Do Nothing*/} else if(ptStart.y > (bRect.y + bRect.height - bRect.height/4)) {/*Do Nothing*/} else { newDefects.push_back(v); } } d++; }//ENDOF While() numOfDefects = newDefects.size(); Defects[cIdx].swap(newDefects); removeRedundantEndPoints(Defects[cIdx], m); } //ENDOF Method: eleminateDefects(MyInputImgStruct *m)
void MyGesture::removeRedundantFingerTips(){ /*** * DOC: */ vector<Point> newFingers; for(int i=0; i<FingerTips.size(); i++) { for(int j=i; j<FingerTips.size(); j++) { if( (distanceP2P(FingerTips[i], FingerTips[j]) < 10) && (i != j) ) { /*Do Nothing*/} else { newFingers.push_back(FingerTips[i]); break; } } } }//ENDOF Method: removeRedundentFingerTips()
double calcAngleOf2Vec(cv::Point& vec1,cv::Point& vec2){ double cos_theta = (vec1.x * vec2.x + vec1.y * vec2.y) / (distanceP2P(cv::Point(0,0),vec1) * distanceP2P(cv::Point(0,0),vec2)); return cos_theta; }
int createDBC_s32(const IplImage* input_image) { //uint8_t t_depth_u8 = 0; //uint8_t t_gest_name_u8 = 0; uint8_t t_smp_idx_u8 = 1; uint8_t t_depth_idx_u8 = 0; uint8_t t_gest_idx_u8 = 1; //char t_depth_c[2]; //char t_gest_c[2]; char ImgFileName_c[40] = ".\\training_data\\dxxx\\numx\\imgxx.png"; IplImage* t_imgSamp_pImg; float t_dist_f = 0; g_trnDBC_pfi = fopen(trDBC_FileName_c, "w"); //number zero database fprintf(g_trnDBC_pfi, "%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); fprintf(g_trnDBC_pfi, "\n"); if(g_trnDBC_pfi == NULL) { return (-1); //Cannot open database file. May be there is incorrect the name of database file. } while(t_depth_idx_u8 < DEPTH_NUM) { /* Get file name */ /* Replace dxxx to folder name of depth image */ strncpy(ImgFileName_c + 16, fname[t_depth_idx_u8], 4); while(t_gest_idx_u8 < GEST_NUM) { if(t_gest_idx_u8 < 10) { sprintf(&t_temp_c[0],"%d", t_gest_idx_u8); strncpy(ImgFileName_c + 24, (const char*)&t_temp_c, 1); } else { sprintf(&t_temp_c[0],"%d", t_gest_idx_u8); strncpy(ImgFileName_c + 23, (const char*)&t_temp_c, 2); } t_smp_idx_u8 = 1; while (t_smp_idx_u8 <= SAMPLE_NUM_MAX) { memset(&trainingData_st, 0 , sizeof(TRAININGDATA_ST)); if(t_smp_idx_u8 < 10) { sprintf(t_temp_c,"%s%d","0", t_smp_idx_u8); strncpy(ImgFileName_c + 29, (const char*)&t_temp_c, 2); } else //number of samples is greater than or equal to 10 { sprintf(t_temp_c,"%d", t_smp_idx_u8); strncpy(ImgFileName_c + 29, (const char*)&t_temp_c, 2); } /*open image sample */ t_imgSamp_pImg = cvLoadImage(ImgFileName_c, CV_LOAD_IMAGE_GRAYSCALE); if(t_imgSamp_pImg != NULL) { /*extract feature */ HandGestureSt.dfdisthreshold = 5000/depth_u16[t_depth_idx_u8]; HandGestureSt.thr_image = t_imgSamp_pImg; HandGestureSt.handDepth = depth_u16[t_depth_idx_u8]; handTrainingProcessing(); //sortFingers_V(HandGestureSt.fingers, FINGER_NUM); //map to training data trainingData_st.finger_num_u8 = HandGestureSt.num_fingers; /*Write to training data*/ fprintf(g_trnDBC_pfi, "%d;", trainingData_st.finger_num_u8); for (int idx = 0; idx < trainingData_st.finger_num_u8; idx++) { trainingData_st.angle_f[idx] = angleToCOG(HandGestureSt.fingers[idx], HandGestureSt.hand_center_mm, HandGestureSt.contourAxisAngle); trainingData_st.dis_f[idx] = distanceP2P((const CvPoint*)&HandGestureSt.hand_center_mm, (const CvPoint*)&HandGestureSt.fingers[idx]) - HandGestureSt.hand_radius; } //sortArray_V((float* const)&trainingData_st.dis_f[0], (const uint8_t)FINGER_NUM); //sortArray_V((float* const)&trainingData_st.angle_f[0], (const uint8_t)FINGER_NUM); for (int idx = 0; idx < FINGER_NUM; idx++) { fprintf(g_trnDBC_pfi, "%0.3f;", trainingData_st.angle_f[idx]); } for (int idx = 0; idx < FINGER_NUM; idx++) { fprintf(g_trnDBC_pfi, "%0.3f;", trainingData_st.dis_f[idx]); } fprintf(g_trnDBC_pfi, "%d", t_gest_idx_u8); fprintf(g_trnDBC_pfi, "\n"); t_smp_idx_u8++; } else { t_smp_idx_u8 = 1; break; } } t_gest_idx_u8++; } t_depth_idx_u8++; } if (fclose(g_trnDBC_pfi) == 0) { return 0; } else { return (-1); } }