本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
上一篇文章介绍了如何用Aforge去捕捉运动物体,现在就介绍一个更深入的操作----手势识别。
我实现手势识别的原理很简单:捕捉运动物体+手写识别,把运动的物体的轨迹记录下来,然后通过手写识别引擎去搜索数据中最匹配的数据,从而知道“写”的是什么。目前常见的开源手写识别引擎有zinnia,wagomu 这些,不过小弟我比较业余,只把网上的比较常见的手写识别代码改进一下,只能识别字母和数字,真想通过摄像头隔空“手写”的朋友就要多花时间玩玩上面提到的几个开源手写类库了。
本文介绍的手写识别:先在一个固定大小的画板上,用鼠标画下某图形,输入该图形对应的字母,程序把画板上的字母特征点都保存下来特征数据库(相当于学习记忆),然后再在画板上画出类似该字母的图形,程序就通过新画的特征点搜索特征数据库从而找出最类似的字母。
接下来贴出核心代码,详细的代码请到这里下载:http://download.csdn.net/source/2312865
GetBMPContext()是把画板中的图形的特征分析出来,Learn()是把特征与特定的字母/数字对应起来保存到数据库,Recognise()是把当前画板的图形特征从数据库中搜索,从而找出对应的字母/数字。
const int SCAN_GAP = 10; private String GetBMPContext(Bitmap bmp) { Boolean bool1stScan = true; int ax = 0, ay = 0, bx = 0, by = 0; String result = ""; for (int i = 1; i < bmp.Width; i = i + SCAN_GAP) { for (int j = 1; j < bmp.Height; j = j + SCAN_GAP) { if (bmp.GetPixel(i, j).ToArgb() == Color.Black.ToArgb()) { if (bool1stScan == false) { if (i <= ax) ax = i; if (i >= bx) bx = i; if (j <= ay) ay = j; if (j >= by) by = j; } else { bool1stScan = false; ax = i; bx = i; ay = j; by = j; } } } } Bitmap bmp2 = new Bitmap(20, 20); Graphics g2 = Graphics.FromImage((Image)bmp2); g2.Clear(Color.White); g2.DrawImage(bmp, new Rectangle(0, 0, bmp2.Width, bmp2.Height), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel); g2.Dispose(); // pictureBox1.Image = bmp2; int a = 0, b = 0; for (int i = 0; i < bmp2.Width; i++) { for (int j = 0; j < bmp2.Height; j++) { if (bmp2.GetPixel(i, j).ToArgb() == Color.Black.ToArgb()) result = result + "0"; else result = result + "1"; } } return result; } public void Learn(String name) { StreamWriter sw = new StreamWriter(fileName, true); sw.WriteLine(name + " " + GetBMPContext(bmpDraw)); sw.Close(); } public String Recognise() { String current = GetBMPContext(bmpDraw); StreamReader sr = new StreamReader(fileName); int max = 0; String result = ""; while (sr.EndOfStream == false) { String[] key = sr.ReadLine().Split(' '); String name = key[0]; String data = key[1]; int match = 0; for (int i = 0; i < current.Length; i++) { if (current[i] == data[i]) match++; } if (match >= max) { result = name; max = match; } //Trace.WriteLine(result + ":" + match + "," + max); } sr.Close(); return result; }