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

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

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

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

    elif black_bar_width &gt; 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.
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: