单个手指的手势识别

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!

       本文把Aforge的运动识别前面介绍的手写识别融合在一起,实现单个手指的手势识别。下图演示了本文代码运行的结果,图片有点大,请稍候。。。

 

       我预先让程序学习了B和C这两个字母,然后通过手指的手势识别向程序绘画图形,所以点击recorgize时,就自动把图形的特征对应的字母给识别出来了。

      这个例子关键部分在于如何灵活运用Aforge的运动识别,如何判断是要画图,还是普通的移来移去呢?在这里,我判断移动对象的大小,当突然面积增大(即两个指套合并)则开始绘图(手势识别的开始),当拆开再合并则为解除绘图(手势识别的结束),说白了就是用一个当前状态=!当前状态去做。

      本文的代码可以到这里下载:http://download.csdn.net/source/2313846

      下面贴出运动判断的核心代码:

  1. privatevoid videoSourcePlayer1_NewFrame( object sender, ref Bitmap image ) 
  2.     nowImg = (Bitmap)image.Clone(); 
  3.  
  4.     Bitmap objectImage = colorFilter.Apply( image ); 
  5.  
  6.     // lock image for further processing  
  7.     BitmapData objectData = objectImage.LockBits( new Rectangle( 0, 0, image.Width, image.Height ), 
  8.         ImageLockMode.ReadOnly, image.PixelFormat ); 
  9.  
  10.     // grayscaling  
  11.     UnmanagedImage grayImage = grayFilter.Apply( new UnmanagedImage( objectData ) ); 
  12.  
  13.     // unlock image  
  14.     objectImage.UnlockBits( objectData ); 
  15.  
  16.     // locate blobs   
  17.     blobCounter1.ProcessImage( grayImage ); 
  18.     List<Rectangle> rects = new List<Rectangle>(); 
  19.     rects.AddRange(blobCounter1.GetObjectsRectangles()); 
  20.  
  21.     if ( rects.Count >0 ) 
  22.     {
  23.         #region 去掉内部和黏在一起的对象  
  24.         for (int i = 0; i < rects.Count - 1; i++) 
  25.         { 
  26.             //true表示X轴上不能相交,false表示相交  
  27.             Boolean isNoTouchX = Math.Max(rects[i + 1].Right , rects[i].Right) - Math.Min(rects[i + 1].Left ,rects[i].Left) > (rects[i].Width + rects[i + 1].Width); 
  28.             //true表示Y轴上不能相交,false表示相交  
  29. Boolean isNoTouchY = Math.Max(rects[i + 1].Bottom, rects[i].Bottom) - Math.Min(rects[i + 1].Top, rects[i].Top) > (rects[i].Height + rects[i + 1].Height);
  30.             if (isNoTouchX == false && isNoTouchY == false)//如果两个对象相交  
  31.             { 
  32.                 Rectangle rect = new Rectangle(Math.Min(rects[i].Left, rects[i + 1].Left), 
  33.                     Math.Min(rects[i].Top, rects[i + 1].Top), 
  34.                     Math.Max(rects[i].Right, rects[i + 1].Right) - Math.Min(rects[i].Left, rects[i + 1].Left), 
  35.                     Math.Max(rects[i].Bottom, rects[i + 1].Bottom) - Math.Min(rects[i].Top, rects[i + 1].Top)); 
  36.                 rects.RemoveAt(i + 1); 
  37.                 rects.RemoveAt(i); 
  38.  
  39.                 rects.Add(rect); 
  40.                 i = 0; 
  41.             } 
  42.         }
  43.         #endregion
  44.         #region 画出表示点  
  45.         Rectangle objectRect = rects[0]; 
  46.  
  47.         int oldSize=oldRect.Width+oldRect.Height; 
  48.         int nowSize=rects[0].Width+rects[0].Height; 
  49.  
  50.         if (nowSize > (oldSize * 1.2))//如果突然变大,即两个指套合并  
  51.         { 
  52.             isCapture =!isCapture; 
  53.             clsHandWrite.Clear(); 
  54.         } 
  55.  
  56.         Graphics g = Graphics.FromImage(image); 
  57.  
  58.         if (isCapture)//如果捕捉到对象  
  59.         { 
  60.             Pen pen = new Pen(Color.FromArgb(255, 0, 0), 3); 
  61.             g.DrawRectangle(pen, objectRect); 
  62.             int x = (objectRect.Left + objectRect.Width / 2) * pbDraw.Width / videoSourcePlayer1.Width; 
  63.             int y = (objectRect.Top + objectRect.Height / 2) * pbDraw.Height / videoSourcePlayer1.Height; 
  64.                     clsHandWrite.Draw(x,y ); 
  65.         } 
  66.         else//如果没有捕捉到对象  
  67.         { 
  68.             Pen pen = new Pen(Color.FromArgb(160, 255, 160), 3); 
  69.             g.DrawRectangle(pen, objectRect); 
  70.         } 
  71.  
  72.         g.Dispose();
  73.    
  74.         #endregion  
  75.  
  76.         oldRect = rects[0]; 
  77.          
  78.     } 
  79.  
  80.     UpdateObjectPicture(objectImage ); 
  81.      
posted @ 2013-03-12 20:14  天地乐  阅读(599)  评论(0编辑  收藏  举报