简体   繁体   English

阈值图像数组和渲染的有效方法 - Python / NumPy / OpenCV

[英]Efficient way to threshold image array and render - Python / NumPy / OpenCV

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.从那里我的 python 脚本将 8 位颜色信息(黑色和白色;范围从 0 - 黑色 - 到 255 - 白色)放入一个 numpy 数组中。 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.该阵列是二维的,第一维高达 384,第二维高达 288 使用 openCV 窗口显示它效果很好,实时视频超过 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).我现在的目标是操纵图像,以便实时视频将任何低于 200 的颜色值显示为 0(全黑),将任何高于 200 的颜色值显示为 255(全白)。 However, my code right now only gives me about 3fps.然而,我的代码现在只给我大约 3fps。

My code is doing the following:我的代码正在执行以下操作:

  • save the image that comes from the camera in a numpy array将来自相机的图像保存在 numpy 数组中
  • open the first for loop to iterate through the x values打开第一个for循环以遍历 x 值
  • in that first for loop iterate through the second for loop with the y values在第一个for循环中,使用 y 值遍历第二个for循环
  • check each color value for every pixel and check if it is above 200 or not检查每个像素的每个颜色值并检查它是否高于 200
  • depending on the if clause make the color value 0 or 255根据if子句使颜色值为 0 或 255
  • display the new image显示新图像

This 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.在这里读到for循环比while循环更快,但它并没有显着提高代码的速度,这就是为什么我假设重写processedImage花费的时间太长。

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)

np.where() can be used too: np.where()也可以使用:

processed_frame = np.where(frame >= 200, 255, 0)

eg例如

>>> 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]])
>>>

Staying with NumPy, it seems fastest would be -继续使用 NumPy,似乎最快的是 -

(frame>200)*np.uint8(255)

Since, you are already using OpenCV, a faster way would be with cv2.threshold -因为,您已经在使用 OpenCV,更快的方法是使用cv2.threshold -

cv2.threshold(frame,200,255,cv2.THRESH_BINARY)[1]

Sample run to verify results and get timings on 1024X1024 image -样本运行以验证结果并获取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

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.带有cv2.threshold的 OpenCV 版本似乎是其他版本中最快的。

Using Seb's solution is a big improvement but it seems that using numpy.where is even faster:使用 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)

vs.对比

%%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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM