예제 #1
0
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            captureSource = new CaptureSource
            {
                VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice()
            };

            var videoBrush = new VideoBrush();

            videoBrush.SetSource(captureSource);
            Viewport.Fill = videoBrush;

            markerDetector = new CaptureSourceMarkerDetector();
            var marker = Marker.LoadFromResource("Bola.pat", 64, 64, 80);

            markerDetector.Initialize(captureSource, 1d, 4000d, marker);

            markerDetector.MarkersDetected += (obj, args) =>
            {
                Dispatcher.BeginInvoke(() =>
                {
                    var results = args.DetectionResults;
                    if (results.HasResults)
                    {
                        var centerAtOrigin =
                            Matrix3DFactory.
                            CreateTranslation(
                                -Imagem.ActualWidth *
                                0.5,
                                -Imagem.
                                ActualHeight *
                                0.5, 0);
                        var scale =
                            Matrix3DFactory.CreateScale
                                (0.5, -0.5, 0.5);
                        var world = centerAtOrigin *
                                    scale *
                                    results[0].
                                    Transformation;
                        var vp =
                            Matrix3DFactory.
                            CreateViewportTransformation
                                (Viewport.ActualWidth,
                                Viewport.ActualHeight);
                        var m =
                            Matrix3DFactory.
                            CreateViewportProjection
                                (world,
                                Matrix3D.Identity,
                                markerDetector.
                                Projection, vp);
                        Imagem.Projection =
                            new Matrix3DProjection
                        {
                            ProjectionMatrix = m
                        };
                    }
                });
            };
        }
예제 #2
0
        private void Transform(AstroObject astroObject, Matrix3D baseTransformation, FrameworkElement txt)
        {
            // Transform Model
            if (astroObject == null)
            {
                return;
            }
            var m = Matrix.Identity;

            m *= Matrix.CreateTranslation(0, 60, 0);
            m *= Matrix.CreateRotationX(Microsoft.Xna.Framework.MathHelper.ToRadians(90));
            m *= baseTransformation.ToXnaMatrix();
            astroObject.Transform = m;
            astroObject.IsVisible = true;

            // Transform FrameworkElement
            // Center at origin of the TextBlock
            var centerAtOrigin = Matrix3DFactory.CreateTranslation(-txt.ActualWidth * 0.5, -txt.ActualHeight * 0.5, 0);
            // Swap the y-axis
            var scale = Matrix3DFactory.CreateScale(1, -1, 1);
            // Move a bit away from the center
            var translation = Matrix3DFactory.CreateTranslation(0, 50, 0);
            // Calculate the complete transformation matrix based on the first detection result
            var world = centerAtOrigin * translation * scale * baseTransformation;

            // Calculate the final transformation matrix by using the camera projection matrix
            var vp = Matrix3DFactory.CreateViewportTransformation(Viewport.ActualWidth, Viewport.ActualHeight);
            var mp = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, arDetector.Projection, vp);

            // Apply the final transformation matrix to the TextBox
            txt.Projection = new Matrix3DProjection {
                ProjectionMatrix = mp
            };
            txt.Visibility = Visibility.Visible;
        }
예제 #3
0
        private async Task InitializeDetector()
        {
            //  Initialize the Detector
            arDetector = new CaptureSourceMarkerDetector();

            // Load the marker pattern. It has 16x16 segments and a width of 80 millimeters
            var marker = await Marker.LoadFromResource("ms-appx:///Marker_SLAR_16x16segments_80width.pat", 16, 16, 80);

            // The perspective projection has the near plane at 1 and the far plane at 4000
            await arDetector.Initialize(1, 4000, new List <Marker> {
                marker
            },
                                        Windows.Devices.Enumeration.Panel.Back,
                                        640,
                                        480,
                                        30,
                                        adaptive.IsChecked.Value);

            // Attach the AR detection event handler
            // The event is fired if at least one marker was detected
            arDetector.MarkersDetected += async(s, me) =>
            {
                // Change to UI thread in order to manipulate the text control's projection
                await Dispatcher.RunAsync(
                    CoreDispatcherPriority.Normal,
                    () =>
                {
                    WriteableBitmap bm = new WriteableBitmap(640, 480);
                    me.Buffer.AsBuffer().CopyTo(bm.PixelBuffer);
                    Viewport.Source = bm;
                    // Calculate the projection matrix
                    var dr = me.DetectionResults;
                    if (dr.HasResults)
                    {
                        // Center at origin of the TextBlock
                        var centerAtOrigin = Matrix3DFactory.CreateTranslation(-Txt.ActualWidth * 0.5, -Txt.ActualHeight * 0.5, 0);
                        // Swap the y-axis and scale down by half
                        var scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5);
                        // Calculate the complete transformation matrix based on the first detection result
                        var world = centerAtOrigin *scale *dr[0].Transformation;

                        // Calculate the final transformation matrix by using the camera projection matrix
                        var vp = Matrix3DFactory.CreateViewportTransformation(Viewport.ActualWidth, Viewport.ActualHeight);
                        var m  = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, arDetector.Projection, vp);

                        // Apply the final transformation matrix to the TextBox
                        Txt.Projection = new Matrix3DProjection {
                            ProjectionMatrix = m
                        };
                    }
                });
            };
        }
예제 #4
0
 private void RunUpdate()
 {
     doAR = false;
     CompositionTarget.Rendering += (s, ea) =>
     {
         if (!doAR)
         {
             // Rotate other AR object
             var trans = Matrix3DFactory.CreateRotationZ(timedRotation);
             trans = trans * Matrix3DFactory.CreateTranslation(0, 0, -400);
             ApplyTransformation(ImgLogo, trans);
         }
         timedRotation += 0.01f;
     };
 }
예제 #5
0
        private void Initialize()
        {
            try
            {
                // Init variables
                timedRotation = 0;
                Scale         = 0.4;
                Rotate        = 0;

                // Init capture source
                captureSource = new CaptureSource();
                captureSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                // Desired format is 320 x 240 (good tracking results and performance)
                captureSource.VideoCaptureDevice.DesiredFormat = new VideoFormat(PixelFormatType.Unknown, 320, 240, 30);

                // Init AR
                markerSlar = Marker.LoadFromResource("data/Marker_SLAR_16x16segments_80width.pat", 16, 16, 80.0, "SLAR");
                markerL    = Marker.LoadFromResource("data/Marker_L_16x16segments_80width.pat", 16, 16, 80.0, "L");
                ArDetector = new CaptureSourceMarkerDetector(captureSource, 1, 4000, new List <Marker> {
                    markerSlar, markerL
                });
                AttachAREvent();

                // Init Rest
                projectionMatrix = Matrix3DFactory.CreatePerspectiveFieldOfViewRH(0.7, ViewportContainer.Width / ViewportContainer.Height, 1, 4000);
                this.DataContext = this;

                // Start all
                SetARObject();
                RunUpdate();
            }
            catch (Exception ex)
            {
                var builder = new StringBuilder();
                foreach (var sf in captureSource.VideoCaptureDevice.SupportedFormats)
                {
                    builder.AppendFormat("{0}: {1} x {2} @ {3} fps. Stride: {4}\r\n", sf.PixelFormat, sf.PixelWidth, sf.PixelHeight, sf.FramesPerSecond, sf.Stride);
                }
                MessageBox.Show("Error during initialization. Please make sure a default webcam was set.\r\nSupported formats:\r\n" + builder.ToString() + "\r\n\r\n" + ex.ToString(), "Error during init.", MessageBoxButton.OK);
                throw;
            }
        }
예제 #6
0
        private void InitializeDetector()
        {
            //  Initialize the Detector
            arDetector = new CaptureSourceMarkerDetector();

            // Load the marker pattern. It has 16x16 segments and a width of 80 millimeters
            var marker = Marker.LoadFromResource("Marker_SLAR_16x16segments_80width.pat", 16, 16, 80);

            // The perspective projection has the near plane at 1 and the far plane at 4000
            arDetector.Initialize(captureSource, 1, 4000, new List <Marker> {
                marker
            }, adaptive.IsChecked.Value);

            // Attach the AR detection event handler
            // The event is fired if at least one marker was detected
            arDetector.MarkersDetected += (s, me) =>
            {
                // Change to UI thread in order to manipulate the text control's projection
                Dispatcher.BeginInvoke(() =>
                {
                    // Calculate the projection matrix
                    var dr = me.DetectionResults;
                    if (dr.HasResults)
                    {
                        // Center at origin of the TextBlock
                        var centerAtOrigin = Matrix3DFactory.CreateTranslation(-Txt.ActualWidth * 0.5, -Txt.ActualHeight * 0.5, 0);
                        // Swap the y-axis and scale down by half
                        var scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5);
                        // Calculate the complete transformation matrix based on the first detection result
                        var world = centerAtOrigin * scale * dr[0].Transformation;

                        // Calculate the final transformation matrix by using the camera projection matrix
                        var vp = Matrix3DFactory.CreateViewportTransformation(Viewport.ActualWidth, Viewport.ActualHeight);
                        var m  = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, arDetector.Projection, vp);

                        // Apply the final transformation matrix to the TextBox
                        Txt.Projection = new Matrix3DProjection {
                            ProjectionMatrix = m
                        };
                    }
                });
            };
        }
예제 #7
0
        private void ApplyTransformation(FrameworkElement element, Matrix3D baseTransformation)
        {
            // Create additional transformations
            var centerImageAtOrigin = Matrix3DFactory.CreateTranslation(-element.ActualWidth * 0.5, -element.ActualHeight * 0.5, 0);
            var invertYAxis         = Matrix3DFactory.CreateScale(1, -1, 1);
            var viewport            = Matrix3DFactory.CreateViewportTransformation(ViewportContainer.ActualWidth, ViewportContainer.ActualHeight);
            var rotate = Matrix3DFactory.CreateRotationZ(MathHelper.ToRadians(Rotate));
            var scale  = Matrix3DFactory.CreateScale(Scale);

            // Compose transform
            var m = Matrix3D.Identity;

            m = m * centerImageAtOrigin;
            m = m * invertYAxis;
            m = m * rotate;
            m = m * scale;
            m = m * baseTransformation;
            m = Matrix3DFactory.CreateViewportProjection(m, Matrix3D.Identity, projectionMatrix, viewport);

            // Apply transform
            element.Projection = new Matrix3DProjection {
                ProjectionMatrix = m
            };
        }
예제 #8
0
        void Update()
        {
            if (_arWrapper != null && _isRunning)
            {
                // Update
                if (_arWrapper.arwCapture())
                {
                    // We need to change the threshold and debug mode here, otherwise a concurrent op can happen and UpdateAr will crash
                    if (_arWrapperViewModel != null)
                    {
                        if (_arWrapper.arwGetVideoThresholdMode() != _arWrapperViewModel.SelectedThresholdMode.Mode)
                        {
                            _arWrapper.arwSetVideoThresholdMode(_arWrapperViewModel.SelectedThresholdMode.Mode);
                        }
                        if (_arWrapper.arwGetVideoDebugMode() != _arWrapperViewModel.UseDebugMode)
                        {
                            _arWrapper.arwSetVideoDebugMode(_arWrapperViewModel.UseDebugMode);
                        }
                    }

                    // Update
                    _arWrapper.arwUpdateAR();

                    if (!_wasStarted)
                    {
                        // Get video params
                        int    width, height, pixelSize;
                        string pixelFormat;
                        if (!_arWrapper.arwGetVideoParams(out width, out height, out pixelSize, out pixelFormat))
                        {
                            throw new InvalidOperationException("ARToolkit arwGetVideoParams failed.");
                        }
                        Helper.Log("Video Params: {0} x {1}. Pixels size: {2} Format: {3}", width, height, pixelSize, pixelFormat);

                        // Initialize buffer
                        var       bufferLen     = width * height;
                        const int bytesPerPixel = 4;
                        if (_bufferAr == null || _bufferAr.Length != bufferLen)
                        {
                            _bufferAr = new uint[bufferLen];
                        }
                        if (_bufferWb == null || _bufferWb.Length != bufferLen)
                        {
                            _bufferWb = new byte[bufferLen * bytesPerPixel];
                            Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                _writeableBitmap      = new WriteableBitmap(width, height);
                                PreviewElement.Source = _writeableBitmap;
                            });
                        }
                        _wasStarted = true;
                    }

                    // Get projection matrix
                    _arWrapper.arwGetProjectionMatrix(_projectionMatrix);

                    // Get marker modelView matrix and other properties
                    _isMarkerVisisble = false;
                    var confidence = -1f;
                    if (!_isMarkerVisisble)
                    {
                        _isMarkerVisisble = _arWrapper.arwQueryMarkerVisibility(_markerId);
                        _arWrapper.arwQueryMarkerTransformation(_markerId, _markerModelViewMatrix);
                        confidence = _arWrapper.arwGetMarkerOptionFloat(_markerId, ArMarkerOption.SquareConfidence);
                    }
#if DEBUG
                    if (_isMarkerVisisble)
                    {
                        Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
                        {
                            DbgTxt.Text = string.Format("Marker: {0} Confidence: {1:f02}\r\n" +
                                                        "{2,7:f02} {3,7:f02} {4,7:f02} {5,7:f02}\r\n" +
                                                        "{6,7:f02} {7,7:f02} {8,7:f02} {9,7:f02}\r\n" +
                                                        "{10,7:f02} {11,7:f02} {12,7:f02} {13,7:f02}\r\n" +
                                                        "{14,7:f02} {15,7:f02} {16,7:f02} {17,7:f02}\r\n",
                                                        _markerId, confidence,
                                                        _markerModelViewMatrix[00], _markerModelViewMatrix[04], _markerModelViewMatrix[08], _markerModelViewMatrix[12],
                                                        _markerModelViewMatrix[01], _markerModelViewMatrix[05], _markerModelViewMatrix[09], _markerModelViewMatrix[13],
                                                        _markerModelViewMatrix[02], _markerModelViewMatrix[06], _markerModelViewMatrix[10], _markerModelViewMatrix[14],
                                                        _markerModelViewMatrix[03], _markerModelViewMatrix[07], _markerModelViewMatrix[11], _markerModelViewMatrix[15]);
                        });
                    }
#endif

                    // Update video frame and render
                    if (_writeableBitmap != null && UpdateVideoTexture())
                    {
                        unsafe
                        {
                            fixed(uint *srcPtr = _bufferAr)
                            {
                                var b   = 0;
                                var len = _bufferWb.Length / 4;

                                for (var i = 0; i < len; i++, b += 4)
                                {
                                    // On a little-endian system, R occupies the lowest 8 bits, then G, then B, then A the highest 8 bits.
                                    // RGBA -> BGRA
                                    var p = srcPtr[i];
                                    _bufferWb[b + 0] = (byte)((p >> 16) & 0xff); // R
                                    _bufferWb[b + 1] = (byte)((p >> 8) & 0xff);  // G
                                    _bufferWb[b + 2] = (byte)((p >> 0) & 0xff);  // B
                                    _bufferWb[b + 3] = (byte)((p >> 24) & 0xff); // A
                                }
                            }
                        }

                        // Update needs to run on the UI thread
                        Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            // Show video buffer
                            using (var stream = _writeableBitmap.PixelBuffer.AsStream())
                            {
                                stream.Write(_bufferWb, 0, _bufferWb.Length);
                            }
                            _writeableBitmap.Invalidate();

                            // Compute XAML tranformation matrix
                            if (_isMarkerVisisble)
                            {
                                // Center at origin of the controls
                                var centerAtOrigin = Matrix3DFactory.CreateTranslation(-ControlPanel.ActualWidth * 0.5, -ControlPanel.ActualHeight * 0.5, 0);
                                // Swap the y-axis and scale down by half
                                var scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5);
                                // Rotate around z
                                var rotate = _shouldRotate ? Matrix3DFactory.CreateRotationZ(rotValue += 0.05) : Matrix3D.Identity;
                                // Viewport transformation
                                var viewport = Matrix3DFactory.CreateViewportTransformation(ContentPanel.ActualWidth, ContentPanel.ActualHeight);

                                // Calculate the final transformation matrix by using the marker model view and camera projection matrix
                                var m = Matrix3DFactory.CreateViewportProjection(
                                    centerAtOrigin * rotate * scale,
                                    _markerModelViewMatrix.ToMatrix3D(),
                                    _projectionMatrix.ToMatrix3D(),
                                    viewport);

                                // Apply the matrix to the UI control
                                ControlPanel.Projection = new Matrix3DProjection {
                                    ProjectionMatrix = m
                                };
                                ControlPanel.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                ControlPanel.Visibility = Visibility.Collapsed;
                            }
                        });
                    }
                }
            }
        }
예제 #9
0
        private void Update()
        {
            // Animation
            if (ChkAnimated.IsChecked != null && ChkAnimated.IsChecked.Value)
            {
                CameraZ = -Math.Abs(Math.Sin(_f)) * (FarPlane - NearPlane) * 1.5;
                CameraY = Math.Sin(_f * 10) * 1000;
                _f     += 0.008;
            }

            // Create global transformations
            var      vw          = Viewport.ActualWidth;
            var      vh          = Viewport.ActualHeight;
            var      invertYAxis = Matrix3DFactory.CreateScale(1, -1, 1);
            var      translate   = Matrix3DFactory.CreateTranslation(TranslateX, TranslateY, TranslateZ);
            var      rotateX     = Matrix3DFactory.CreateRotationX(MathHelper.ToRadians(RotateX));
            var      rotateY     = Matrix3DFactory.CreateRotationY(MathHelper.ToRadians(RotateY));
            var      rotateZ     = Matrix3DFactory.CreateRotationZ(MathHelper.ToRadians(RotateZ));
            var      scale       = Matrix3DFactory.CreateScale(ScaleX, ScaleY, ScaleZ);
            var      lookAt      = Matrix3DFactory.CreateLookAtLH(CameraX, CameraY, CameraZ, CameraLookAtX, CameraLookAtY, CameraLookAtZ);
            var      viewport    = Matrix3DFactory.CreateViewportTransformation(vw, vh);
            Matrix3D projectionMatrix;

            projectionMatrix = ChkPerspective.IsChecked != null && ChkPerspective.IsChecked.Value ? Matrix3DFactory.CreatePerspectiveFieldOfViewLH(MathHelper.ToRadians(FieldOfView), vw / vh, NearPlane, FarPlane) : Matrix3DFactory.CreateOrthographicLH(vw, vh, NearPlane, FarPlane);

            // Transform all elements
            var selectedMatrix = Matrix3D.Identity;

            foreach (var elem in _elements)
            {
                // The UIElement
                var e = elem.Element;

                // Create basic transformation matrices
                var centerAtOrigin = Matrix3DFactory.CreateTranslation(-e.ActualWidth * 0.5, -e.ActualHeight * 0.5, 0);
                var baseTranslate  = Matrix3DFactory.CreateTranslation(elem.PositionX, elem.PositionY, elem.PositionZ);

                // Combine the transformation matrices
                var m = Matrix3D.Identity;
                m = m * centerAtOrigin;
                m = m * invertYAxis;

                // Apply the world transformation to the selected element
                if (elem == _selectedElement)
                {
                    m = m * scale;
                    m = m * rotateX * rotateY * rotateZ;
                    m = m * translate;

                    // Should the camera target be fixed at the selected element?
                    if (ChkLookAtSelected.IsChecked != null && ChkLookAtSelected.IsChecked.Value)
                    {
                        lookAt = Matrix3DFactory.CreateLookAtLH(CameraX, CameraY, CameraZ, elem.PositionX, elem.PositionY, elem.PositionZ);
                    }
                }

                // Calculate the final view projection matrix
                m = m * baseTranslate;
                m = Matrix3DFactory.CreateViewportProjection(m, lookAt, projectionMatrix, viewport);

                if (elem == _selectedElement)
                {
                    selectedMatrix = m;
                }

                // Apply the transformation to the UIElement
                e.Projection = new Matrix3DProjection {
                    ProjectionMatrix = m
                };
            }

            // Trace
            TxtTrace1.Text = String.Format("{0} Elements. Matrix:\r\n{1}", _elements.Count, selectedMatrix.Dump());
        }
예제 #10
0
        private void Detect()
        {
            if (isDetecting || !isInitialized)
            {
                return;
            }

            isDetecting = true;
            var stopwatch = Stopwatch.StartNew();

            try
            {
                // Update buffer size
                var pixelWidth  = (int)photoCamera.PreviewResolution.Width;
                var pixelHeight = (int)photoCamera.PreviewResolution.Height;
                if (buffer == null || buffer.Length != pixelWidth * pixelHeight)
                {
                    buffer = new byte[pixelWidth * pixelHeight];

                    // Create constant transformations instances
                    // Center at origin of the 256x256 controls
                    centerAtOrigin = Matrix3DFactory.CreateTranslation(-128, -128, 0);
                    // Swap the y-axis and scale down by half
                    scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5);
                    // Viewport transformation
                    viewport           = Matrix3DFactory.CreateViewportTransformation(pixelWidth, pixelHeight);
                    matrix3DProjection = new Matrix3DProjection();
                    Txt.Projection     = matrix3DProjection;
                    Img.Projection     = matrix3DProjection;
                }

                // Grab snapshot
                photoCamera.GetPreviewBufferY(buffer);

                // Detect
                var dr = arDetector.DetectAllMarkers(buffer, pixelWidth, pixelHeight);

                // Draw the detected squares
                //bitmap.Clear();
                //ViewportOverlay.Source = bitmap;

                // Calculate the projection matrix
                if (dr.HasResults)
                {
                    // Calculate the complete transformation matrix based on the first detection result
                    var world = centerAtOrigin * scale * dr[0].Transformation;

                    // Calculate the final transformation matrix by using the camera projection matrix
                    var m = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, arDetector.Projection, viewport);

                    // Apply the final transformation matrix to the TextBox
                    matrix3DProjection.ProjectionMatrix = m;

                    //// Draw the detected squares
                    //foreach (var r in dr)
                    //{
                    //   bitmap.DrawQuad((int)r.Square.P1.X, (int)r.Square.P1.Y, (int)r.Square.P2.X, (int)r.Square.P2.Y, (int)r.Square.P3.X, (int)r.Square.P3.Y, (int)r.Square.P4.X, (int)r.Square.P4.Y, Colors.Red);
                    //}
                }
            }
            finally
            {
                isDetecting = false;
                stopwatch.Stop();
                TxtDiag.Text = string.Format("{0} ms", stopwatch.ElapsedMilliseconds);
            }
        }