本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
上次介绍了单点手势识别,这次就继续介绍一下如何实现多点手势识别,先来看看本文实现的效果图,图片有点大,请稍候。。。:
我预先让程序学习了B和C这两个字母,第一个对象通过点击鼠标左键去选择颜色(对象为绿色),第二个对象通过点击鼠标右键去选择颜色(对象为红色),然后通过两支手指的手势识别分别向程序绘画图形,所以点击recorgize时,就自动把图形的特征对应的字母给识别出来了。
本文上一篇文章的延伸,如图中所示,这里通过一个对象的消失/重现来识别是否开始绘图,当突然消失/重现则开始绘图,再次消失/重现则停止绘图。本文的代码可以到这里下载:http://download.csdn.net/source/2323958
接下来贴出本文的核心代码:
private void videoSourcePlayer1_NewFrame( object sender, ref Bitmap image ) { //保存捕获到的对象 List<Rectangle> []rects = new List<Rectangle>[2]; Bitmap[] objectImage = new Bitmap[2]; for (int i = 0; i < ObjectSum; i++)//捕获对象 { nowImg[i] = (Bitmap)image.Clone(); objectImage[i] = colorFilter[i].Apply(nowImg[i]); // lock image for further processing BitmapData objectData = objectImage[i].LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); // grayscaling UnmanagedImage grayImage = new GrayscaleBT709().Apply(new UnmanagedImage(objectData)); // unlock image objectImage[i].UnlockBits(objectData); // 从颜色中筛选有效的对象 blobCounter[i].ProcessImage(grayImage); rects[i] = new List<Rectangle>(); rects[i].AddRange(blobCounter[i].GetObjectsRectangles()); //如果当前对象i不存在,并且原有的对象i又是存在的,则表示是对象i隐藏起来了 if (rects[i].Count == 0 && oldRect[i].IsEmpty == false) { isCapture[i] = !isCapture[i];//改变为反模式 clsHandWrite[i].Clear(); } else if (rects[i].Count > 0)//如果当前对象i存在 { #region 去掉内部和黏在一起的对象 for (int ii = 0; ii < rects[i].Count - 1; ii++) { //true表示X轴上不能相交,false表示相交 Boolean isNoTouchX = Math.Max(rects[i][ii + 1].Right, rects[i][ii].Right) - Math.Min(rects[i][ii + 1].Left, rects[i][ii].Left) > (rects[i][ii].Width + rects[i][ii + 1].Width); //true表示Y轴上不能相交,false表示相交 Boolean isNoTouchY = Math.Max(rects[i][ii + 1].Bottom, rects[i][ii].Bottom) - Math.Min(rects[i][ii + 1].Top, rects[i][ii].Top) > (rects[i][ii].Height + rects[i][ii + 1].Height); if (isNoTouchX == false && isNoTouchY == false)//如果两个对象相交 { Rectangle rect = new Rectangle(Math.Min(rects[i][ii].Left, rects[i][ii + 1].Left), Math.Min(rects[i][ii].Top, rects[i][ii + 1].Top), Math.Max(rects[i][ii].Right, rects[i][ii + 1].Right) - Math.Min(rects[i][ii].Left, rects[i][ii + 1].Left), Math.Max(rects[i][ii].Bottom, rects[i][ii + 1].Bottom) - Math.Min(rects[i][ii].Top, rects[i][ii + 1].Top)); rects[i].RemoveAt(ii + 1); rects[i].RemoveAt(ii); rects[i].Add(rect); ii = 0; } } #endregion #region 画出表示点 Rectangle objectRect = rects[i][0];//只取得该对象第一个矩阵 Graphics g = Graphics.FromImage(image); if (isCapture[i])//如果捕捉到对象 { Pen pen = new Pen(Color.FromArgb(255, 255, 255), 3); g.DrawRectangle(pen, objectRect); int x = (objectRect.Left + objectRect.Width / 2) * pbDraw1.Width / videoSourcePlayer1.Width; int y = (objectRect.Top + objectRect.Height / 2) * pbDraw1.Height / videoSourcePlayer1.Height; clsHandWrite[i].Draw(x, y); } else//如果没有捕捉到对象 { Pen pen = new Pen(Color.FromArgb(160, 255, 160), 3); g.DrawRectangle(pen, objectRect); } g.Dispose(); oldRect[i] = new Rectangle();//初始化 oldRect[i] = rects[i][0]; #endregion } } Cls_Common.UpdateObjectPicture(ref pictureBox1, objectImage[0]);//显示过滤颜色的对象1 Cls_Common.UpdateObjectPicture(ref pictureBox2, objectImage[1]);//显示过滤颜色的对象2 } /// <summary> /// 选择绿色的物体为识别的对象 /// </summary> private void videoSourcePlayer1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left)//点击左键,识别绿色对象 Cls_Common.MarkGreen(nowImg[0], ref colorFilter[0], e.X, e.Y); else if (e.Button == MouseButtons.Right)//点击右键,识别红色对象 Cls_Common.MarkRed(nowImg[1], ref colorFilter[1], e.X, e.Y); }