本文來自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);
- }