【问题标题】:It is taking too much time to process frames while doing pixel by pixel operation of video frames在对视频帧进行逐像素操作时处理帧需要太多时间
【发布时间】:2020-06-04 16:48:13
【问题描述】:
import cv2
import numpy as np

cap = cv2.VideoCapture(0)

def threshold_slow(image):
    h = image.shape[0]
    w = image.shape[1]
    for x in range(0, w):
        for y in range(0, h):
            k = np.array(image[x, y])
            print(k)

def video():
    while True:
        ret,frame = cap.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        threshold_slow(frame)
        cv2.imshow('frame',frame)
        key = cv2.waitKey(25)
        if key == ord('q'):
            break
if __name__ == '__main__':
    video()
cap.release()
cv2.destroyAllWindows()

我已经做了我能做的几乎所有事情,但我仍然无法重新爱上它。任何有想法的人请帮助一些代码。当我将 print 放在 for 循环之外时,它工作正常。但后来我没有得到图像中每个像素的值。

【问题讨论】:

  • 如果for 循环中的逐像素操作太慢,不要这样做!使用cv2.threshold()
  • 那么,如果我有这样的情况; k = image[y, x] 如果 140
  • 我添加了一个答案,展示了如何快速做到这一点。

标签: python image-processing pixel opencv3.0


【解决方案1】:

您真的,真的应该避免在 Python 中对图像进行for 循环和“逐像素”操作。尝试使用 OpenCV 矢量化例程,例如 cv2.threshold(),否则,使用矢量化 Numpy 例程。

您在 cmets 中提到您想要这样做:

h = im.shape[0] 
w = im.shape[1] 
for x in range(0, w): 
    for y in range(0, h): 
        if im[y,x]>140 and im[y,x]<160: 
            im[y,x]=255 

这在我的机器上需要 487 毫秒。如果你像这样使用 Numpy,它需要 56 微秒。即快 9,000 倍。

im[ np.logical_and(im>140, im<160) ] = 255

这将使您的代码看起来更像这样 - 未经测试:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

def video():
    while True:
        ret,frame = cap.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        frame[ np.logical_and(frame>140, frame<160) ] = 255
        cv2.imshow('frame',frame)
        key = cv2.waitKey(25)
        if key == ord('q'):
            break
if __name__ == '__main__':
    video()
cap.release()
cv2.destroyAllWindows()

您还可以使用 OpenCV inRange() 在灰度图像中选择一系列灰度,如下所示:

mask = cv2.inRange(im, 140, 160)

然后您可以将其应用于您的图像:

frame[~mask] = 255

但我认为这比较慢。

【讨论】:

  • 首先,谢谢你,马克,你的评论,它帮助我进一步提高了速度。但是当我使用 NumPy 时,它会延迟太多,您能否在 for 循环中向我展示与 NumPy 相同的情况。
  • 没有for 循环!将带有 Numpy 内容的行放在您的主循环中 - 我稍后会将其添加到我的答案中。
  • 马克太棒了,非常感谢。
  • 谢谢你,马克,我得到了实时
【解决方案2】:

print 不可避免地很慢(与其他代码相比)。假设图像为 256x256,您的代码将打印 65536 个值。根据格式(我不熟悉 OpenCV,但假设每个像素 1 个字节),每个像素的输出范围为 2 到 4 个字节(将 8 位无符号字节转换为文本 + 行尾),所以128kB-320kB,然后您的终端需要滚动。

您最好的办法是限制您尝试打印的像素区域:即,使用适当的参数为您的范围调用指定一个适当的小区域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 2015-08-28
    • 2015-06-12
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2017-03-29
    相关资源
    最近更新 更多