python - 使用OpenCV-Python,如何有效地同时使用Python列表和Numpy数组?

标签 python algorithm numpy opencv

我正在尝试重现我在美术馆看到的实时视频狭缝扫描效果。

该程序使用opencv-python保留来自网络摄像头的最后480帧的缓冲区,然后将每帧的像素行合并为一个图像。我编写了产生所需效果的代码,但运行速度比我想要的慢。如何以最有效的方式一起使用python列表和numpy数组来优化算法?

请注意,填满缓冲区大约需要10秒钟,然后才能看到视频效果。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# originally tried to use numpy to store the buffer
#buffer = np.zeros(shape=(480,480,640,3),dtype=np.uint8) 
buffer = []
slices = []
f2 = np.zeros(shape=(480,640,3),dtype=np.uint8)

display = False
rows = np.arange(480)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    frame = cv2.flip(frame, -1) # flipping the frame to get the scan lines to move downward

    # originally I tried to make the buffer like this but get a memory error    
    #buffer = np.roll(buffer, -1, axis=0)
    #buffer[-1] = frame

    # using a list of numpy arrays seems to be more efficient for storing the buffer   
    buffer.append(frame)
    if(len(buffer) > 480):
        buffer = buffer[1:]

        # using a list to combine a row of pixels from each frame
        # could this be optimized with numpy arrays?
        for i in range(len(buffer)):
            slices.append(buffer[i][i])

        # convert each row to a numpy array to store final frame for display
        f2[rows] = np.array(slices[::-1])
        slices.clear()
        cv2.imshow('frame', f2)

    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

我的另一个想法是重写代码以使用更少的缓冲帧,并将每个帧中的几行合并在一起,但是我想尽可能尝试使用全分辨率视频优化代码。

最佳答案

我实现了设置 slice 大小以加快处理速度。它使图像更具阻挡性,但是没关系。我喜欢 slice 大小为8。我还实现了一些颜色映射,以达到有趣的目的。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

buffer = []
slices = []
height = 480
width = 640
sliceSize = 8

cap.set(4, height)
cap.set(3, width)
f2 = np.zeros(shape=(height,width,3),dtype=np.uint8)

display = False
rows = np.arange(int(height/2))

cv2.namedWindow('funnymirror', cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty('funnymirror', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

c = 0
cmap = 9
cycle = True

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    frame = cv2.flip(frame, 0) # flipping the frame to get the scan lines to move downward

    cframe = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)  # BGR color to gray level

    if cycle:
        c= (c +1) % 255
    cframe+= c
    cframe = cv2.applyColorMap(cframe, cmap)

    frame = cv2.addWeighted(frame, 0.7, cframe, 0.3, 0)

    # using a list of numpy arrays seems to be more efficient for storing the buffer   
    buffer.append(frame)
    if(len(buffer) > int(height/sliceSize)):
        buffer = buffer[1:]

        # using a list to combine a row(s) of pixels from each frame
        for i in range(int(height/sliceSize)):
            for j in range(sliceSize):
                slices = buffer[i][i*sliceSize+j]
                f2[i*sliceSize+j] = np.array(slices)

        f2 = cv2.flip(f2, -1)
        cv2.imshow('funnymirror', f2)


    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'): # press q to quit
        break
    # for testing purposes only change slice size on the fly
    elif key == 91: # press [ to reduces slices
        sliceSize = int(sliceSize/2)
        if sliceSize < 1:
            sliceSize = 1
        print(f'sliceSize: {sliceSize}')
    elif key == 93: # press ] to increase slices
        if sliceSize < 64:
            sliceSize*=2
        print(f'sliceSize: {sliceSize}')
    # press 1, 2, 3, or 4 to change color map
    elif key == 49: # press 1
        cmap = 2
    elif key == 50: # press 2
        cmap = 4
    elif key == 51: # press 3
        cmap = 9
    elif key == 52: #press 4
        cmap = 7
    elif key == 61: # press = to toggle cycling color map
        cycle= not cycle
        print(cycle)
    elif key!=255:
        print(key)

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

关于python - 使用OpenCV-Python,如何有效地同时使用Python列表和Numpy数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57995763/

相关文章:

algorithm - google go 中的可重用优先级队列实现

python - 如何使用 numpy 将 nan 添加到数组的末尾

python - 对 Polyval 的输出感到困惑

python - NN 的 DNA 数据输入,一种热编码

c - 如何制作通用链表

algorithm - 哪种算法更快 O(N) 或 O(2N)?

python - Numpy reshape - 自动填充或移除

python - NumPy 广播 : Calculating sum of squared differences between two arrays

Python - 字符串中的 xb

python - 在Biopython PDB模块中获取残基编号和残基名称