井号键编译

  如何写一个简单的手写识别算法,可以精准快速的识别出自定义的简单图形:

1450555byd2b080knay051.jpg
  把所有的笔画定义了个8个方向,然后将B的笔画可以分解成一个字符串。然后当人在触摸屏上画出一个符号时,也将它分解成8个方向的字符串,最后比较两个字符串的距离就能判断出和不同符号的近似度。

1450552ukwkljuvkef2iwe.jpg
  实现起来也很简单,第一步去噪,因为不同触摸屏的采样频率不同。

1450553ks3izriu76y683r.jpg

  实现代码:
 

  1. void GestureAlgorithm::addPoint(int x, int y){int d_x, d_y;
  2. d_x = x-positions.back().x;d_y = y-positions.back().y;
  3. if( d_x*d_x + d_y*d_y >= MIN_MOVEMENT){updateStatistic(x, y);recognizeGesture();}}
  4. void GestureAlgorithm::updateStatistic(int x, int y){positions.push_back(Point(x, y));point_num = positions.size();if(point_num >1){// For Point Recognizationdist_sum += positions.begin()->dist(x,y);dist_average =dist_sum/(point_num - 1);
  5. // For Line Recognization// Need a patch for the V0 calculation.Point v0 = Point(positions[1].x - positions[0].x, positions[0].y );Point v1 = Point(x - positions[0].x, y -positions[0].y);if(normalize(v0) normalize( v1)){float theta = acos(dot(v0, v1));theta_sum += theta;theta_sqsum += sq(theta);theta_average = theta_sum / (float)(point_num - 1);theta_factor = sqrt((float)(point_num - 1)*theta_sqsum - sq(theta_sum))/(point_num-1);}}mainDirections = detectDirection(positions);
  6. //Statistic Updatepos_x_sum += x;pos_y_sum += y;pos_xx_sum += sq(x);pos_xy_sum += x * y;
  7. midPoint = Point(pos_x_sum/point_num, pos_y_sum/point_num);curGestureRender->render_bbox->addPoint(x, y);}


  实现代码:

  1. PosList GestureAlgorithm::limitDirections(const PosList positions)
    • {
      • PosList res;
        • int lastx, lasty;
          • bool firstTime = true;
            •  
            • for( PosList::const_iterator ii = positions.begin(); ii != positions.end(); ++ii )
              • {
                • if( firstTime )
                  • {
                    • lastx = ii->x;
                      • lasty = ii->y;
                        •  
                        • firstTime = false;
                          • }
                            • else
                              • {
                                • int dx, dy;
                                  •  
                                  • dx = ii->x – lastx;
                                    • dy = ii->y – lasty;
                                      •  
                                      • if( dy > 0 )
                                        • {
                                          • if( dx > dy -dx > dy )
                                            • dy = 0;
                                              • else
                                                • dx = 0;
                                                  • }
                                                    • else
                                                      • {
                                                        • if( dx > -dy -dx > -dy )
                                                          • dy = 0;
                                                            • else
                                                              • dx = 0;
                                                                • }
                                                                  • res.push_back( Point( dx, dy ) );
                                                                    • lastx = ii->x;
                                                                      • lasty = ii->y;
                                                                        • }
                                                                          • }
                                                                            •  
                                                                            • return res;
                                                                              • }
                                                                                •  

 


  实现代码:

  1. Position Num:141
    • X=113 Y= 0
      • X= 0 Y= -15
        • X=0 Y= 179
          • X= 13 Y= 0
            • X=-110 Y= 0
              • X= 0 Y= 6
                • X=0 Y= -101
                  • X= 3 Y= 0
                    • Directions Number: 8
                      • Directions Length:540
                        • UP Number: 3 Down Number: 2 Left: 1 right 2
                          • Position Num:142


  实现代码:

  1. PosList GestureAlgorithm::removeShortestNoise(const PosList positions)
    • {
      • PosList res;
        • int shortestSoFar;
          • PosList::const_iterator shortest;
            • bool firstTime = true;
              •  
              • for( PosList::const_iterator ii = positions.begin(); ii != positions.end(); ++ii )
                • {
                  • if( firstTime )
                    • {
                      • shortestSoFar = ii->x*ii->x + ii->y*ii->y;
                        • shortest = ii;
                          •  
                          • firstTime = false;
                            • }
                              • else
                                • {
                                  • if( (ii->x*ii->x + ii->y*ii->y) < shortestSoFar ) { shortestSoFar = ii->x*ii->x + ii->y*ii->y;
                                    • shortest = ii;
                                      • }
                                        • }
                                          • }
                                            •  
                                            • for( PosList::const_iterator ii = positions.begin(); ii != positions.end(); ++ii )
                                              • {
                                                • if( ii != shortest)
                                                  • res.push_back( *ii );
                                                    • }
                                                      •  
                                                      • return res;
                                                        • }
                                                          •  
                                                          • PosList GestureAlgorithm::detectDirection(const PosList positions)
                                                            • {
                                                              • PosList directions = simplify(limitDirections(positions));
                                                                • double minLength = calcLength(directions) *minMatch;
                                                                  •  
                                                                  • while(directions.size() > 0 calcLength(removeShortestNoise(directions)) > minLength)
                                                                    • {
                                                                      • directions = simplify(removeShortestNoise(directions));
                                                                        • }
                                                                          •  
                                                                          • upNum = 0; downNum = 0; leftNum = 0; rightNum =0;
                                                                            • for(int i = 0; i< directions.size(); i++) { if(directions[i].y >= 0 directions[i].x ==0)
                                                                              • upNum++;
                                                                                • else if(directions[i].y < 0 directions[i].x ==0) downNum++; else if(directions[i].x >= 0 directions[i].y ==0 )
                                                                                  • leftNum++;
                                                                                    • else if(directions[i].x < 0 directions[i].y ==0 )
                                                                                      • rightNum++;
                                                                                        • }
                                                                                          • return directions;
                                                                                            • }

复制代码
  这个算法的厉害之处是可以实时识别,画到一半也能判断出来。
锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛