[英]Efficient way to threshold image array and render - Python / NumPy / OpenCV
我有一台相机正在将图像数据发送到我的电脑。 从那里我的 python 脚本将 8 位颜色信息(黑色和白色;范围从 0 - 黑色 - 到 255 - 白色)放入一个 numpy 数组中。 该阵列是二维的,第一维高达 384,第二维高达 288 使用 openCV 窗口显示它效果很好,实时视频超过 24fps。
我现在的目标是操纵图像,以便实时视频将任何低于 200 的颜色值显示为 0(全黑),将任何高于 200 的颜色值显示为 255(全白)。 然而,我的代码现在只给我大约 3fps。
我的代码正在执行以下操作:
for
循环以遍历 x 值for
循环中,使用 y 值遍历第二个for
循环if
子句使颜色值为 0 或 255这是代码中的决定性部分:
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)
我在这里读到for
循环比while
循环更快,但它并没有显着提高代码的速度,这就是为什么我假设重写processedImage
花费的时间太长。
有没有办法让整个过程更快?
感谢您的任何回答!
试试这个:
frame[frame > 200] = 255
frame[frame <= 200] = 0
cv2.imshow("LiveVideo", frame)
np.where()
也可以使用:
processed_frame = np.where(frame >= 200, 255, 0)
例如
>>> im = (np.random.rand(5, 5) * 255).round()
>>> im
array([[ 45., 92., 74., 207., 211.],
[206., 184., 31., 117., 119.],
[ 88., 82., 203., 34., 5.],
[157., 99., 154., 251., 54.],
[160., 177., 14., 206., 234.]])
>>> np.where(im >= 200, 255, 0)
array([[ 0, 0, 0, 255, 255],
[255, 0, 0, 0, 0],
[ 0, 0, 255, 0, 0],
[ 0, 0, 0, 255, 0],
[ 0, 0, 0, 255, 255]])
>>>
继续使用 NumPy,似乎最快的是 -
(frame>200)*np.uint8(255)
因为,您已经在使用 OpenCV,更快的方法是使用cv2.threshold
-
cv2.threshold(frame,200,255,cv2.THRESH_BINARY)[1]
样本运行以验证结果并获取1024X1024
图像的时间 -
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
与其他解决方案对相同数据的计时 -
# @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)
带有cv2.threshold
的 OpenCV 版本似乎是其他版本中最快的。
使用 Seb 的解决方案是一个很大的改进,但似乎使用numpy.where
更快:
%%timeit
frame1 = frame.copy()
frame1[frame1 > 200] = 255
frame1[frame1 <= 200] = 0
974 µs ± 19.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
对比
%%timeit
frame2 = frame.copy()
frame2 = np.where(frame2 > 200, 255, 0)
385 µs ± 7.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> np.alltrue(frame1 == frame2)
True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.