未来游戏新趋势——野比的视频体感游戏实验《抓住板砖》

未来游戏新趋势——野比的视频体感游戏实验《抓住板砖》_第1张图片

作者:野比 ([email protected]

时间:May, 2012

封面图片为野比原创,请勿未经允许私自引用


Nobi's Somatosensory Game -- Catch the Brick

野比的体感游戏 —— 抓住板砖

写在前面的话:这纯粹是个实验小品,妄称游戏,娱乐而已,不要当真。做这个东西的原因,其一在于对体感游戏的兴趣,其二也是为了练习使用Emgu CV。希望通过这篇文章,抛砖引玉,能够激发出大家创造的激情。希望能有更多更好的关于体感控制方面的精品出现! 


====>源代码下载<==== 


要使用源代码,请先安装Emgu CV(请找度娘索取),并且把bin目录添加到系统变量中。如果不行或者不会,就把bin下面的所有dll文件复制到C:\Windows\system32里去。

源代码里面有一个BitmapEx,是增强的System.Drawing.Bitmap,用到指针来进行GetPixel()和SetPixel(),性能比Bitmap好不少。

BitmapEx的代码如下。

[csharp]  view plain copy print ?
  1. /********************************************** 
  2.  * Extended Bitmap Class 
  3.  * 增强型位图类 
  4.  * -------------------------------------------- 
  5.  * 野比春熊 
  6.  * [email protected] 
  7.  * May 13th, 2012 Mother's Day 
  8.  * -------------------------------------------- 
  9.  * You MAY ABLE TO USE, DUPLICATE this program. 
  10.  * But you MAY NOT MODIFY it WITHOUT my per- 
  11.  * mission. 
  12.  * (Ha ha, just a joke. You got this file, you 
  13.  * got everything already.) 
  14.  * Use as you wish. You can donate to me if 
  15.  * you feel grateful. 
  16.  * *******************************************/  
  17. using System;  
  18. using System.Collections.Generic;  
  19. using System.Text;  
  20. using System.Drawing.Imaging;  
  21. using System.Drawing;  
  22.   
  23. namespace SpringbearWorks.Image  
  24. {  
  25.     /// <summary>  
  26.     /// 增强位图类。  
  27.     /// </summary>  
  28.     /// <remarks>  
  29.     /// 高性能 Bitmap 类。  
  30.     /// </remarks>  
  31.     public class BitmapEx : IDisposable, ICloneable  
  32.     {  
  33.         #region 字段  
  34.         internal Bitmap _bitmap;  
  35.         BitmapData _bitmapData;  
  36.         #endregion  
  37.  
  38.         #region 构造与析构  
  39.         private BitmapEx() { }  
  40.   
  41.         public BitmapEx(int width, int height, PixelFormat format)  
  42.         {  
  43.             _bitmap = new Bitmap(width, height, format);  
  44.         }  
  45.   
  46.         ~BitmapEx()  
  47.         {  
  48.             Dispose(false);  
  49.         }  
  50.   
  51.         public void Dispose()  
  52.         {  
  53.             GC.SuppressFinalize(this);  
  54.             Dispose(true);  
  55.         }  
  56.   
  57.         protected virtual void Dispose(bool disposing)  
  58.         {  
  59.             Unlock();  
  60.             if (disposing)  
  61.             {  
  62.                 _bitmap.Dispose();  
  63.             }  
  64.         }  
  65.         #endregion  
  66.  
  67.         #region 方法  
  68.         public object Clone()  
  69.         {  
  70.             BitmapEx clone = new BitmapEx();  
  71.             clone._bitmap = (Bitmap)_bitmap.Clone();  
  72.             return clone;  
  73.         }  
  74.   
  75.         public int Width  
  76.         {  
  77.             get { return _bitmap.Width; }  
  78.         }  
  79.   
  80.         public int Height  
  81.         {  
  82.             get { return _bitmap.Height; }  
  83.         }  
  84.   
  85.         public void Lock()  
  86.         {  
  87.             _bitmapData = _bitmap.LockBits(  
  88.                 new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),  
  89.                 ImageLockMode.ReadWrite,  
  90.                 _bitmap.PixelFormat  
  91.                 );  
  92.         }  
  93.   
  94.         unsafe public Color GetPixel(int x, int y)  
  95.         {  
  96.             if (_bitmapData.PixelFormat == PixelFormat.Format32bppArgb)  
  97.             {  
  98.                 byte* b = (byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 4);  
  99.                 return Color.FromArgb(*(b + 3), *(b + 2), *(b + 1), *b);  
  100.             }  
  101.             if (_bitmapData.PixelFormat == PixelFormat.Format24bppRgb)  
  102.             {  
  103.                 byte* b = (byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 3);  
  104.                 return Color.FromArgb(*(b + 2), *(b + 1), *b);  
  105.             }  
  106.             return Color.Empty;  
  107.         }  
  108.   
  109.         unsafe public void SetPixel(int x, int y, Color c)  
  110.         {  
  111.             if (_bitmapData.PixelFormat == PixelFormat.Format32bppArgb)  
  112.             {  
  113.                 byte* b = (byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 4);  
  114.                 *b = c.B;  
  115.                 *(b + 1) = c.G;  
  116.                 *(b + 2) = c.R;  
  117.                 *(b + 3) = c.A;  
  118.             }  
  119.             if (_bitmapData.PixelFormat == PixelFormat.Format24bppRgb)  
  120.             {  
  121.                 byte* b = (byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 3);  
  122.                 *b = c.B;  
  123.                 *(b + 1) = c.G;  
  124.                 *(b + 2) = c.R;  
  125.             }  
  126.         }  
  127.   
  128.         public Byte GetIntensity(int x, int y)  
  129.         {  
  130.             Color c = GetPixel(x, y);  
  131.             return (byte)((c.R * 0.30 + c.G * 0.59 + c.B * 0.11) + 0.5);  
  132.         }  
  133.   
  134.         public void Unlock()  
  135.         {  
  136.             if (_bitmapData != null)  
  137.             {  
  138.                 _bitmap.UnlockBits(_bitmapData);  
  139.                 _bitmapData = null;  
  140.             }  
  141.         }  
  142.   
  143.         public void Save(string filename, ImageFormat format)  
  144.         {  
  145.             _bitmap.Save(filename, format);  
  146.         }  
  147.   
  148.         public void Save(string filename)  
  149.         {  
  150.             _bitmap.Save(filename);  
  151.         }  
  152.         #endregion  
  153.     }  
  154. }  

在项目中添加现有项,把Form1.cs和Form1.Designer.cs一起加入,使其为启动的主窗体,即可开始调试本程序。

游戏原理很简单,就这这几个步骤。

  1. 对背景采样(注意不能有运动物体)
  2. 从视频里减去背景(剩下的就是伟岸的你了)
  3. 二值化剪影
  4. 读取板砖范围内的像素点,和剪影交叉超过20%则认为被点击
  5. 5.如此这般

上面第4步,按照我设想的其实应该分成a.查找剪影边界,生成Region,b.求板砖和Region的交集,若不为空,则认为相交。现在这种算法效率太低。

实际操作时发现AForge的边缘检测算法似乎对我电脑上130w的摄像头有点勉为其难,效果相当不好。

无所谓了,反正是玩嘛。于是就用遮罩+XOR提取了运动图像部分(人)。

游戏攻略:

  1. 使用身体任何一个部分去碰触红色板砖即可。
  2. 永远不要妄想能抓住板砖。

下面来个游戏动画图。

未来游戏新趋势——野比的视频体感游戏实验《抓住板砖》_第2张图片

 

未来游戏新趋势——野比的视频体感游戏实验《抓住板砖》_第3张图片

 

未来游戏新趋势——野比的视频体感游戏实验《抓住板砖》_第4张图片



欢迎指正! 

关于体感游戏的一些思考

体感游戏,从Wii打响第一枪开始至今已经很多年了。NDS的吹气玩法,Microsoft的Kinect等等,无不在提醒着我们,体感控制,正在日趋完善。

前段时间看到一个科技视频,美国科学家使用布置在房间、手持的多个摄像机、投影仪同步,然后实时生成房间、物品和人的3D数据模型,实现了人体体感控制任意虚拟物品的科幻效果。 


视频链接:点击访问


作者:野比 ([email protected]

时间:May, 2012

(全文完)

你可能感兴趣的:(游戏,算法,windows,Microsoft,null,byte)