I have a camera that is sending the image data to my computer. From there my python script puts the 8bit color info (black and white; ranging from 0 - black - to 255 - white) into a numpy array. The array is 2D, first dimension up to 384 and second dimensions up to 288 Displaying this with a openCV window works great and the live video is more than 24fps.
My aim now is to manipulate the image, so that the live video displays any color value below 200 as 0 (completely black) and any color value above 200 as 255 (completely white). However, my code right now only gives me about 3fps.
My code is doing the following:
for loop to iterate through the x valuesfor loop iterate through the second for loop with the y valuesif clause make the color value 0 or 255This is the decisive part in the code:
processedImage = frame
i = 0
for i in range(0, displayedWidth):
ii = 0
for ii in range(0, displayedHeight):
if frame[ii, i] > 200:
processedImage[ii, i] = 255
else:
processedImage[ii, i] = 0
cv2.imshow("LiveVideo", processedImage)
I read here that for loops are faster than while loops, but it didn't improve the code's speed significantly, which is why I assume the rewriting of the processedImage takes too long.
Is there a way to make the whole process faster?
Thanks for any answers!
Try this:
frame[frame > 200] = 255
frame[frame <= 200] = 0
cv2.imshow("LiveVideo", frame)
Staying with NumPy, it seems fastest would be -
(frame>200)*np.uint8(255)
Since, you are already using OpenCV, a faster way would be with cv2.threshold -
cv2.threshold(frame,200,255,cv2.THRESH_BINARY)[1]
Sample run to verify results and get timings on 1024X1024 image -
In [2]: np.random.seed(0)
...: frame = np.random.randint(0,256,(1024,1024)).astype(np.uint8)
In [3]: %timeit (frame>200)*np.uint8(255)
253 µs ± 13.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [4]: %timeit cv2.threshold(frame,200,255,cv2.THRESH_BINARY)[1]
58.2 µs ± 437 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [7]: out1 = (frame>200)*np.uint8(255)
In [8]: out2 = cv2.threshold(frame,200,255,cv2.THRESH_BINARY)[1]
In [9]: np.allclose(out1, out2)
Out[9]: True
Timings with other solutions on same data -
# @AKX's soln
In [10]: %timeit np.where(frame >= 200, 255, 0)
3.73 ms ± 22.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# @Seb's soln
In [11]: %%timeit
...: frame[frame > 200] = 255
...: frame[frame <= 200] = 0
10.2 ms ± 15.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
OpenCV's version with cv2.threshold seems the fastest by a big margin among others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With