Loops through each row in a binary image and gets the width of each group of black or white pixels

Example image:

Code:

#get height and width of image
height, width = possible_barcode_img.shape[:2]

#prepare list for rows
barcode_rows = []

for i in range(height):

# set variables and list for beginning of row
white_bar_width = 0
black_bar_width = 0
barcode_row = []

for j in range(width):
if possible_barcode_img[i,j] == 0:
black_bar_width = black_bar_width +1

#ensure last bar is gotten if there was one
if white_bar_width > 0:
barcode_row.append(["white", white_bar_width])
white_bar_width = 0

elif possible_barcode_img[i,j] > 0:
white_bar_width = white_bar_width +1

#ensure last bar is gotten if there was one
if black_bar_width > 0:
barcode_row.append(["black", black_bar_width])
black_bar_width = 0

#ensure last bar is gotten since a row just finished
if white_bar_width > 0:
barcode_row.append(["white", white_bar_width])

elif black_bar_width > 0:
barcode_row.append(["black", black_bar_width])

barcode_rows.append(barcode_row)


Print row 50 of the picture in the question print(barcode_rows[50]):

[['black', 3], ['white', 7], ['black', 4], ['white', 6], ['black', 4], ['white', 6], ['black', 13], ['white', 5], ['black', 4], ['white', 15], ['black', 4], ['white', 5], ['black', 5], ['white', 5], ['black', 13], ['white', 15], ['black', 13], ['white', 5], ['black', 13], ['white', 6], ['black', 3], ['white', 15], ['black', 5], ['white', 4], ['black', 4], ['white', 14], ['black', 13], ['white', 6], ['black', 4], ['white', 14], ['black', 13], ['white', 14], ['black', 5], ['white', 5], ['black', 4], ['white', 5], ['black', 4], ['white', 14], ['black', 4], ['white', 5], ['black', 4], ['white', 5], ['black', 13], ['white', 14], ['black', 13], ['white', 5], ['black', 14], ['white', 4], ['black', 5], ['white', 4]]


50 bars found as in the picture, ready for decoding.

This has quite an effect on fps when doing it with video. I know that I don't have to loop through the entire image, I will have it send to a decoder after each row of pixels and end the loop if successful.

However I'm hoping there's a more optimized way to do this than using the Python loops on each individual pixel because I don't think the above will be fast enough for my needs.

• With code bar type you use? I think it is Interleaved 2 of 5... – Adam Silenko Oct 21 '18 at 19:44
• Yes that is correct. – Trevor Oct 21 '18 at 19:48

• Yeah I was going to figure the wide or narrow width after I got the numbers. My concern was that the existing code was slow. I realized I don't have to reinvent the wheel and decided to try using a decode library. from pyzbar.pyzbar import decode from pyzbar.pyzbar import ZBarSymbol decode(possible_barcode_img, symbols=[ZBarSymbol.I25]) It seems to work well for what I need. – Trevor Oct 21 '18 at 21:10