基於Aforge的手勢識別之二~~~單點手勢識別

2023-10-12 00:58

本文主要是介绍基於Aforge的手勢識別之二~~~單點手勢識別,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文來自http://blog.csdn.net/hellogv/ ,引用必須注明出處!

       本文把Aforge的運動識別與前面介紹的手寫識別融合在一起,實現單個手指的手勢識別。下圖演示了本文代碼運行的結果,圖片有點大,請稍候。。。

       我預先讓程序學習了B和C這兩個字母,然後通過手指的手勢識別向程序繪畫圖形,所以點擊recorgize時,就自動把圖形的特征對應的字母給識別出來了。

      這個例子關鍵部分在於如何靈活運用Aforge的運動識別,如何判斷是要畫圖,還是普通的移來移去呢?在這裡,我判斷移動對象的大小,當突然面積增大(即兩個指套合並)則開始繪圖(手勢識別的開始),當拆開再合並則為解除繪圖(手勢識別的結束),說白了就是用一個當前狀態=!當前狀態去做。

      本文的代碼可以到這裡下載:http://download.csdn.net/source/2313846

      下面貼出運動判斷的核心代碼:

[c-sharp]  view plain copy print ?
  1. private void videoSourcePlayer1_NewFrame( object sender, ref Bitmap image )  
  2. {  
  3.     nowImg = (Bitmap)image.Clone();  
  4.   
  5.     Bitmap objectImage = colorFilter.Apply( image );  
  6.   
  7.     // lock image for further processing  
  8.     BitmapData objectData = objectImage.LockBits( new Rectangle( 0, 0, image.Width, image.Height ),  
  9.         ImageLockMode.ReadOnly, image.PixelFormat );  
  10.   
  11.     // grayscaling  
  12.     UnmanagedImage grayImage = grayFilter.Apply( new UnmanagedImage( objectData ) );  
  13.   
  14.     // unlock image  
  15.     objectImage.UnlockBits( objectData );  
  16.   
  17.     // locate blobs   
  18.     blobCounter1.ProcessImage( grayImage );  
  19.     List<Rectangle> rects = new List<Rectangle>();  
  20.     rects.AddRange(blobCounter1.GetObjectsRectangles());  
  21.   
  22.     if ( rects.Count >0 )  
  23.     {  
  24.         #region 去掉內部和黏在一起的對象  
  25.         for (int i = 0; i < rects.Count - 1; i++)  
  26.         {  
  27.             //true表示X軸上不能相交,false表示相交  
  28.             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);  
  29.             //true表示Y軸上不能相交,false表示相交  
  30.             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);  
  31.             if (isNoTouchX == false && isNoTouchY == false)//如果兩個對象相交  
  32.             {  
  33.                 Rectangle rect = new Rectangle(Math.Min(rects[i].Left, rects[i + 1].Left),  
  34.                     Math.Min(rects[i].Top, rects[i + 1].Top),  
  35.                     Math.Max(rects[i].Right, rects[i + 1].Right) - Math.Min(rects[i].Left, rects[i + 1].Left),  
  36.                     Math.Max(rects[i].Bottom, rects[i + 1].Bottom) - Math.Min(rects[i].Top, rects[i + 1].Top));  
  37.                 rects.RemoveAt(i + 1);  
  38.                 rects.RemoveAt(i);  
  39.   
  40.                 rects.Add(rect);  
  41.                 i = 0;  
  42.             }  
  43.         }  
  44.         #endregion  
  45.  
  46.         #region 畫出表示點  
  47.         Rectangle objectRect = rects[0];  
  48.   
  49.         int oldSize=oldRect.Width+oldRect.Height;  
  50.         int nowSize=rects[0].Width+rects[0].Height;  
  51.   
  52.         if (nowSize > (oldSize * 1.2))//如果突然變大,即兩個指套合並  
  53.         {  
  54.             isCapture =!isCapture;  
  55.             clsHandWrite.Clear();  
  56.         }  
  57.   
  58.         Graphics g = Graphics.FromImage(image);  
  59.   
  60.         if (isCapture)//如果捕捉到對象  
  61.         {  
  62.             Pen pen = new Pen(Color.FromArgb(255, 0, 0), 3);  
  63.             g.DrawRectangle(pen, objectRect);  
  64.             int x = (objectRect.Left + objectRect.Width / 2) * pbDraw.Width / videoSourcePlayer1.Width;  
  65.             int y = (objectRect.Top + objectRect.Height / 2) * pbDraw.Height / videoSourcePlayer1.Height;  
  66.                     clsHandWrite.Draw(x,y );  
  67.         }  
  68.         else//如果沒有捕捉到對象  
  69.         {  
  70.             Pen pen = new Pen(Color.FromArgb(160, 255, 160), 3);  
  71.             g.DrawRectangle(pen, objectRect);  
  72.         }  
  73.   
  74.         g.Dispose();  
  75.      
  76.         #endregion  
  77.   
  78.         oldRect = rects[0];  
  79.           
  80.     }  
  81.   
  82.     UpdateObjectPicture(objectImage );  
  83.       
  84. }  

这篇关于基於Aforge的手勢識別之二~~~單點手勢識別的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/192094

相关文章

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

Pr 入门系列之二:导入与管理素材(下)

◆  ◆  ◆ 管理素材 导入素材后,项目面板中每一个媒体都只是原始素材的“链接”。 所以,视频编辑过程中一般情况下都不会破坏原始素材。 1、在不同视图模式下组织素材 项目面板提供了三大视图 View供选用:列表视图、图标视图以及自由格式视图。 A. 锁定 B. 列表视图 C. 图标视图 D. 自由格式视图 E. 缩放滑块 F. 排序图标 G. 自动匹配序列 H. 查找 I. 新建素材箱 J.

使用YOLOv10训练自定义数据集之二(数据集准备)

0x00 前言 经过上一篇环境部署的介绍【传送门】,我们已经得到了一个基本可用的YOLOv10的运行环境,还需要我们再准备一些数据,用于模型训练。 0x01 准备数据集 1. 图像标注工具 数据集是训练模型基础素材。 对于小白来说,一般推荐从一些开放网站中下载直接使用,官方推荐了一个名为Roboflow的数据集网站。Roboflow是一个免费开源数据集管理平台,它不仅提供免费的数据集,还

UICollectionView 的研究之二 :自定义 UICollectionViewFlowLayout

UICollectionView 实现各式复杂布局核心在于 UICollectionViewLayout,需要我们去自定义实现。 通过各种layout 的自定义实现,以及它们之间的切换。可以实现一些酷炫的布局,例如 (图片选自:http://www.cnblogs.com/markstray/p/5822262.html) Cover Flow 布局 堆叠布局 圆形布局

Pr 入门系列之二:导入与管理素材(上)

导入和管理素材是视频编辑流程中的关键步骤。正确导入素材确保项目中的媒体文件兼容性和稳定性,而有效管理素材则提高编辑效率,帮助你有序组织和快速访问所需资源,避免混乱和错误。 ◆  ◆  ◆ 新建项目 项目文件(.prproj)保存着视频工作流程中的所有信息。 Pr菜单:文件/新建/项目 Project 快捷键:Ctrl + Alt + N 导入页面 如上图所示,可以不选择任何素材,直接点击“创建

RedisStack十部曲之二:Redis的核心概念

文章目录 键空间修改和查询键键过期遍历键空间 客户端缓存在计算机科学中有两个难题客户端缓存的Redis实现跟踪模式的工作机制统一的键命名空间 两种连接方式缓存策略Opt-in 模式Opt-out 模式广播模式NOLOOP选项避免竟态条件当与服务器失去连接怎么办什么值得缓存 流水线请求/响应协议和往返时间(RTT)Redis管道这不仅仅是RTT的问题流水线VS脚本为什么在一台机器上进行死循环

C++笔记15•数据结构:二叉树之二叉搜索树•

二叉搜索树 1.二叉搜索树 概念: 二叉搜索树又称二叉排序树也叫二叉查找树,它可以是一棵空树。 二叉树具有以下性质: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树; 2.二叉搜索树功能 1. 二叉搜索树的查找 a 、从根开始比

【Canvas与诗词】录王昌龄诗《出塞之二》匣里金刀血未干

【成图】 【代码】 <!DOCTYPE html><html lang="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><head><title>匣里金刀血未干</title><style type="text/css">.centerlize{margin:0 auto;

selenium 自动化之二(1)----元素定位特殊操作复选框

针对一些相对单存定位的元素,会有个别的元素定位情况及一些元素的相关操作 checkbox的元素定位及选项,该元素属于单选或者复选等场景,那我们就需要全选或者单选或者多选 #通过xpath及css 方式定位法先找出元素checkboxs=driver.find_elements_by_xpath("//input[@type='checkbox']")checkboxs=dri

14、java 面向对象之一:面向过程与面向对象区别、对象的创建与使用、类的成员之一(属性)、类的属性之二(方法)等详解

java 面向对象之一: Ⅰ、面向过程与面向对象的区别:1、面向过程与面向对象描述:2、面向对象的两个要素:类与对象 Ⅱ、对象的创建与使用:1、面向对象思想:对象的创建与使用其一、描述:其二、代码为:其三、截图为: Ⅲ、类的成员:1、类中方法的声明和使用:其一、描述:其二、代码为:其三、截图为: 2、同类不同对象间的关系:独立堆空间其一、描述:其二、代码为:A、Person.java 与