General

There are three different Marker Detector implementations with two different communication approaches available. The CaptureSourceMarkerDetector uses Silverlight's CaptureSource directly and can be considered as push based technology. The GenericMarkerDetector and the BitmapMarkerDetector on the other hand provide a more generic interface and can be considered as a pull approach. The GenericMarkerDetector takes an IXrgbReader interface implementation as input for detection and the BitmapMarkerDetector reads the data form a WriteableBitmap.
A marker detection provides the detection results through the DetectionResult class which contains a reference to the Marker that was detected, the Confidence of the marker matching, a Square that holds the pixel coordinates where the marker was found and the calculated transformation Matrix.

CaptureSourceMarkerDetector - Pushed Marker Detection Results

The CaptureSourceMarkerDetector is initialized with a CaptureSource instance and searches for markers each time a new frame is created by the CaptureSource. The CaptureSourceMarkerDetector has the MarkersDetected event which is fired each frame and provides the DetectionResults. The MarkersDetected event is raised in a background thread, therefore it's necessary to use Dispatcher.BeginInvoke to apply the detection results to UI elements.
This marker detector is optimized to get the best performance and is typically used in combination with the Webcam.

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

// Load marker and initialize detector
using (Stream markerSlarStream = App.GetResourceStream(new Uri("SLARToolKitSample;component/data/Marker_SLAR_16x16segments_80width.pat", UriKind.Relative)).Stream)
{
   var markerSlar = Marker.Load(markerSlarStream, 16, 16, 80.0, "SLAR");
   ArDetector = new CaptureSourceMarkerDetector(captureSource, 1, 4000, new List<Marker>{ markerSlar });
}

// This event is raised in a background thread and not in the UI thread. Use Dispatcher.BeginInvoke to change UIElements.
ArDetector.MarkersDetected += (s, e) =>
{
   var detectedResults = e.DetectionResults;
   // Process results ...
}

GenericMarkerDetector and BitmapMarkerDetector - Pulling Marker Detection Results

The GenericMarkerDetector has a generic interface and can be used in combination with an implementation of the IXrgbReader interface which provides integer pixel data as XRGB byte components. The BitmapMarkerDetector takes an WriteableBitmap for detection that comes form a Webcam snapshot or any other WriteableBitmap provider. Both have a DetectAllMarkers method that is called explicitly at any given rate. The performance of the BitmapMarkerDetector is actually only slightly worse than the CaptureSourceMarkerDetector's.

// Load marker and initialize detector
arDetector = new BitmapMarkerDetector();
using (Stream markerStream = App.GetResourceStream(new Uri("SLARToolKitBalderSample;component/data/Marker_SLAR_16x16segments_80width.pat", UriKind.Relative)).Stream)
{
   var marker = Marker.Load(markerStream, 16, 16, 80.0);
   arDetector.Initialize(videoFormat.Width, videoFormat.Height, Game.Camera.Near, Game.Camera.Far, marker);
}

// Attach the event hander to the CaptureImageCompleted event:
captureSource.CaptureImageCompleted += (s, e) =>
{
        // e.Result is a WriteableBitmap
	var bmp = e.Result;      

	// Explicitly detect markers in webcam snapshot
	var detectedResults = arDetector.DetectAllMarkers(bmp);

	// Highlight detected markers using the  WriteableBitmapEx
	foreach (var r in detectedResults)
	{
	 bmp.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);
	}

	// Process results further ...
}

// The detection is subsequently performed in the CompositionTarget.Rendering event handler in the foreground thread
CompositionTarget.Rendering += (s, ea) =>
{
   captureSource.CaptureImageAsync();
};

Last edited Jun 3, 2010 at 4:40 PM by teichgraf, version 25

Comments

No comments yet.