decoding barcodes

64
CS 1 with Robots Decoding Barcodes Institute for Personal Robots in Education

Upload: haracha

Post on 28-Jan-2016

96 views

Category:

Documents


0 download

DESCRIPTION

Decoding Barcodes. Institute for Personal Robots in Education (IPRE) ‏. Barcodes are designed to be machine readable They encode numbers and symbols using black and white bars. The examples on this page are standard 1D barcodes using the Code39 encoding scheme. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Decoding Barcodes

CS 1 with Robots

Decoding Barcodes

Institute for Personal Robots in Education

(IPRE)

Page 2: Decoding Barcodes

Aug 29 2007 2

Barcodes are designed to be machine readableThey encode numbers and symbols using black and white bars.

The examples on this page are standard 1D barcodes using the Code39 encoding scheme.Usually read by laser scanners, they can also be read using a camera.

Page 3: Decoding Barcodes

Aug 29 2007 3

Code39 (Sometimes called 3 from 9) barcodes use 9 bars to represent each symbol.The bars can be black or white.The bars are either narrow or wide.Wide bars must be 2.1 to 3 times larger than narrow bars.Each symbol pattern starts and ends with a black bar.A valid barcode starts and ends with the STAR (*) symbol, which is used as a delimiter.

The STAR (*) symbol is made up of a narrow black bar, a wide white bar, a narrow black bar, a narrow white bar, a wide black bar, a narrow white bar, a wide black bar, a narrow white bar, and a narrow black bar.

Page 4: Decoding Barcodes

Aug 29 2007 4

Code39 (Sometimes called 3 from 9) barcodes use 9 bars to represent each symbol.The bars can be black or white.The bars are either narrow or wide.Wide bars must be 2.1 to 3 times larger than narrow bars.Each symbol pattern starts and ends with a black bar.A valid barcode starts and ends with the STAR (*) symbol, which is used as a delimiter.

This could also be represented as the string “bWbwBwBwb”

Page 5: Decoding Barcodes

Aug 29 2007 5

How many bars is in a barcode that encodes 3 symbols?Although each symbol pattern starts and ends with a black bar, patterns must be separated by a white bar (typically narrow), so each symbol except the last is represented with 10 bars in total. (The last symbol has 9 bars, and does not need a separator after it.)Don't forget the Start and Stop symbol!

Page 6: Decoding Barcodes

Aug 29 2007 6

How many bars is in a barcode that encodes 3 symbols?Although each symbol pattern starts and ends with a black bar, patterns must be separated by a white bar (typically narrow), so each symbol except the last is represented with 10 bars in total. (The last symbol has 9 bars, and does not need a separator after it.)Don't forget the Start and Stop symbol!

3 symbols + start + stop = 5 symbols, at 9 bars each, plus 4 narrow white bars to separate the symbols is 9 * 5 + 4,

or 10*5 – 1 to make 49 bars total!

Page 7: Decoding Barcodes

Aug 29 2007 7

All of the symbol patterns:

What symbol is on the right?

Page 8: Decoding Barcodes

Aug 29 2007 8

It's an “I”

What symbol is on the right?

Page 9: Decoding Barcodes

Aug 29 2007 9

But what does a barcode look like from the robot?

The robot's camera has relatively low resolution (256x192 pixels).To decode a barcode successfully from an image, we need multiple pixels for each bar . This means that we are limited in the size of barcodes we can successfully use.Here is a picture of a two symbol (4 patterns total) barcode taken with a (VERY) carefully aimed robot camera:

Page 10: Decoding Barcodes

Aug 29 2007 10

It's sort of messy!

High contrast elements (black and white lines) generate color artifacts due to the bayer filter layout in the camera.

Page 11: Decoding Barcodes

Aug 29 2007 11

Step 1: Lets clean it up!

Convert to black and white with a thresholding process!

Page 12: Decoding Barcodes

Aug 29 2007 12

Step 1: Lets clean it up!

Convert to black and white with a thresholding process!For each pixel, check to see if it's brighter than a threshold (say, 127).

If yes, set the color to white!If no, set the color to black!

Page 13: Decoding Barcodes

Aug 29 2007 13

Threshold Code

Page 14: Decoding Barcodes

Aug 29 2007 14

Threshold Code

def threshold(pic): for i in getPixels(pic): g = getGreen(i) if( g < 127): setRed(i,0) setGreen(i,0) setBlue(i,0) else: setRed(i,255) setGreen(i,255) setBlue(i,255)

return(pic)

Page 15: Decoding Barcodes

Aug 29 2007 15

Threshold Code: How to improve it!

Note that we are using the green value as a proxy for the “brightness” (or luminance) of the pixel.

To do this correctly, we should calculate the luminance of the pixel with the following formula:

Y = 0.2126 * Red + 0.7152 * Green + 0.0722 * Blue

Notice how the Green component makes up 70% of the Luminance (Y) value?

That is why it's almost OK to cheat and just use the green channel!

Page 16: Decoding Barcodes

Aug 29 2007 16

Now what?

We have a thresholded image, now we have to scan across it to look for bars.Lets start out with a simpler task, just scan across it and save a list of the pixel values (white=255 or black=0) in a list.But where do we scan?

Page 17: Decoding Barcodes

Aug 29 2007 17

Now what?

We have a thresholded image, now we have to scan across it to look for bars.Lets start out with a simpler task, just scan across it and save a list of the pixel values (white=255 or black=0) in a list.But where do we scan?How about the middle?How do you find the middle of the image?

Page 18: Decoding Barcodes

Aug 29 2007 18

Our Image:

X=255X=0 Width = 256

Y=0

Y=191

Height = 192

Page 19: Decoding Barcodes

Aug 29 2007 19

Our Image: Middle

X=255X=0 Width = 256

Y=0

Y=191

Height = 192

Middle =Height / 2

Page 20: Decoding Barcodes

Aug 29 2007 20

Code to save pixel values along a horizontal scanline:

def makeScanLine(bwPic):

return(values)

Page 21: Decoding Barcodes

Aug 29 2007 21

Code to save pixel values along a horizontal scanline:

def makeScanLine(bwPic): height = getHeight(bwPic) mid = height / 2

width = getWidth(bwPic)

values = [] for x in range(0, width): pix = getPixel(bwPic, x, mid) val = getGreen(pix) values.append(val)

return(values)

Page 22: Decoding Barcodes

Aug 29 2007 22

Example Scanline Data:

[0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]

Note the large runs of white at the beginning and end of the barcode!

Page 23: Decoding Barcodes

Aug 29 2007 23

How to improve our data?

Scanline data presents the raw pixel data, but it's not very easy to understand.Lets scan for “runs” of pixels of the same color.Convert this:[0,0, 255,255,255,255,255, 0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0]

Page 24: Decoding Barcodes

Aug 29 2007 24

How to improve our data?

Scanline data presents the raw pixel data, but it's not very easy to understand.Lets scan for “runs” of pixels of the same color.Convert this:[0,0, 255,255,255,255,255, 0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0]

to this:[ (2,0), (5,255), (2,0), (2,255), (4,0), (2,255), (4,0), (2,255), (2,0)]

Page 25: Decoding Barcodes

Aug 29 2007 25

How to improve our data?

Scanline data presents the raw pixel data, but it's not very easy to understand.Lets scan for “runs” of pixels of the same color.Convert this:[0,0, 255,255,255,255,255, 0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0, 255,255, 0,0,0,0]

to this:[ (2,0), (5,255), (2,0), (2,255), (4,0), (2,255), (4,0), (2,255), (2,0)]

Which could be read as:“bWbwBwBwb”

Page 26: Decoding Barcodes

Aug 29 2007 26

Code to spot runs of the same color

def parseScanline(scanLine):

return(barData)

Page 27: Decoding Barcodes

Aug 29 2007 27

Code to spot runs of the same color

def parseScanline(scanLine):

barData = [] previous = scanLine[0] length = 0 for element in scanLine: if (element != previous): #a change has occured! myTuple = (length, previous) barData.append( myTuple ) #add run info to barData list length = 1 previous = element else: #No change. length = length + 1

Page 28: Decoding Barcodes

Aug 29 2007 28

Don't forget to record the last run!

def parseScanline(scanLine):

barData = [] previous = scanLine[0] length = 0 for element in scanLine: if (element != previous): #a change has occured! myTuple = (length, previous) barData.append( myTuple ) #add run info to barData list length = 1 previous = element else: #No change. length = length + 1

#Rescue the last bit of data stored in the previous # and length variables! myTuple = (length, previous) barData.append( myTuple )

return(barData)

Page 29: Decoding Barcodes

Aug 29 2007 29

Some real data!

Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Can you spot the narrow and wide bars?

Page 30: Decoding Barcodes

Aug 29 2007 30

Some real data!

Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Narrow bars look to be around 3-4 pixels in size, and wide bars appear to be around 6-8 pixels in size!

Page 31: Decoding Barcodes

Aug 29 2007 31

Some real data! With real-world problems!

Wait! What's that black bar doing at the front of our image (2,0) before all that white space (26,255)?

Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Page 32: Decoding Barcodes

Aug 29 2007 32

Some real data!

Wait! What's that black bar doing at the front of our image (2,0) before all that white space (26,255)?

Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Zoom in:

Page 33: Decoding Barcodes

Aug 29 2007 33

Some real data!

The robot's camera has a bug! It produces two columns of black pixels on the left of every image!

But no problems! We'll just make sure that our barcode parsing code can handle random bars before the barcode officially starts!

Zoom in:

Page 34: Decoding Barcodes

Aug 29 2007 34

Another problem!

Wait! What are those single pixel black and white bars doing in the middle of our image? Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Page 35: Decoding Barcodes

Aug 29 2007 35

Another problem!

Wait! What are those single pixel black and white bars doing in the middle of our image? Actual scanline data:

[ (2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255),(4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (39, 255) ]

Zoom in:

Page 36: Decoding Barcodes

Aug 29 2007 36

Another problem!

We need to remove those single pixel errors!

Zoom in:

Page 37: Decoding Barcodes

Aug 29 2007 37

Code to remove single pixel errors:

Remove single pixel errors!Example data: [ (4, 255), (8, 0), (2, 255), (1, 0), (1, 255), (6, 0), (4, 255) ]

We want:[ (4, 255), (8, 0), (2, 255), (6, 0), (4, 255) ]

Page 38: Decoding Barcodes

Aug 29 2007 38

Code to remove single pixel errors:

def removeSingles(barData):

return(newBarData)

Page 39: Decoding Barcodes

Aug 29 2007 39

Code to remove single pixel errors:

def removeSingles(barData):newBarData =[]

for item in barData:length = item[0]

if (length != 1):newBarData.append(item)

return(newBarData)

Page 40: Decoding Barcodes

Aug 29 2007 40

Good data, but how to find Wide and Narrow bars?

[(2, 0), (26, 255), (3, 0), (8, 255), (3, 0), (3, 255), (8, 0), (4, 255), (8, 0), (4, 255), (2, 0), (4, 255), (8, 0), (4, 255), (4, 0), (8, 255), (2, 0), (4, 255), (4, 0), (4, 255), (8, 0), (2, 255), (6, 0), (4, 255), (4, 0), (8, 255), (8, 0), (4, 255), (2, 0), (4, 255), (4, 0), (4, 255), (2, 0), (8, 255), (4, 0), (4, 255), (8, 0), (4, 255), (7, 0), (3, 255), (4, 0), (255, 39)]

How do we pick the threshold that separates wide from narrow bars?Look at just the widths:[2, 26, 3, 8, 3, 3, 8, 4, 8, 4, 2, 4, 8, 4, 4, 8, 2, 4, 4, 4, 8, 2, 6, 4, 4, 8, 8, 4, 2, 4, 4, 4, 2, 8, 4, 4, 8, 4, 7, 3, 4, 39]

Page 41: Decoding Barcodes

Aug 29 2007 41

Good data, but how to find Wide and Narrow bars?

SORT the widths:[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

Eyeball it! What would make a good threshold?

Page 42: Decoding Barcodes

Aug 29 2007 42

Good data, but how to find Wide and Narrow bars?

SORT the widths:[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

Eyeball it! A 5 or 6 would make a good threshold! But how does the computer figure that out?

Page 43: Decoding Barcodes

Aug 29 2007 43

Good data, but how to find Wide and Narrow bars?

SORT the widths:[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

What is the median width?[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

Page 44: Decoding Barcodes

Aug 29 2007 44

Good data, but how to find Wide and Narrow bars?

What is the median width?[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,

4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

How about ¾ of the way up the list?[2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,

4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26, 39]

Page 45: Decoding Barcodes

Aug 29 2007 45

Good data, but how to find Wide and Narrow bars?

Pick a threshold halfway between the median (4 = narrow bar size) and the ¾ point ( 8 = wide bar size): (8 – 4) / 2 = 2 ( 2 bigger than median value is 6!)4 + 2 = 6

Anything 6 pixels or larger is a wide bar!

Page 46: Decoding Barcodes

Aug 29 2007 46

Code to find the width threshold:

def calculateWidthThreshold(barData):

return( threshold )

Page 47: Decoding Barcodes

Aug 29 2007 47

Code to find the width threshold:

def calculateWidthThreshold(barData): #Load just the widths! barWidths = [] for x in barData: barWidths.append(x[0])

barWidths.sort() #Find the size of a narrow bar! medianIdx = len(barWidths) / 2 narrowSize= barWidths[medianIdx]

#Go to the 3/4 point, find the size of a wide bar! wideIdx = medianIdx + (medianIdx / 2) wideSize = barWidths[wideIdx]

#Calculate the threshold dist = (wideSize – narrowSize) / 2

threshold = narrowSize + dist

return( threshold )

Page 48: Decoding Barcodes

Aug 29 2007 48

Decoding the bars!

Now that we know the width threshold, we can convert our barData into a string representing the barcode! (made up of the letters {b,B,w,W})For example:barData = [ (4, 255), (8, 0), (7, 255), (3, 0) ]

should produce a string like this:“wBWb”(narrow white, wide Black, white White, narrow black)

Page 49: Decoding Barcodes

Aug 29 2007 49

Decoding the bars!

def decodeBars(barData,widthThreshold):

return(barString)

Page 50: Decoding Barcodes

Aug 29 2007 50

Decoding the bars!

def decodeBars(barData,widthThreshold): barString = ""

for bar in barData: if(bar[1] == 255): #It's a white bar! if(bar[0] >= widthThreshold):

#It's a wide white bar! barString = barString + "W" else:

#It's a narrow white bar barString = barString + "w" else: #It's a black bar! if(bar[0] >= widthThreshold):

#It's a wide black bar! barString = barString + "B" else:

#it's a narrow black bar! barString = barString + "b"

return(barString)

Page 51: Decoding Barcodes

Aug 29 2007 51

Parsing the barcode string

Actual barString: bWbWbwBwBwbwBwbWbwbwBwBwbWBwbwbwbWbwBwBwbW

Now we just have to parse this string to find our barcode!

All (valid) barcodes start with the pattern:

“bWbwBwBwb” or the “*” symbol

Lets go looking for it!

Page 52: Decoding Barcodes

Aug 29 2007 52

Parsing the barcode string

There it is! bWbWbwBwBwbwBwbWbwbwBwBwbWBwbwbwbWbwBwBwbW

Page 53: Decoding Barcodes

Aug 29 2007 53

Parsing the barcode string

Now, a white bar will separate the start symbol from the first data symbol! bWbWbwBwBwbwBwbWbwbwBwBwbWBwbwbwbWbwBwBwbW

Page 54: Decoding Barcodes

Aug 29 2007 54

Parsing the barcode string

The second symbol is 9 bars long, and is also followed by a white bar! BwbWbwBwBwbwBwbWbwbwBwBwbWBwbwbwbWbwBwBwbW

So if we look up “BwbWbwbwB” we can figure out what our first symbol is!

Page 55: Decoding Barcodes

Aug 29 2007 55

All of the symbol patterns:

How do we get all those symbols into our code to do the lookup?

Page 56: Decoding Barcodes

Aug 29 2007 56

All of the symbol patterns:

#Use a dictionary!code39dict = { 'BwbWbwbwB': "1", 'bwBWbwbwB': "2", 'BwBWbwbwb': "3", 'bwbWBwbwB': "4", 'BwbWBwbwb': "5", ... 'BwbwbWbwB': "A", 'bwBwbWbwB': "B", 'BwBwbWbwb': "C", ... 'bWbwBwBwb': "*", #Start/Stop character }

Luckily I've already typed the codes in for you, look on the website for the code39dict.py file!

Page 57: Decoding Barcodes

Aug 29 2007 57

Parsing the barcode string

code39dict = { 'BwbWbwbwB': "1", }

answer = code39dict[“BwbWbwbwB”]print answer“1”

Our first symbol is a 1!

Page 58: Decoding Barcodes

Aug 29 2007 58

Parsing the barcode string

Each symbol is 9 bars long, and separated by a white bar! ...wBwbWbwbwBwBwbWBwbwbwbWbwBwBwbW

Our second symbol is a “5”

Page 59: Decoding Barcodes

Aug 29 2007 59

Parsing the barcode string

The second symbol is 9 bars long, and is also followed by a white bar! ...BwbWBwbwbwbWbwBwBwbW

And our last symbol should look familiar, because it is the “*” or Start/Stop symbol, and is the same as our first symbol!

Note that the large white area after the barcode is represented by a single W.

All together, our barcode reads: “*15*”

We don't report the *'s, so our number is 15

Page 60: Decoding Barcodes

Aug 29 2007 60

Code to find the start symbol!

def findCode39(barString):

Page 61: Decoding Barcodes

Aug 29 2007 61

Code to find the start symbol!

def findCode39(barString):

#Search for a start code!startLoc = barString.find("bWbwBwBwb")

if(startLoc == -1): #No start character foundreturn(None)

#Beginning of first data symbol...#each code is 9 bars long,#plus one bar to separate them!

startLoc = startLoc + 10

#Initialize a variable to store our codecodeData = “”

Page 62: Decoding Barcodes

Aug 29 2007 62

Code to read each symbol!

while( startLoc < len(barString)):code = barString[startLoc:startLoc+9]letter = code39dict.get(code,-1)

if (letter == -1): #Invalid code!return(None)

else: #Valid code!if(letter == '*'): #Found end of barcode

return(codeData) #Return the data!

else: #Add letter to our codeDatacodeData = codeData + letter

#We advance by 10 to the next code symbolstartLoc = startLoc + 10

#did not find a stop code! Abort! return(None)

Page 63: Decoding Barcodes

Aug 29 2007 63

Barcodes – Not that hard after all!

Questions?

Page 64: Decoding Barcodes

CS 1 with Robots

Thank you for attention!