You may not need to delve into scipy or opencv. The following solution uses pil and numpy:
from PIL import Image
import numpy
#define a greyscale threshold which we will use later
threshold = 230
#open image as greyscale with PIL and convert to numpy array
with Image.open('your_image.png').convert('L') as img:
arr_gry = numpy.array(img)
#create 1-D array of max column values
colmax = numpy.zeros(arr_gry.shape[0])
colmax = numpy.min(arr, axis=0)
#analyse the bands array and define start and end of each band
band_limits = {}
band_list = []
prev_column = 0
for i,column in enumerate(colmax):
if column > threshold and ('start' not in band_limits):
band_limits['start'] = i
if column <=threshold and prev_column > threshold:
band_limits['end'] = i
band_list.append(band_limits)
band_limits = {}
prev_column = column
###The following is for illustration purposes only
#convert to RGB array
arr_clr = numpy.stack([arr_gry,arr_gry,arr_gry], axis=2)
#Colour the bands and mid points
for band in band_list:
arr_clr[:,band['start']:band['end']] = [255,0,0]
arr_clr[:,(band['start']+band['end'])//2] = [0,0,255]
#Convert array to Image
out = Image.fromarray(arr_clr)
out.show()
This produces the following image
Obviously you can use opencv if desired to open, view and save the images. But in this example all the processing is done in numpy so pil is more than capable.