4
\$\begingroup\$

Example image:

barcode

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:
            #add to count
            black_bar_width = black_bar_width +1

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

        elif possible_barcode_img[i,j] > 0:
            #add to width
            white_bar_width = white_bar_width +1

            #ensure last bar is gotten if there was one
            if black_bar_width > 0:
                #add bar to row
                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:
        #add bar to row
        barcode_row.append(["white", white_bar_width])

    elif black_bar_width > 0:
        #add bar to row
        barcode_row.append(["black", black_bar_width])

    #add entire row to rows
    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.

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

You don't need a number of pixels, you need to detect narrow bars and wide bars. Use first black and white bar width as a pattern with 15% margin for next bars. The wide bar has 2.0 to 3.0 times the width of a narrow bar. Try to detect start or stop code at the begin of selected line, if it is correct, then read the rest of the line... After every 5 black+white bars (in the right direction) you can decode two digits, black bars define 1st and white 2nd ... Bars have weights: 1st: 1, 2nd: 2, 3th: 4, 4th: 7: 5th 0. Add weights of every wide bars, and you get the digit (11 = 0). If 3 lines give you the same result, this is probably your code...

EDIT:

You can see the algorithm on your code: enter image description here

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Trevor Oct 21 '18 at 21:10
  • \$\begingroup\$ You got it. The "?" is the edge of a cyan marker I used to help locate the barcode and unintentionally got in there. also typo, 1+7 is actually 8. The barcode reads "12345678". \$\endgroup\$ – Trevor Oct 21 '18 at 22:27
  • \$\begingroup\$ Image corrected... \$\endgroup\$ – Adam Silenko Oct 21 '18 at 23:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.