您的位置:首页 > 其它

基于Aforge的手势识别之二~~~单点手势识别

2010-05-04 13:46 716 查看
本文来自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 );
            
        }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: