本文來自http://blog.csdn.net/hellogv/ ,引用必須注明出處!
本文把Aforge的運動識別與前面介紹的手寫識別融合在一起,實現單個手指的手勢識別。下圖演示了本文代碼運行的結果,圖片有點大,請稍候。。。
我預先讓程序學習了B和C這兩個字母,然後通過手指的手勢識別向程序繪畫圖形,所以點擊recorgize時,就自動把圖形的特征對應的字母給識別出來了。
這個例子關鍵部分在於如何靈活運用Aforge的運動識別,如何判斷是要畫圖,還是普通的移來移去呢?在這裡,我判斷移動對象的大小,當突然面積增大(即兩個指套合並)則開始繪圖(手勢識別的開始),當拆開再合並則為解除繪圖(手勢識別的結束),說白了就是用一個當前狀態=!當前狀態去做。
本文的代碼可以到這裡下載:http://download.csdn.net/source/2313846
下面貼出運動判斷的核心代碼:
- private void videoSourcePlayer1_NewFrame( object sender, ref Bitmap image )
- {
- nowImg = (Bitmap)image.Clone();
- Bitmap objectImage = colorFilter.Apply( image );
- // lock image for further processing
- BitmapData objectData = objectImage.LockBits( new Rectangle( 0, 0, image.Width, image.Height ),
- ImageLockMode.ReadOnly, image.PixelFormat );
- // grayscaling
- UnmanagedImage grayImage = grayFilter.Apply( new UnmanagedImage( objectData ) );
- // unlock image
- objectImage.UnlockBits( objectData );
- // locate blobs
- blobCounter1.ProcessImage( grayImage );
- List<Rectangle> rects = new List<Rectangle>();
- rects.AddRange(blobCounter1.GetObjectsRectangles());
- if ( rects.Count >0 )
- {
- #region 去掉內部和黏在一起的對象
- for (int i = 0; i < rects.Count - 1; i++)
- {
- //true表示X軸上不能相交,false表示相交
- 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);
- //true表示Y軸上不能相交,false表示相交
- 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);
- if (isNoTouchX == false && isNoTouchY == false)//如果兩個對象相交
- {
- Rectangle rect = new Rectangle(Math.Min(rects[i].Left, rects[i + 1].Left),
- Math.Min(rects[i].Top, rects[i + 1].Top),
- Math.Max(rects[i].Right, rects[i + 1].Right) - Math.Min(rects[i].Left, rects[i + 1].Left),
- Math.Max(rects[i].Bottom, rects[i + 1].Bottom) - Math.Min(rects[i].Top, rects[i + 1].Top));
- rects.RemoveAt(i + 1);
- rects.RemoveAt(i);
- rects.Add(rect);
- i = 0;
- }
- }
- #endregion
- #region 畫出表示點
- Rectangle objectRect = rects[0];
- int oldSize=oldRect.Width+oldRect.Height;
- int nowSize=rects[0].Width+rects[0].Height;
- if (nowSize > (oldSize * 1.2))//如果突然變大,即兩個指套合並
- {
- isCapture =!isCapture;
- clsHandWrite.Clear();
- }
- Graphics g = Graphics.FromImage(image);
- if (isCapture)//如果捕捉到對象
- {
- Pen pen = new Pen(Color.FromArgb(255, 0, 0), 3);
- g.DrawRectangle(pen, objectRect);
- int x = (objectRect.Left + objectRect.Width / 2) * pbDraw.Width / videoSourcePlayer1.Width;
- int y = (objectRect.Top + objectRect.Height / 2) * pbDraw.Height / videoSourcePlayer1.Height;
- clsHandWrite.Draw(x,y );
- }
- else//如果沒有捕捉到對象
- {
- Pen pen = new Pen(Color.FromArgb(160, 255, 160), 3);
- g.DrawRectangle(pen, objectRect);
- }
- g.Dispose();
- #endregion
- oldRect = rects[0];
- }
- UpdateObjectPicture(objectImage );
- }