<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Jeremiah-Morrill/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Jeremiah-Morrill/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Jeremiah-Morrill/Posts</link>
    <language>en</language>
    <pubDate>Sat, 25 May 2013 23:41:00 GMT</pubDate>
    <lastBuildDate>Sat, 25 May 2013 23:41:00 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Building the Laser Graffiti System</title>
      <description><![CDATA[
<p>Last year, Clint Rutkas contacted me about building a project involving lasers, graffiti and code. When you get a request like that, you never decline, especially when lasers are involved. The project requirements sounded quite simple: create an application
 that can, using a laser pointer as a virtual spray can, draw virtual graffiti on the side of a building. It sounded a little daunting to me at first, but after it was broken up into small digestible pieces, the project ended up not being very complicated.</p>
<p>Below is the basic hardware setup of the <i>Laser Graffiti System</i>.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image00110.png"><img title="clip_image001[10]" border="0" alt="clip_image001[10]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image00110_thumb.png" width="500" height="349"></a></p>
<h3>Building a Laser Tracker Engine</h3>
<h4>Giving Sight to the Blind</h4>
<p>The very first thing that needed to be proven was the ability to track a laser point. The most obvious solution was to give our application some vision with a webcam. Since this was going to be a WPF application, I decided to use my open-source project,
<a href="http://wpfmediakit.codeplex.com/">WPF MediaKit</a>, which comes with a webcam control called the VideoCaptureElement.</p>
<p>At the time, VideoCaptureElement was not very robust, and it occurred to me that my control wasn't very useful beyond looking at your webcam in a WPF app! I needed a way to get high-performance access to every pixel of every frame the webcam spat out. This
 was a good time to add that ability and increase value in my project. Without getting into the gory details of DirectShow and p/invoke, I was able to add a hook to pass me the pixel buffer, where I would wrap it in a Bitmap class and raise an event for each
 frame.</p>
<p>The XAML required to get each video sample from the web camera.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">MediaKit:VideoCaptureElement</span> <span class="attr">LoadedBehavior</span><span class="kwrd">=&quot;Play&quot;</span>
    <span class="attr">RenderOptions</span>.<span class="attr">BitmapScalingMode</span><span class="kwrd">=&quot;LowQuality&quot;</span>
    <span class="attr">UnloadedBehavior</span><span class="kwrd">=&quot;Manual&quot;</span>
    <span class="attr">DesiredPixelWidth</span><span class="kwrd">=&quot;{Binding DesiredPixelWidth}&quot;</span>
    <span class="attr">DesiredPixelHeight</span><span class="kwrd">=&quot;{Binding DesiredPixelHeight}&quot;</span>
    <span class="attr">VideoCaptureDevice</span><span class="kwrd">=&quot;{Binding SelectedItem, ElementName=videoCapDevices}&quot;</span>
    <span class="attr">FPS</span><span class="kwrd">=&quot;30&quot;</span>
    <span class="attr">EnableSampleGrabbing</span><span class="kwrd">=&quot;True&quot;</span>
    <span class="attr">NewVideoSample</span><span class="kwrd">=&quot;VideoCaptureElement_NewVideoSample&quot;</span>
    <span class="attr">Margin</span><span class="kwrd">=&quot;0&quot;</span>
    <span class="attr">x:Name</span><span class="kwrd">=&quot;videoElement&quot;</span>
    <span class="attr">Stretch</span><span class="kwrd">=&quot;Fill&quot;</span>
    <span class="attr">MinHeight</span><span class="kwrd">=&quot;380&quot;</span>
    <span class="attr">MinWidth</span><span class="kwrd">=&quot;500&quot;</span> <span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Did I Mention Lasers?</h4>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0045.png"><img title="clip_image004[5]" border="0" alt="clip_image004[5]" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0045_thumb.png" width="240" height="156"></a></p>
<p>Now that I had the ability to look at every pixel sent to me, I needed to make sense of it all. In order to complete the project, we have to be able to find a laser point shined on a wall. The difficulty lies in the fact that a laser can be of varying size
 and color. For example, if you take two consecutive video frames with the same green laser point, you will find the point may slightly differ between the two. This is because we are dealing with analog data and slightly changing lighting conditions. Whatever
 algorithm we choose to find the laser must take this into account.</p>
<p>There are many advanced ways to use video analytics to find the laser pointer, but this project did have a deadline, and I wanted to keep it fun, so I went with a simple method, which allows a user to filter the video based off ranges of hue, saturation,
 and luminance. To do this, we make use of the <a href="http://code.google.com/p/aforge/">
AForge image processing library</a>. AForge is an open-source library that comes with tons of useful utilities for just what we want to do.</p>
<h4>Filtering pixels and counting blobs…</h4>
<p>As previously mentioned, we need to first filter the image based on hue, saturation, and luminance. Luckily, the AForge library comes with such a filter, so there is not much work to be done here:
</p>
<pre class="csharpcode"><span class="rem">/* This AForge class helps us filter out the pixels we do not want */</span>
var hsl = <span class="kwrd">new</span> HSLFiltering
{
    Hue = <span class="kwrd">new</span> IntRange(HueMinimum, HueMaximum),
    Saturation = <span class="kwrd">new</span> DoubleRange(SaturationMinimum, SaturationMaximum),
    Luminance = <span class="kwrd">new</span> DoubleRange(LuminanceMinimum, LuminanceMaximum)
};

var bitmapData = bitmap.LockBits(
    <span class="kwrd">new</span> Rectangle((<span class="kwrd">int</span>)targetSearchArea.X, 
        (<span class="kwrd">int</span>)targetSearchArea.Y, 
        (<span class="kwrd">int</span>)targetSearchArea.Width, 
        (<span class="kwrd">int</span>)targetSearchArea.Height),
    System.Drawing.Imaging.ImageLockMode.ReadWrite, 
    m_lastBitmap.PixelFormat);


<span class="rem">/* Apply the AForge filter.  Doing it &quot;in place&quot; is more efficient as</span>
<span class="rem"> * new bitmap does not have to be allocated and copied */</span>
hsl.ApplyInPlace(bitmapData);</pre>
<p>So, what needs to be done now that we have a filtered image showing only a laser dot? The answer: Blob counting! A blob, in the context of video analytics, is a set of pixels that are all touching, and AForge comes with a class ready to tackle that too!</p>
<p>The AForge blob counter takes in a gray-scale image for processing, and then returns all blobs found in the image. The information included on a blob includes the rectangular pixel area where the laser was found in the video frame. The center of that area
 should be the center of our laser. It's important to note that if the HSL filter is improperly calibrated, we will get an overabundance of blobs and there will accordingly be no way we can tell if it is the laser point or not.</p>
<pre class="csharpcode"><span class="rem">/* Create an initialize our blob counter */</span>
var blobsCounter = <span class="kwrd">new</span> BlobCounter
    {
       FilterBlobs = <span class="kwrd">true</span>,
       ObjectsOrder = ObjectsOrder.Size,
       MinHeight = BlobMinimumHeight,
       MinWidth = BlobMinimumWidth,
       MaxWidth = 25,
       MaxHeight = 25
    };

<span class="rem">/* We first let the blob counter process our image */</span>
blobsCounter.ProcessImage(grayImage);

<span class="rem">/* Retrieve a list of blobs that were found */</span>
Blob[] blobs = blobsCounter.GetObjects(grayImage);</pre>
<p>The early laser tracking prototype. We can literally have it track anything, based off color.<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0085.jpg"><img title="clip_image008[5]" border="0" alt="clip_image008[5]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0085_thumb.jpg" width="275" height="397"></a></p>
<h3>Building the Laser Graffiti Application</h3>
<h4>Our Rocket Engine Needs a Rocket</h4>
<p>At this point, I had a working proof of concept and a laser tracker. What I needed now was an application to use it. You know, the laser-graffiti
<i>application</i>.</p>
<p>There are many ways to construct a WPF application and one pattern that's been getting a little bit of traction is MVVM. I chose to make a composite application using Prism and MVVM. Prism is a great guidance library pack for making composite WPF applications
 with tons of tools to help in common scenarios.</p>
<h4><i>Composite</i> What? Huh?</h4>
<p>When developing applications, usually of the larger variety, things can become complex. Complexity turns into a mess. A mess turns into time investment. Time investment turns into money. The more money spent, the fewer bonuses you will receive. To make sure
 we get that end-of-year pay raise, we want to control complexity from the get-go by making our code and our internal systems
<i>loosely coupled</i>. A composite application is just a collection of loosely coupled systems that is composited at runtime.</p>
<p>The advantages of a composite application are:</p>
<p>· Components can be developed independently</p>
<p>· Components can be swapped out more easily than if they were tightly coupled</p>
<p>· The application remains extendable, meaning you can more easily extend your application</p>
<p>· Maintenance is much clearer with less chance of breaking other components</p>
<p>· Unit testing is more feasible</p>
<h4>Composite Application Entrails</h4>
<p>There are many, many excellent resources about Prism available on the internet, so I'd rather not compete with them. I did, however, want to cover the basics, and at least how I've used it within the Laser Graffiti application.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0095.png"><img title="clip_image009[5]" border="0" alt="clip_image009[5]" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0095_thumb.png" width="230" height="146"></a></p>
<p><b>The Shell Assembly</b> – This contains the main entry point of the application and the initial or main UI container for the application. Before anything else, this assembly will initialize something called a bootstrapper. The bootstrapper simply does
 any pre-initialization that needs to be done before initializing the rest of the application.</p>
<p><b>Module Assemblies</b> – Each module assembly can be considered a <i>component</i>. The bootstrapper initializes each component and then the module spins up any application
<i>services</i> and adds any user interface to the shell. For instance, the MediaKit module handles the capture of the video and the AForgeModule handles the vision routines.</p>
<p><b>The Infrastructure Assembly</b> – This contains any base classes, well known/shared interfaces or general infrastructure code. Simply put, most if not all modules will have reference to this.</p>
<h3>Rendering the Graffiti</h3>
<p>I needed a way to draw the graffiti to a projector. Overall, this will be accomplished by drawing the graffiti to a window. The window will be set to
<i>maximized</i> with no border. I also needed to write the code to draw the graffiti. Initially, I just used the WPF InkCanvas control, but I found it wasn't well tuned for what I wanted to do with it. So, I decided XNA would give the most performance and
 flexibility with the level of effects desired for drawing graffiti.</p>
<p>I had never really done any XNA development, so this project is certainly not built using best practices. The important part to notice is that the project is more or less a regular XNA application with the exception that the executable is added as a library
 reference. This is because we instantiate the XNA from our WPF application's process. The following snippet of code accomplishes this:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ShowGraffitiWall(<span class="kwrd">bool</span> show)
{
    <span class="kwrd">if</span> (m_game != <span class="kwrd">null</span>)
        m_game.Exit();

    <span class="kwrd">if</span> (!show) 
        <span class="kwrd">return</span>;

    var t = <span class="kwrd">new</span> Thread((ThreadStart)<span class="kwrd">delegate</span>
    {
        m_game = <span class="kwrd">new</span> XnaGraffitiGame();
        m_game.SetScreen(m_lastScreen);
        m_game.Effect = m_lastGraffitiEffect;
        m_game.Run();
        m_game.Dispose();
    });

    t.SetApartmentState(ApartmentState.STA);
    t.IsBackground = <span class="kwrd">true</span>;
    t.Start();
}</pre>
<p>We instantiate the XNA window this way because it allows our WPF code to send the XNA messages of where the laser pointer was detected.</p>
<h4>Drawing with the GPU</h4>
<p>A blanket statement about XNA is that it is a drawing API. XNA applications can get quite complex when you add in things like 3D or shaders, but for this article, I'm only covering the required simple stuff. That said, I do make the assumption that the reader
 has had at least a few hours of XNA experience.</p>
<p>Our primary goal is to render virtual graffiti using XNA. This means we need to be able to draw a line. I started by creating a PNG file that would act as a “brush.” In XNA, these 2D graphics are also known as sprites. The brush sprite looks like this:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0115.png"><img title="clip_image011[5]" border="0" alt="clip_image011[5]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0115_thumb.png" width="273" height="264"></a></p>
<p>Now we can use XNA's SpriteBatch class to draw our brush. The first problem I had, though, was that most XNA tutorials show drawing the sprite, continue, clear the screen, draw the sprite, continue, etc. I needed to retain previous brush strokes, which means
 drawing onto an intermediate drawing surface (RenderTarget2D), then drawing that to the screen.</p>
<p>The next issue I had was that the line I was trying to draw was very broken. See, the laser detection code runs at a maximum 30 FPS (the limit of my web camera). If I moved the laser fast enough, the screen would just look like a bunch of random points were
 being drawn. I had to move the laser very slowly to make it appear like a line. I remember reading an
<a href="http://www.cynergysystems.com/blogs/page/rickbarraza?entry=advanced_render_techniques_with_writeablebitmaps">
excellent article</a> detailing a project by Rick Barraza, which led me to <a href="http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html">
a link to some popular algorithms</a> for creating a line where your input is two, 2D points.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0125.gif"><img title="clip_image012[5]" border="0" alt="clip_image012[5]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0125_thumb.gif" width="298" height="146"></a></p>
<p>So, drawing a line required only a simple, two-step process of A) getting a new point from laser detection, and B) drawing a line from last_laser_coordinate to current_laser_coordinate. After putting that together, we can now produce some useful looking
 graffiti!</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0144.jpg"><img title="clip_image014[4]" border="0" alt="clip_image014[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0144_thumb.jpg" width="401" height="302"></a></p>
<h4>Adding Crazy Graffiti Effects</h4>
<p>The excitement of drawing simple lines in XNA wore off pretty fast. After all, the GPU is capable of some pretty amazing things. What about drawing with fire? Fire isn't boring:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0164.jpg"><img title="clip_image016[4]" border="0" alt="clip_image016[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0164_thumb.jpg" width="455" height="281"></a></p>
<p>The fire effect is done using a method slightly similar to the solid color sprite method described earlier. However, since it uses a particle system, the fire effect is much more complex. Each particle has its own shader to control position and color. With
 the time constraints of this project, I had modified code from this <a href="http://creators.xna.com/en-US/sample/particle3d">
XNA tutorial</a>. There weren't many changes from the tutorial's code, but a big hurdle was that the particles took 3D coordinates instead of the 2D coordinates I needed to draw the graffiti. I found a small snippet to handle that, though I was informed by
 other XNA gurus that there is an easier way to accomplish this. If you are curious, this is what it looks like (and it's not for the faint of heart):</p>
<pre class="csharpcode"><span class="kwrd">protected</span> Vector3 ScreenPointToVector3(Point coords)
{
    Matrix viewMatrix = 
        Matrix.CreateTranslation(0, -25, 0) *
        Matrix.CreateRotationY(
            MathHelper.ToRadians(CameraRotation)) *
        Matrix.CreateRotationX(
            MathHelper.ToRadians(CameraArc)) *
        Matrix.CreateLookAt(
            <span class="kwrd">new</span> Vector3(0, 0, -CameraDistance),
            <span class="kwrd">new</span> Vector3(0, 0, 0), 
            Vector3.Up);

    <span class="kwrd">float</span> aspectRatio = 
        (<span class="kwrd">float</span>)m_game.GraphicsDevice.Viewport.Width /
            (<span class="kwrd">float</span>)m_game.GraphicsDevice.Viewport.Height;

    Matrix projectionMatrix = 
        Matrix.CreatePerspectiveFieldOfView(
            MathHelper.PiOver4,
            aspectRatio,
            1, 10000);

    Vector3 nearScreenPoint = <span class="kwrd">new</span> Vector3(coords.X, coords.Y, 0);
    Vector3 farScreenPoint = <span class="kwrd">new</span> Vector3(coords.X, coords.Y, 1);
    Vector3 nearWorldPoint = 
        m_game.GraphicsDevice.Viewport.Unproject(
            nearScreenPoint, 
            projectionMatrix, 
            viewMatrix, 
            Matrix.Identity);
    Vector3 farWorldPoint = 
        m_game.GraphicsDevice.Viewport.Unproject(
            farScreenPoint, 
            projectionMatrix, 
            viewMatrix, 
            Matrix.Identity);

    Vector3 direction = farWorldPoint - nearWorldPoint;

    <span class="kwrd">float</span> zFactor = -nearWorldPoint.Z / direction.Z;
    Vector3 zeroWorldPoint = nearWorldPoint &#43; direction * zFactor;

    <span class="kwrd">return</span> zeroWorldPoint;
}</pre>
<h3>The End Result</h3>
<p>Web-camera device selection:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0204.jpg"><img title="clip_image020[4]" border="0" alt="clip_image020[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0204_thumb.jpg" width="426" height="350"></a></p>
<p>Fine tuning the laser detection:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0224.jpg"><img title="clip_image022[4]" border="0" alt="clip_image022[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10042066/clip_image0224_thumb.jpg" width="461" height="385"></a></p>
<h3>About Jeremiah</h3>
<p><a href="http://jmorrill.hjtcentral.com/">Jeremiah Morrill</a> is a software developer and 2010 MVP living in Las Vegas, Nevada. He owns a software company called HJT,
<a title="http://www.hjtcentral.com/" href="http://www.hjtcentral.com/">http://www.hjtcentral.com/</a>, with a couple partners. There he focuses on multimedia and rich user interfaces with WPF and Silverlight. Jeremiah spends a lot of his free time learning,
 listening and helping others in the online development communities.&nbsp; </p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Jeremiah-Morrill/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1516d45ea42c4399be2b9e7600c8f5c7">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-the-Laser-Graffiti-System</comments>
      <itunes:summary>
Last year, Clint Rutkas contacted me about building a project involving lasers, graffiti and code. When you get a request like that, you never decline, especially when lasers are involved. The project requirements sounded quite simple: create an application
 that can, using a laser pointer as a virtual spray can, draw virtual graffiti on the side of a building. It sounded a little daunting to me at first, but after it was broken up into small digestible pieces, the project ended up not being very complicated. 
Below is the basic hardware setup of the Laser Graffiti System. 
 
Building a Laser Tracker Engine
Giving Sight to the Blind
The very first thing that needed to be proven was the ability to track a laser point. The most obvious solution was to give our application some vision with a webcam. Since this was going to be a WPF application, I decided to use my open-source project,
WPF MediaKit, which comes with a webcam control called the VideoCaptureElement. 
At the time, VideoCaptureElement was not very robust, and it occurred to me that my control wasn&#39;t very useful beyond looking at your webcam in a WPF app! I needed a way to get high-performance access to every pixel of every frame the webcam spat out. This
 was a good time to add that ability and increase value in my project. Without getting into the gory details of DirectShow and p/invoke, I was able to add a hook to pass me the pixel buffer, where I would wrap it in a Bitmap class and raise an event for each
 frame. 
The XAML required to get each video sample from the web camera. 
&amp;lt;MediaKit:VideoCaptureElement LoadedBehavior=&amp;quot;Play&amp;quot;
    RenderOptions.BitmapScalingMode=&amp;quot;LowQuality&amp;quot;
    UnloadedBehavior=&amp;quot;Manual&amp;quot;
    DesiredPixelWidth=&amp;quot;{Binding DesiredPixelWidth}&amp;quot;
    DesiredPixelHeight=&amp;quot;{Binding DesiredPixelHeight}&amp;quot;
    VideoCaptureDevice=&amp;quot;{Binding SelectedItem, ElementName=videoCapDevices}&amp;quot;
    FPS=&amp;quot;30&amp;quot;
    EnableSampleGrabbing=&amp;quot;Tr</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-the-Laser-Graffiti-System</link>
      <pubDate>Fri, 23 Jul 2010 19:54:04 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-the-Laser-Graffiti-System</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10042066_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10042066_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Jeremiah Morrill</dc:creator>
      <itunes:author>Jeremiah Morrill</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-the-Laser-Graffiti-System/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>PDC</category>
      <category>WPF</category>
      <category>XNA</category>
      <category>Lasers</category>
      <category>XNA framework</category>
      <category>audiovideo</category>
    </item>    
</channel>
</rss>