来自网络摄像头的实时RGB图

2024-04-26 13:44:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要创建一个图形,从视频实时显示RGB。我知道我必须捕获一帧并在图形和x轴绘图时间中绘制3个通道。但是我有一个错误。网络摄像头正常打开,屏幕上显示空白图形。有人知道我该如何写这段代码吗

import cv2
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation

capture = cv2.VideoCapture(0)
ret, frame = capture.read()

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)


while True:
    ret, frame = capture.read()
    cv2.imshow('Frame', frame)

    if not ret:
        break


    def animate(i):

        b, g, r = cv2.split(frame)
        xs = []
        ys = []
        for line in b:
            if len(line) > 1:
                x, y = line.split(',') #Getting the error: 'numpy.ndarray has no attribute split'.
                xs.append(x)
                ys.append(y)
        ax1.clear()
        ax1.plot(xs, ys)


    ani = FuncAnimation(fig, animate, interval=1000)
    plt.show()

    keyval = cv2.waitKey(1) & 0xFF

    if keyval == ord('q'):
        break


capture.release()
cv2.destroyAllWindows()

    
    

Tags: import图形ifmatplotliblinefigpltcv2
1条回答
网友
1楼 · 发布于 2024-04-26 13:44:58

您希望在接收网络摄像头帧时显示交互式图形

    1. 您可以使用plt.ion()ion()方法在接收输入时更新图形
    • 您可能会问为什么不使用FuncAnimation?

      • 据我所知FuncAnimation方法不是为while循环设计的FuncAnimation对于预先计算的帧很有用。在这里你可以看到example1example2
    1. 如何获得每秒的帧
    • 我们可以计算fps(每秒帧数)值。例如,如果fps值为5,则5帧持续时间等于1秒

    • 我们可以使用一个变量对帧进行计数,并检查该变量是否等于fps。然后我们添加帧

      • if frame_count % fps == 0:
            b, g, r = cv2.split(frame)
        
            line = [line for line in zip(b, g, r) if len(line)]
        
            xs.append(second)
            blue.append(np.mean(line[0]))
            green.append(np.mean(line[1]))
            red.append(np.mean(line[2]))
        
      • 你可能会问为什么不使用time.time for calculating the seconds?

      • 我认为使用fps比使用time.time更可靠。我想保证每秒钟都能得到帧

结果:

enter image description here

我已从命令提示符处获得结果。如果您调试它,您可能会得到多个图像,而不是一个更新的图像

更新-1


如果要分离通道,可以将每个计算的方差乘以不同的系数:

blue.append(np.var(line[0])*0.02)
green.append(np.var(line[1])*0.03)
red.append(np.var(line[2])*0.04)

结果:

enter image description here

  • 您也可以使用np.mean
blue.append(np.mean(line[0])*0.02)
green.append(np.mean(line[1])*0.03)
red.append(np.mean(line[2])*0.04)

结果:

enter image description here

更新-2


如果要将输出数据写入excel,可以使用^{}

您可以安装:


  • pip环境:pip install xlsxwriter
  • Python环境:conda install -c anaconda xlsxwriter

三个步骤:


  • 步骤1:创建工作表:

    • book = Workbook('Channel.xlsx')
      sheet = book.add_worksheet()
      
  • 步骤2:初始化rowcolumn变量:

    • row = 0
      col = 0
      
  • 第三步:写

    • for s, b, g, r in zip(xs, blue, green, red):
          sheet.write(row, col, s)
          sheet.write(row + 1, col, b)
          sheet.write(row + 2, col, g)
          sheet.write(row + 3, col, r)
          col += 1
      

输出:

enter image description here

更新-3


    1. 时间

  • 在以前的更新中,错误的fps = cv2.CAP_PROP_FPS。正确的用法是fps = capture.get(cv2.CAP_PROP_FPS)。现在我们正在获取网络摄像头的fps

    1. 加速

  • 我们使用redgreenbluexs列表结构来存储显示和写入excel文件的帧和秒数

  • 随着帧数据的增加,列表结构成为实时处理的负担。因此,一种解决方案是划分显示和写入操作

  • 用于显示:b_frameg_framer_frame、和s_frame

  • 要写入excel,请使用bluegreenredxs

  • 主要优点是现在我们可以减少显示帧的存储空间。因为我们存储在bluegreenredxs

  • 例如:两秒钟后删除第一帧

    del b_frame[0]
    del g_frame[0]
    del r_frame[0]
    del s_frame[0]
    
  • 因为b_frameg_framer_frames_frame不再包含所有帧。系统加速

更新-4


VideoCapture在读取、解码和返回下一帧时阻塞应用程序。很可能这就是相机冻结的原因

一个选项是使用VideoStream,它通过使用队列结构同时处理读取、解码和返回操作

安装imutils


  • 对于pip:pip install imutils
  • 对于Python:conda install -c conda-forge imutils

例如:


from imutils.video import VideoStream

vs = VideoStream().start()

while True:
    frame = vs.read()
    
    if frame is None:
        break
     
    .
    .


vs.stop()

我测试了VideoStream,在应用过程中没有冻结帧或暂停

代码:


import cv2
import numpy as np
import matplotlib.pyplot as plt

from imutils.video import VideoStream
from xlsxwriter import Workbook

fig = plt.figure()

plt.ion()  # Set interactive mode on

xs = []
blue = []
red = []
green = []

b_frame = []
g_frame = []
r_frame = []
s_frame = []

# We will be using Video-capture to get the fps value.
capture = cv2.VideoCapture(0)
fps = capture.get(cv2.CAP_PROP_FPS)
capture.release()

# New module: VideoStream
vs = VideoStream().start()

frame_count = 0
second = 1

is_new_frame = False

while True:
    frame = vs.read()

    if frame is None:
        break

    if frame_count % int(fps) == 0:
        b, g, r = cv2.split(frame)

        is_new_frame = True  # New frame has come

        line = [line for line in zip(b, g, r) if len(line)]

        s_frame.append(second)
        b_frame.append(np.mean(line[0]) * 0.02)
        g_frame.append(np.mean(line[1]) * 0.03)
        r_frame.append(np.mean(line[2]) * 0.04)

        plt.plot(s_frame, b_frame, 'b', label='blue', lw=7)
        plt.plot(s_frame, g_frame, 'g', label='green', lw=4)
        plt.plot(s_frame, r_frame, 'r', label='red')
        plt.xlabel('seconds')
        plt.ylabel('mean')
        if frame_count == 0:
            plt.legend()
        plt.show()

        second += 1

    elif second > 2:

        if is_new_frame:

            if second == 3:
                blue.extend(b_frame)
                green.extend(g_frame)
                red.extend(r_frame)
                xs.extend(s_frame)
            else:
                blue.append(b_frame[len(b_frame)-1])
                green.append(g_frame[len(g_frame)-1])
                red.append(r_frame[len(r_frame)-1])
                xs.append(s_frame[len(s_frame)-1])

            del b_frame[0]
            del g_frame[0]
            del r_frame[0]
            del s_frame[0]

            is_new_frame = False  # we added the new frame to our list structure

    cv2.imshow('Frame', frame)

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

    frame_count += 1

cv2.destroyAllWindows()
capture.release()
vs.stop()

book = Workbook('Channel.xlsx')
sheet = book.add_worksheet()

row = 0
col = 0

sheet.write(row, col, 'Seconds')
sheet.write(row + 1, col, 'Blue mean')
sheet.write(row + 2, col, 'Green mean')
sheet.write(row + 3, col, 'Red mean')

col += 1

for s, b, g, r in zip(xs, blue, green, red):
    sheet.write(row, col, s)
    sheet.write(row + 1, col, b)
    sheet.write(row + 2, col, g)
    sheet.write(row + 3, col, r)
    col += 1

book.close()

相关问题 更多 >