<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>Chris Tacke - OpenNETCF.Barcode</title>
    <link>http://blog.opennetcf.com/ctacke/</link>
    <description>Bringing Managed Code to the Embedded World</description>
    <copyright>Chris Tacke</copyright>
    <lastBuildDate>Mon, 23 Aug 2010 13:25:25 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>ctacke@opennetcf.com</managingEditor>
    <webMaster>ctacke@opennetcf.com</webMaster>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=5de3506e-d736-4d17-a773-cd7d84ca54e8</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,5de3506e-d736-4d17-a773-cd7d84ca54e8.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've published the code for <a href="http://barcode.codeplex.com/">the OpenNETCF.Barcode
library</a> I've been working on.  It is certainly not done - I wouldn't use
it in a shipping product at this point becasue the success rate is still pretty low,
so you'll end up with nothing but customer support requests.  
</p>
        <p>
I have some other work for actual customers to do, so I'm not going to be able to
dedicate a lot of time to the project over the next couple weeks so I decided to at
least publish what I have now for those who may be interested and to open it up for
development by anyone else who may wish to contribute.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5de3506e-d736-4d17-a773-cd7d84ca54e8" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.Barcode library published</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,5de3506e-d736-4d17-a773-cd7d84ca54e8.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/23/OpenNETCFBarcodeLibraryPublished.aspx</link>
      <pubDate>Mon, 23 Aug 2010 13:25:25 GMT</pubDate>
      <description>&lt;p&gt;
I've published the code for &lt;a href="http://barcode.codeplex.com/"&gt;the OpenNETCF.Barcode
library&lt;/a&gt; I've been working on.&amp;nbsp; It is certainly not done - I wouldn't use
it in a shipping product at this point becasue the success rate is still pretty low,
so you'll end up with nothing but customer support requests.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I have some other work for actual customers to do, so I'm not going to be able to
dedicate a lot of time to the project over the next couple weeks so I decided to at
least publish what I have now for those who may be interested and to open it up for
development by anyone else who may wish to contribute.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5de3506e-d736-4d17-a773-cd7d84ca54e8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.Barcode</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=03f1391b-b4fd-4e50-9aa3-8d9ca6c8547a</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,03f1391b-b4fd-4e50-9aa3-8d9ca6c8547a.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier blogs on the barcode library can be <a href="http://blog.opennetcf.com/ctacke/CategoryView,category,OpenNETCF.Barcode.aspx">found
here</a>.
</p>
        <p>
The next task I set for myself for the<a href="http://barcode.codeplex.com/"> OpenNETCF.Barcode
library</a> was detecting the bounds of a barcode.  My initial thought on how
to achieve this was to use a Fast Fourier Transform, or FFT of the horizontal luminance
lines I was already extracting.  The general idea would eb that I'd get an initial
line across the middle of the image and make the assumption that this line crosses
the barcode.  I then run an FFT for this data and look at the power spectrum
(basically looking at what the highest frequencies are).  
</p>
        <p>
The actual frequencies returned are not relevant.  My idea was that I could then
"move" up and down from that line, say at 10 pixel spacings, and do an FFT on these
lines.  If those FFTs lead to similar spectra, then we're still on the barcode. 
If the spectra changes dramatically, we've left the barcode.
</p>
        <p>
Fortunately I'd done an FFT algorithm port for the SDF ages ago though this is the
first real-world use of the class.  I had to add a bit of code to generate a
power spectrum, but once that was done I was a bit surprised to see how well the code
worked.  I updated the test UI to display both the current Y position used for
decoding (in green) and a red box for the "detected" bounds on the barcode, then ran
it against several new images I'd taken.
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_0.JPG" />
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_1.JPG" />
        </p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_2.JPG" />
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_3.JPG" />
        </p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_4.JPG" />
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_5.JPG" />
        </p>
        <p>
As you can see, the bounds detection is pretty good.  Next up will be figuring
out how to actually use this information.<br />
 
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=03f1391b-b4fd-4e50-9aa3-8d9ca6c8547a" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Recognizing Barcodes: Take 4</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,03f1391b-b4fd-4e50-9aa3-8d9ca6c8547a.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/17/RecognizingBarcodesTake4.aspx</link>
      <pubDate>Tue, 17 Aug 2010 16:14:27 GMT</pubDate>
      <description>&lt;p&gt;
Earlier blogs on the barcode library can be &lt;a href="http://blog.opennetcf.com/ctacke/CategoryView,category,OpenNETCF.Barcode.aspx"&gt;found
here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The next task I set for myself for the&lt;a href="http://barcode.codeplex.com/"&gt; OpenNETCF.Barcode
library&lt;/a&gt; was detecting the bounds of a barcode.&amp;nbsp; My initial thought on how
to achieve this was to use a Fast Fourier Transform, or FFT of the horizontal luminance
lines I was already extracting.&amp;nbsp; The general idea would eb that I'd get an initial
line across the middle of the image and make the assumption that this line crosses
the barcode.&amp;nbsp; I then run an FFT for this data and look at the power spectrum
(basically looking at what the highest frequencies are).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The actual frequencies returned are not relevant.&amp;nbsp; My idea was that I could then
"move" up and down from that line, say at 10 pixel spacings, and do an FFT on these
lines.&amp;nbsp; If those FFTs lead to similar spectra, then we're still on the barcode.&amp;nbsp;
If the spectra changes dramatically, we've left the barcode.
&lt;/p&gt;
&lt;p&gt;
Fortunately I'd done an FFT algorithm port for the SDF ages ago though this is the
first real-world use of the class.&amp;nbsp; I had to add a bit of code to generate a
power spectrum, but once that was done I was a bit surprised to see how well the code
worked.&amp;nbsp; I updated the test UI to display both the current Y position used for
decoding (in green) and a red box for the "detected" bounds on the barcode, then ran
it against several new images I'd taken.
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_0.JPG"&gt;&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_1.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_2.JPG"&gt;&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_3.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_4.JPG"&gt;&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_4_5.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, the bounds detection is pretty good.&amp;nbsp; Next up will be figuring
out how to actually use this information.&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=03f1391b-b4fd-4e50-9aa3-8d9ca6c8547a" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.Barcode</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=4c5704c9-c0aa-456e-af5a-5e31ae02ec12</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,4c5704c9-c0aa-456e-af5a-5e31ae02ec12.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last week I spent some time working on code to recognize an EAN13 barcode from a photograph. 
You can read the earlier blogs on my work <a href="http://blog.opennetcf.com/ctacke/2010/08/11/RecognizingBarcodes.aspx">here</a> and <a href="http://blog.opennetcf.com/ctacke/2010/08/13/RecognizingBarcodesTake2.aspx">here</a>.
</p>
        <p>
After improving the algorithms for determining whether a particular pixel was part
of a bar or a space, I was still having trouble with decoding one of my barcode pictures. 
Considering I had only tried two barcodes, I'd say that a 50% failure rate isn't very
good.  So the question now was "how do I improve recognition?"  
</p>
        <p>
Stepping through the code, I saw where the failure was occurring.  My code was
determining a "bit width" based on the EAN13's start delimiter of bar-space-bar, then
stepping across the image at that interval.  I had originally tried to add some
"intelligence" to the code to have the sample point shift left or right on the pixel
line if it was close to a state transition.  While it was an interesting idea
and improved decoding of the first barcode, it still wasn't doing much on this second
barcode.  
</p>
        <p>
It then occurred to me that I was being a bit of an idiot.  EAN13 is a fixed-width
code, so it always contains the exact same number of bits, so if I just found the
start and the end, I could divide the total width by the number of bits in the code
to get a better bit-width.  Even better, rather than sampling one pixel per bit,
why not just take the average luminance across the entire width and then check that
*average* against the threshold?  I updated the code and sure enough, I was able
to decode the second barcode.  Huzzah, success!
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_3_0.JPG" width="100%" />
        </p>
        <p>
So I'd say that now I have at least a rudimentary library for recognizing and decoding
an EAN13 barcode, but it still lacks one critical piece (and several things that would
be nice-to-haves).  When you want to recognize a barcode, you have to provide
a Y position across which the luminance line is extracted and you have to provide
a "threshold" value which the library uses to determine the value of a bit. 
A real consumer of this library isn't going to want to have to provide this information.
</p>
        <p>
Sure, for the Y position we can make an assumption that a horizontal line across the
center of the image will be on the barcode (and that's what I'm doing now) but are
there potentially better places to sample?  Would we get better results if we
did some sort of vertical averaging?  And what about the threshold?  
The two barcodes I was working with had fairly different threshold values that successfully
returned a result.  
</p>
        <p>
One of the next steps would be to add code to find the barcode bounds. I'm already
finding the left and right, which is simple, but finding the top and bottom would
be a bit more of a challenge.  Also I'd need a way to efficiently determine a
"best" threshold.  Those will be the tasks for this week (I've already done some
promising work on bounds finding, which I'll report in the next blog entry).<br /></p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=4c5704c9-c0aa-456e-af5a-5e31ae02ec12" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Recognizing Barcodes: Take 3</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,4c5704c9-c0aa-456e-af5a-5e31ae02ec12.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/16/RecognizingBarcodesTake3.aspx</link>
      <pubDate>Mon, 16 Aug 2010 19:41:55 GMT</pubDate>
      <description>&lt;p&gt;
Last week I spent some time working on code to recognize an EAN13 barcode from a photograph.&amp;nbsp;
You can read the earlier blogs on my work &lt;a href="http://blog.opennetcf.com/ctacke/2010/08/11/RecognizingBarcodes.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://blog.opennetcf.com/ctacke/2010/08/13/RecognizingBarcodesTake2.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
After improving the algorithms for determining whether a particular pixel was part
of a bar or a space, I was still having trouble with decoding one of my barcode pictures.&amp;nbsp;
Considering I had only tried two barcodes, I'd say that a 50% failure rate isn't very
good.&amp;nbsp; So the question now was "how do I improve recognition?"&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Stepping through the code, I saw where the failure was occurring.&amp;nbsp; My code was
determining a "bit width" based on the EAN13's start delimiter of bar-space-bar, then
stepping across the image at that interval.&amp;nbsp; I had originally tried to add some
"intelligence" to the code to have the sample point shift left or right on the pixel
line if it was close to a state transition.&amp;nbsp; While it was an interesting idea
and improved decoding of the first barcode, it still wasn't doing much on this second
barcode.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
It then occurred to me that I was being a bit of an idiot.&amp;nbsp; EAN13 is a fixed-width
code, so it always contains the exact same number of bits, so if I just found the
start and the end, I could divide the total width by the number of bits in the code
to get a better bit-width.&amp;nbsp; Even better, rather than sampling one pixel per bit,
why not just take the average luminance across the entire width and then check that
*average* against the threshold?&amp;nbsp; I updated the code and sure enough, I was able
to decode the second barcode.&amp;nbsp; Huzzah, success!
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_3_0.JPG" width="100%"&gt;
&lt;/p&gt;
&lt;p&gt;
So I'd say that now I have at least a rudimentary library for recognizing and decoding
an EAN13 barcode, but it still lacks one critical piece (and several things that would
be nice-to-haves).&amp;nbsp; When you want to recognize a barcode, you have to provide
a Y position across which the luminance line is extracted and you have to provide
a "threshold" value which the library uses to determine the value of a bit.&amp;nbsp;
A real consumer of this library isn't going to want to have to provide this information.
&lt;/p&gt;
&lt;p&gt;
Sure, for the Y position we can make an assumption that a horizontal line across the
center of the image will be on the barcode (and that's what I'm doing now) but are
there potentially better places to sample?&amp;nbsp; Would we get better results if we
did some sort of vertical averaging?&amp;nbsp; And what about the threshold?&amp;nbsp;&amp;nbsp;
The two barcodes I was working with had fairly different threshold values that successfully
returned a result.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
One of the next steps would be to add code to find the barcode bounds. I'm already
finding the left and right, which is simple, but finding the top and bottom would
be a bit more of a challenge.&amp;nbsp; Also I'd need a way to efficiently determine a
"best" threshold.&amp;nbsp; Those will be the tasks for this week (I've already done some
promising work on bounds finding, which I'll report in the next blog entry).&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=4c5704c9-c0aa-456e-af5a-5e31ae02ec12" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.Barcode</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=6ede5bfb-0164-49b4-87b0-1b628bb9becf</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,6ede5bfb-0164-49b4-87b0-1b628bb9becf.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blog.opennetcf.com/ctacke/2010/08/11/RecognizingBarcodes.aspx">Earlier
in the week I was working on a barcode library</a> that successfully recognized a
barcode from a picture.  The code was pretty rough, but the first cut worked
for the first barcode picture I took so I was pretty satisfied.
</p>
        <p>
I then took another picture from a different book, and of course it failed to decode. 
So that meant revisiting the code and the algorithms I was using to try to improve
the recognition rate.
</p>
        <p>
Here's the new barcode: 
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_0.JPG" />
        </p>
        <p>
When I ran it through the luminance algorithm, this is what I got back:
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_1.JPG" />
        </p>
        <p>
So how do we improve the "recognizability of this thing?  Well the first thing
I see is that the useful range, that is the range of threshold values that might yield
something meaningful, is pretty small. The threshold is essentially the Y value on
the above chart.  If you draw horizontal lines for each y value across the chart,
you see that almost the entire bottom half is going to be "black", meaning low luminance
and essentially worthless data.  So if our overall range is 255 (each point is
a byte value) then instead of using 0-255 for our useful data, just eyeballing it
we're probably only using about 100-255.
</p>
        <p>
My next step was to "scale" all of the values.  Basically subtract off the actual
range of values (the difference from the minimum and maximums across the range) and
then each by a factor to spread that new range across the 0-255 set.  Graphically
the newly ranged data looks like this:
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_2a.JPG" />
        </p>
        <p>
This is much better, but it's still got a whole lot of ugly "noise" at the transitions
between bars and spaces.  These are the long but thin peaks and valleys you see
at the edges of the apparent data bits.  I decided that I'd decrease that effect
by doing a "nearest neighbor" average across the data.  What this means is that
instead of using the raw luminance value of each pixel, I'd use the average of each
pixel along with the ones just to the left and right of it.  Running that algorithm
yields a luminance graph that looks like this:
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_3.JPG" />
        </p>
        <p>
It looks much, much better - at least visually.  I ran it through the existing
recognizer algorithm, and while it got further into it - actually pulling a few digits
out - it still failed to recognize.  It seems that I have a better filtering
algorithm, but my decoding algorithm is still a bit lacking.  We'll look at what
I did to address that in <a href="http://blog.opennetcf.com/ctacke/2010/08/16/RecognizingBarcodesTake3.aspx">the
next article</a>.<br /></p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=6ede5bfb-0164-49b4-87b0-1b628bb9becf" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Recognizing Barcodes: Take 2</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,6ede5bfb-0164-49b4-87b0-1b628bb9becf.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/13/RecognizingBarcodesTake2.aspx</link>
      <pubDate>Fri, 13 Aug 2010 16:09:19 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2010/08/11/RecognizingBarcodes.aspx"&gt;Earlier
in the week I was working on a barcode library&lt;/a&gt; that successfully recognized a
barcode from a picture.&amp;nbsp; The code was pretty rough, but the first cut worked
for the first barcode picture I took so I was pretty satisfied.
&lt;/p&gt;
&lt;p&gt;
I then took another picture from a different book, and of course it failed to decode.&amp;nbsp;
So that meant revisiting the code and the algorithms I was using to try to improve
the recognition rate.
&lt;/p&gt;
&lt;p&gt;
Here's the new barcode: 
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_0.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
When I ran it through the luminance algorithm, this is what I got back:
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_1.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
So how do we improve the "recognizability of this thing?&amp;nbsp; Well the first thing
I see is that the useful range, that is the range of threshold values that might yield
something meaningful, is pretty small. The threshold is essentially the Y value on
the above chart.&amp;nbsp; If you draw horizontal lines for each y value across the chart,
you see that almost the entire bottom half is going to be "black", meaning low luminance
and essentially worthless data.&amp;nbsp; So if our overall range is 255 (each point is
a byte value) then instead of using 0-255 for our useful data, just eyeballing it
we're probably only using about 100-255.
&lt;/p&gt;
&lt;p&gt;
My next step was to "scale" all of the values.&amp;nbsp; Basically subtract off the actual
range of values (the difference from the minimum and maximums across the range) and
then each by a factor to spread that new range across the 0-255 set.&amp;nbsp; Graphically
the newly ranged data looks like this:
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_2a.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
This is much better, but it's still got a whole lot of ugly "noise" at the transitions
between bars and spaces.&amp;nbsp; These are the long but thin peaks and valleys you see
at the edges of the apparent data bits.&amp;nbsp; I decided that I'd decrease that effect
by doing a "nearest neighbor" average across the data.&amp;nbsp; What this means is that
instead of using the raw luminance value of each pixel, I'd use the average of each
pixel along with the ones just to the left and right of it.&amp;nbsp; Running that algorithm
yields a luminance graph that looks like this:
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode_2_3.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
It looks much, much better - at least visually.&amp;nbsp; I ran it through the existing
recognizer algorithm, and while it got further into it - actually pulling a few digits
out - it still failed to recognize.&amp;nbsp; It seems that I have a better filtering
algorithm, but my decoding algorithm is still a bit lacking.&amp;nbsp; We'll look at what
I did to address that in &lt;a href="http://blog.opennetcf.com/ctacke/2010/08/16/RecognizingBarcodesTake3.aspx"&gt;the
next article&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=6ede5bfb-0164-49b4-87b0-1b628bb9becf" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.Barcode</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=3a62e42a-2666-4e92-b339-b12aa5541cdf</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,3a62e42a-2666-4e92-b339-b12aa5541cdf.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier this week Nick Randolph asked me if I knew of any .NET barcode recognition
software.  Not an SDK for an existing laser scanner, but something that might
take a picture of a barcode and decode it.  
</p>
        <p>
Early on in my development career I dealt with barcode scanners and I've always found
the technology to be fairly interesting.  I remembered some work <a href="http://www.mperfect.net/barCode/">Casey
Chesnut</a> had done quite some time ago on barcode recognition that I had always
wanted to spend a little time playing building off of.  Of course Casey didn't
provide any code, but that's fine - I'd rather attack this as a pure mental exercise
for myself.  
</p>
        <p>
I actually decided to attack the problem a little differently than Casey.  I
knew that doing a decode of a "pure" clean barcode would be easy and not a realistic
scenario anyway, so I didn't even bother working on code to do it.  I knew I
was going to be able to do the decoding algorithm part - that's simply turning bits
into text and anyone can do that given the algorithm.  The challenge, and fun,
is in extracting the binary data bits from an "analog" picture.  I'm saying "digital"
and "analog" here in that an ideal barcode bit is either black or white, on or
off, a picture (even a digital picture) is not going to be so clear.
</p>
        <p>
So step one was to take a picture of a barcode.  I grabbed a book off the shelf
and used my phone to snap a picture (bonus points if you know what book it is):
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode.jpg" />
        </p>
        <p>
You can see, it's not an "optimal" image - it's dark and there are a lot of variations
in color.  This seemed way more realistic.
</p>
        <p>
Next I needed to get rid of the "color" and I decided the best path would be to simply
"draw" a logical line horizontally through the center of the image assuming that it
would cross the barcode.  
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode2.jpg" />
        </p>
        <p>
I extracted every pixel across this line and determined the luminance of each, essentially
turning the line of pixels into greyscale.
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode4.jpg" />
        </p>
        <p>
Next I needed to turn this analog grey data into binary, which introduced a variable
I'll call the "threshold." Luminance values above the threshold (brighter) would be
a zero, below the threshold would be a one.  This means that you can alter what
the software "sees" for bars by simply adjusting that threshold.
</p>
        <p>
I put together a library and a sample application that showed all of this process
at once - the barcode, a chart of the luminance and a chart of the "binary" representation
of that luminance based on a given threshold.
</p>
        <p>
The next step was to try to turn this "binary" data into actual bits that I could
decode.  My first attempt followed this reasoning:  
<br />
1. an EAN13 barcode (which is what I'm working with) starts with three "guard" or
delimiter bits: 1-0-1.  
<br />
2. I start at the left edge of the image and traverse until I hit the first "on" pixel
and record that as the start position.<br />
3. I traverse until the next "off" pixel.  The distance between the on and off
is the width of a bit.<br />
4. I "back up" 1/2 of a bit width (to give me the best odds of hitting the actual
bit value) and then step forward by bit widths, checking the pixel value.
</p>
        <p>
It took a little tweaking of the logic, in which I'd move the current and subsequent
sample points away from any nearby "edge" to help get me in the middle of a data point. 
With only this minor logic improvement I was able to decode the picture I started
with.  I had a sample app that showed each of these steps:<br />
- The loaded barcode image<br />
- The luminance across the barcode at the mid point as a graph 
<br />
- A graph of the binary representation of that luminance based on a threshold<br />
- decoding of that binary set
</p>
        <p align="center">
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/barcode5.jpg" />
        </p>
        <p>
All that in just about 1 day of work.
</p>
        <p>
Of course the second barcode picture I took and tried failed.  It worked through
all of the steps until the decode, where it always fell apart, being unable to correctly
identify any digit but the first.  The failure, I think, is due to the fact the
book cover is glossy, so I have a lot more "noise" in the luminance graph.  That
simply means I need to improve my image recognition algorithm, which will be the focus
of <a href="http://blog.opennetcf.com/ctacke/2010/08/13/RecognizingBarcodesTake2.aspx">the
next blog entry on this library</a>.
</p>
        <p>
Now you might be asking "well where's the code for this?"  Patience.  It's
in Codeplex right now, it's just not yet published.  I want to get it to a state
that's a little less ugly before I turn it loose.  When can you expect it? 
Well I can't say for certain, but Codeplex required publication within 30 days, so
that gives you a "latest possible release" date - though I hope to publish earlier.<br /></p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=3a62e42a-2666-4e92-b339-b12aa5541cdf" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Recognizing Barcodes</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,3a62e42a-2666-4e92-b339-b12aa5541cdf.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2010/08/11/RecognizingBarcodes.aspx</link>
      <pubDate>Wed, 11 Aug 2010 19:11:36 GMT</pubDate>
      <description>&lt;p&gt;
Earlier this week Nick Randolph asked me if I knew of any .NET barcode recognition
software.&amp;nbsp; Not an SDK for an existing laser scanner, but something that might
take a picture of a barcode and decode it.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Early on in my development career I dealt with barcode scanners and I've always found
the technology to be fairly interesting.&amp;nbsp; I remembered some work &lt;a href="http://www.mperfect.net/barCode/"&gt;Casey
Chesnut&lt;/a&gt; had done quite some time ago on barcode recognition that I had always
wanted to spend a little time playing building off of.&amp;nbsp; Of course Casey didn't
provide any code, but that's fine - I'd rather attack this as a pure mental exercise
for myself.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I actually decided to attack the problem a little differently than Casey.&amp;nbsp; I
knew that doing a decode of a "pure" clean barcode would be easy and not a realistic
scenario anyway, so I didn't even bother working on code to do it.&amp;nbsp; I knew I
was going to be able to do the decoding algorithm part - that's simply turning bits
into text and anyone can do that given the algorithm.&amp;nbsp; The challenge, and fun,
is in extracting the binary data bits from an "analog" picture.&amp;nbsp; I'm saying "digital"
and "analog" here in that an ideal&amp;nbsp;barcode bit is either black or white, on or
off, a picture (even a digital picture) is not going to be so clear.
&lt;/p&gt;
&lt;p&gt;
So step one was to take a picture of a barcode.&amp;nbsp; I grabbed a book off the shelf
and used my phone to snap a picture (bonus points if you know what book it is):
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
You can see, it's not an "optimal" image - it's dark and there are a lot of variations
in color.&amp;nbsp; This seemed way more realistic.
&lt;/p&gt;
&lt;p&gt;
Next I needed to get rid of the "color" and I decided the best path would be to simply
"draw" a logical line horizontally through the center of the image assuming that it
would cross the barcode.&amp;nbsp; 
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode2.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
I extracted every pixel across this line and determined the luminance of each, essentially
turning the line of pixels into greyscale.
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode4.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Next I needed to turn this analog grey data into binary, which introduced a variable
I'll call the "threshold." Luminance values above the threshold (brighter) would be
a zero, below the threshold would be a one.&amp;nbsp; This means that you can alter what
the software "sees" for bars by simply adjusting that threshold.
&lt;/p&gt;
&lt;p&gt;
I put together a library and a sample application that showed all of this process
at once - the barcode, a chart of the luminance and a chart of the "binary" representation
of that luminance based on a given threshold.
&lt;/p&gt;
&lt;p&gt;
The next step was to try to turn this "binary" data into actual bits that I could
decode.&amp;nbsp; My first attempt followed this reasoning:&amp;nbsp; 
&lt;br&gt;
1. an EAN13 barcode (which is what I'm working with) starts with three "guard" or
delimiter bits: 1-0-1.&amp;nbsp; 
&lt;br&gt;
2. I start at the left edge of the image and traverse until I hit the first "on" pixel
and record that as the start position.&lt;br&gt;
3. I traverse until the next "off" pixel.&amp;nbsp; The distance between the on and off
is the width of a bit.&lt;br&gt;
4. I "back up" 1/2 of a bit width (to give me the best odds of hitting the actual
bit value) and then step forward by bit widths, checking the pixel value.
&lt;/p&gt;
&lt;p&gt;
It took a little tweaking of the logic, in which I'd move the current and subsequent
sample points away from any nearby "edge" to help get me in the middle of a data point.&amp;nbsp;
With only this minor logic improvement I was able to decode the picture I started
with.&amp;nbsp; I had a sample app that showed each of these steps:&lt;br&gt;
- The loaded barcode image&lt;br&gt;
- The luminance across the barcode at the mid point as a graph 
&lt;br&gt;
- A graph of the binary representation of that luminance based on a threshold&lt;br&gt;
- decoding of that binary set
&lt;/p&gt;
&lt;p align=center&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/barcode5.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
All that in just about 1 day of work.
&lt;/p&gt;
&lt;p&gt;
Of course the second barcode picture I took and tried failed.&amp;nbsp; It worked through
all of the steps until the decode, where it always fell apart, being unable to correctly
identify any digit but the first.&amp;nbsp; The failure, I think, is due to the fact the
book cover is glossy, so I have a lot more "noise" in the luminance graph.&amp;nbsp; That
simply means I need to improve my image recognition algorithm, which will be the focus
of &lt;a href="http://blog.opennetcf.com/ctacke/2010/08/13/RecognizingBarcodesTake2.aspx"&gt;the
next blog entry on this library&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Now you might be asking "well where's the code for this?"&amp;nbsp; Patience.&amp;nbsp; It's
in Codeplex right now, it's just not yet published.&amp;nbsp; I want to get it to a state
that's a little less ugly before I turn it loose.&amp;nbsp; When can you expect it?&amp;nbsp;
Well I can't say for certain, but Codeplex required publication within 30 days, so
that gives you a "latest possible release" date - though I hope to publish earlier.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=3a62e42a-2666-4e92-b339-b12aa5541cdf" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.Barcode</category>
    </item>
  </channel>
</rss>