I have a histogram of an image, basically a histogram of an image is a graph that show how many times a pixel that is converted to a 0-255 value occurs in an image. With Y axis number of occurance and X axis the pixel value.
And what i need is the total number of pixel value from 75-125
image= cv2.imread('grade_0.jpg')
listOfNumbers = image.ravel() #generates the long list of 0-255 values from the image) type numpy.ndarray
Right now my code does this by converting the numpy.ndarray to a list and counting each values one by one
start = time.time()
numberlist = list(list0fNumbers)
sum = 0
for x in range(75,125):
sum = sum + numberlist.count(x)
end = time.time()
print('Sum: ' + str(sum))
print('Execution time_ms: ' + str((end-start) * 10**3))
Result :
Sum: 57111
Execution time_ms: 13492.571830749512
I would be doing something like this for thousands of images and with just this image alone it took 13 seconds. It is just too ineffecient. Any recommendation on how to speed it up to about less than 10ms? I wont be just getting the sum of 75-125, but other ranges as well, e.g. 0-80,75-125,120-220,210-255. Assuming those take 13seconds too to process a single 256x256 pixel image takes about 60 seconds which i would say is a bit long even for a slow computer.
Here is a sample image:


You can use simple boolean operators:
Or, as suggested by @jared:
Timing of the count:
Edit: I realize you want to process several bins, this could be done using:
But this will read again the image's data for each bin.
In this case,
bincount, as suggested by @Andrej, could indeed preferred since it only counts the pixels once:The timings will depends on the size of the image and the number of bins. For small images, counting again might be more efficient, while for large ones
bincountcould be better (but, surprisingly, not always).256 x 256
512 x 512:
1024 x 1024:
2048 x 2048: