Silverlight 4 中摄像头的运用—part1
将跟踪颜色视作输入 

好了,我们能够跟踪到这个颜色了,那这么做的意义是什么呢?实际上,我们可以根据它的位置来移动东西。接下来的例子中,创建的一个球会跟随这个颜色一起移动。你可以用来作出很诡异的对象跟随画面移动的效果。

关键代码:

===================================
//part2
Ellipse ball = new Ellipse();
CompositeTransform ballctf;
ball.Width = 20;
ball.Height = 20;
ball.Fill = new SolidColorBrush(Colors.Orange);
ballctf = new CompositeTransform();
ball.RenderTransform = ballctf;

labRes.Content = "捕获颜色=" + found.ToString();
            labPoint.Content = "坐标=" + _lastPoint.X.ToString() + "," + _lastPoint.Y.ToString();

ballctf.TranslateX = _lastPoint.X;
            ballctf.TranslateY = _lastPoint.Y;

Debug.WriteLine(found);
===================================

分析移动区域

在这一节,我们虽然还不去涉及如何跟踪物体的具体轨迹,但会知道如何判断是否有移动。  一个基本概念是:如果有移动,每帧的画面会明显不同。所以,如果发现两帧画面中位图的像素有不同的地方,就能知道发生了移动。

有两个潜在元素。第一,我们需要两张位图。第二,我们还需要一个比较函数。如果,你正在想着是否需要遍历所有像素来进行比较,那么我告诉你,这里有一个很实用的技巧:使用混合模式。绘制时如果不指定混合模式,新的像素值就会完全覆盖以取代存在的像素值。这也是我们至今为止一直在做的事情。如果使用混合模式,新的像素会影响已存在的像素,两张图片会以一种特别的方式混合在一起。而此刻,我们要用的混合模式叫做difference(差异),它对两张图片的红、绿、蓝三个通道的每个像素进行一次比较,然后给出它们之间的相减所得的差值。如果两个像素完全一致,那么结果就是0,也就是黑色,否则就是别的其它什么值(颜色)。这样,我们就把跟踪移动的问题简化了,只要寻找非黑色区域即可。 
===================================
public partial class MotionTracking : UserControl
    {
        CaptureSource _captureSource;
        VideoCaptureDevice _video;
        VideoBrush _videoBrush;
        Rectangle _rect;
        Image _wb_image;
        WriteableBitmap _wb = null;
        bool _isEnableCamera = false;

WriteableBitmap _newFrameBitmap;
        WriteableBitmap _oldFrameBitmap;

Image _newFrame;
        Image _oldFrame;

public MotionTracking()
        {
            InitializeComponent();

_captureSource = new CaptureSource();
            _video = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
            if (_video != null)
            {
                _video.DesiredFormat = _video.SupportedFormats[1];
                _captureSource.VideoCaptureDevice = _video;
                _videoBrush = new VideoBrush();
                _videoBrush.SetSource(_captureSource);
            }
            CompositionTarget.Rendering += new EventHandler(OnRender);

btnStart.Click += new RoutedEventHandler(btnStart_Click);

this.imageEffectsListBox.Items.Add(new NormalEffect());

this.imageEffectsListBox.Items.Add(new DarkenEffect());
            this.imageEffectsListBox.Items.Add(new MultiplyEffect());
            this.imageEffectsListBox.Items.Add(new ColorBurnEffect());
            this.imageEffectsListBox.Items.Add(new LinearBurnEffect());

this.imageEffectsListBox.Items.Add(new LightenEffect());
            this.imageEffectsListBox.Items.Add(new ScreenEffect());
            this.imageEffectsListBox.Items.Add(new ColorDodgeEffect());
            this.imageEffectsListBox.Items.Add(new LinearDodgeEffect());

this.imageEffectsListBox.Items.Add(new OverlayEffect());
            this.imageEffectsListBox.Items.Add(new SoftLightEffect());
            this.imageEffectsListBox.Items.Add(new HardLightEffect());
            this.imageEffectsListBox.Items.Add(new VividLightEffect());
            this.imageEffectsListBox.Items.Add(new LinearLightEffect());
            this.imageEffectsListBox.Items.Add(new PinLightEffect());

this.imageEffectsListBox.Items.Add(new DifferenceEffect());
            this.imageEffectsListBox.Items.Add(new ExclusionEffect());

this.imageEffectsListBox.Items.Add(new GlowEffect());
            this.imageEffectsListBox.Items.Add(new ReflectEffect());

this.imageEffectsListBox.Items.Add(new HardMixEffect());
            this.imageEffectsListBox.Items.Add(new NegationEffect());
            this.imageEffectsListBox.Items.Add(new PhoenixEffect());

this.imageEffectsListBox.Items.Add(new AverageEffect());

this.imageEffectsListBox.SelectedIndex = 0;
        }

void btnStart_Click(object sender, RoutedEventArgs e)
        {
            if (CaptureDeviceConfiguration.AllowedDeviceAccess ||
                CaptureDeviceConfiguration.RequestDeviceAccess())
            {
                _rect = new Rectangle();
                _rect.Width = 320;
                _rect.Height = 240;

_rect.Fill = _videoBrush;
                _rect.Visibility = Visibility.Collapsed;
                video_Canvas.Children.Add(_rect);

_newFrameBitmap = new WriteableBitmap(_rect, null);
                _oldFrameBitmap = new WriteableBitmap(_rect, null);

_newFrame = new Image();
                _newFrame.Width = 320;
                _newFrame.Height = 240;
                _newFrame.Source = _newFrameBitmap;
                _newFrame.Visibility = Visibility.Collapsed;

_oldFrame = new Image();
                _oldFrame.Width = 320;
                _oldFrame.Height = 240;
                _oldFrame.Source = _oldFrameBitmap;

video_Canvas.Children.Add(_oldFrame);
                video_Canvas.Children.Add(_newFrame);

_captureSource.Start();
                _isEnableCamera = true;

Thread thread = new Thread(new ThreadStart(ThreadProc));
                thread.Start();

}
        }

void OnRender(object sender, EventArgs e)
        {
            if (_isEnableCamera)
            {
                MatrixTransform transform = new MatrixTransform();
                transform.Matrix = new Matrix(-1, 0, 0, 1, 320, 0);
                
                _newFrameBitmap.Render(_rect, transform);
                _newFrameBitmap.Invalidate();
            }
        }

void ThreadProc()
        {
            while (true)
            {
                Thread.Sleep(20);

//Do the action in the UI thread
                Dispatcher.BeginInvoke(ThreadUpdate);
            }
        }

void ThreadUpdate()
        {
            if (_isEnableCamera)
            {
                _oldFrameBitmap.Render(_newFrame, null);
                _oldFrameBitmap.Invalidate();
            }
        }

private void imageEffectsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            BlendModeEffect effect = e.AddedItems[0] as BlendModeEffect;
            if (effect != null)
            {
                if (_oldFrameBitmap != null)
                {
                    ImageBrush _newImageBrush = new ImageBrush();
                    _newImageBrush.ImageSource = _newFrameBitmap;
                    ImageBrush _oldImageBrush = new ImageBrush();
                    _oldImageBrush.ImageSource = _oldFrameBitmap;

//effect.AInput = _oldImageBrush;
                    effect.BInput = _newImageBrush;
                    this._oldFrame.Effect = effect;
                }
            }
        }
    }

===================================

当运行刚启动,会出现一张纯黑色的矩形。但接着就会看到鬼一样移动的轮廓。这个轮廓就是两帧画面的不同之处。

接下来再使用threshold滤镜来对图片进行一下处理,对移动区域做更加精细的捕捉。

参考这里:http://kodierer.blogspot.com/2009/07/livin-on-edge-silverlight-parametric_4324.html

Silverlight中摄像头的运用—part2相关推荐

  1. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

  2. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地【附带实例源码】...

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

  3. Silverlight中使用CompositionInitializer宿主MEF

    MEF可以在传统应用程序中使用(包括桌面的Winform.控制台程序和Web的ASP.NET),也可以在RIA的Silverlight中使用.在Silverlight中只是宿主的方式有所不同,实际上在 ...

  4. Silverlight中的拖拽实现的图片上传---1

    在Silverlight中因为可以直接从系统的文件夹里面拖出来一个文件直接放到浏览器中,我在想使用这个功能来做成图片上传(或者文件上传),这样的用户体验将会是非常好的. 传统的上传都是打开对话框,选择 ...

  5. Silverlight中的ControlTemplate(2)

    Silverlight中的ControlTemplate介绍了ControlTemplate的相关的几个知识,这篇继续介绍剩余的内容 上文我们已经为Tooltip的ControlTemplate添加了 ...

  6. Silverlight实用窍门系列:47.Silverlight中元素到元素的绑定,以及ObservableCollection和List的使用区别...

    问题一:在某一些情况下,我们使用MVVM模式的时候,对于某一个字段(AgeField)需要在前台的很多个控件(A.B.C.D.E)进行绑定,但是如何能够让我们后台字段名改变的时候能够非常方便的改变所有 ...

  7. 在Silverlight中绘制贝塞尔曲线

    在Silverlight中绘制贝塞尔曲线 我以前的流程设计器使用的都是曲线,而且不能调扭曲,朋友们意见很大,后来我升级了设计器,这里贴出我实现扭曲的思路 代码下载: http://files.cnbl ...

  8. 一步一步学Silverlight 2系列(21):如何在Silverlight中调用JavaScript

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  9. 数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一)

    数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一) 步骤: 1. 创建SILVERLIGHT应用程序 2. 创建LINQ TO SQL [注意序列化的问题 ...

最新文章

  1. 服务器技术综述(四)
  2. 10061 mysql,Navicat无法连接到MySQL server的10061错误
  3. java中使用jxl导出Excel表格详细通用步骤
  4. api 定位 微信小程序 精度_一行代码区分微信小程序或QQ小程序
  5. 心学 禅宗_禅宗宣言,用于有效的代码审查
  6. Expected MultipartHttpServletRequest: is a MultipartResolver configured方案。
  7. MySQL 基础 ———— 存储过程与函数
  8. android 文件上传,中文utf-8编码
  9. 【LeetCode】剑指 Offer 14. 剪绳子
  10. c语言实现可变单链表,c语言实现单链表
  11. Redis学习总结(12)——Redis常见面试题再总结
  12. Linux系统安全基本措施及应用(关于账户安全以及sudo权限,安全认证等)
  13. matlab仿真三相变压器,三相变压器励磁涌流的MATLAB仿真与分析
  14. 【历史上的今天】12 月 23 日:Python 起源;TCP/IP 协议发明者出生;设计第一台 PC 的人诞生
  15. QT txt读写—论坛体编辑器
  16. OOC-GCC 特性介绍
  17. 如何在iPhone和iPad上使用Group FaceTime
  18. 【超级简单但超级有用】让PDF书籍变身为可搜索文件
  19. H323测试---安装GNUG服务器
  20. 部署nginx遇到的问题_重定向次数过多或者干脆找不到路径

热门文章

  1. 一个html5流星雨源码
  2. ps里面怎么插入流程图_学会这3个方法,5分钟能绘制出好看又高级的流程图
  3. python发邮件给女朋友代码_python实现邮件发送完整代码(带附件发送方式)
  4. linux进度条脚本,Linux下简易进度条的实现代码
  5. Iterator与ListIterator有什么区别
  6. 时下流行的9种恶意软件,你都了解吗?
  7. Jquery实用笔记
  8. 集群服务器分布式iis_Nginx+IIS分布式部署和负载均衡
  9. java 创建者设计模式_Java设计模式之创建者模式分享热爱编程,程序人生
  10. php留言板记录ip,如何用php程序记录来访IP