在线搭建网站,自助建站 平台,html网页跳转代码,西安电商平台网站Silverlight 4 中摄像头的运用—part1将跟踪颜色视作输入 好了#xff0c;我们能够跟踪到这个颜色了#xff0c;那这么做的意义是什么呢#xff1f;实际上#xff0c;我们可以根据它的位置来移动东西。接下来的例子中#xff0c;创建的一个球会跟随这个颜色一起移动。你可…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