使用pyhon-opencv生成视频帧

使用pyhon-opencv生成视频帧

任务

从摄像机捕获视频,获取视频的每一帧,并将其保存。链接: link

  • 帧:视频其实是一系列图像,当一组图像播放得非常快时,我们的眼睛无法跟上图像的变化,在我们的大脑中,我们在图像中看到的物体似乎在移动,这被称为视频。组成视频的单个图像称为帧。当你非常快地浏览所有帧时,你就会得到视频。
  • 每秒帧数 (fps):每秒帧数或 fps,是指视频在一秒钟内播放的帧数。当我们说视频以 24fps 的速度播放时,这意味着播放该视频时,一秒钟内显示 24 帧。这意味着如果一段视频长 1 分钟,并以 24fps 播放,则视频播放器总共会播放 1440 帧!这就是视频文件比照片大的真正原因。

解决办法

  • 导入opencv包,使用import cv2.
import cv2
  • 使用cv2的VideoCapture()方法从设备的摄像头读取视频,并将其存储在名为cap的变量中,通常一个设备的camera index是0,如下:
cap = cv2.VideoCapture(0)
  • 指定视频的四字符代码,四字符码通常缩写为fourcc,是一个4字节的序列,用于独立标示视频数据流格式。通常XVID代码最适合带有.mp4或.avi扩展名的视频,在此将定义fourcc代码并将其存储在名为fourcc的变量中。
fourcc = cv2.VideoWriter_fourcc(*'XVID')
  • 将设备摄像头拍摄的视频保存在一个名为output的的文件中,后缀为.avi,将文件名存储在名为file_name的变量中,还创建一个名为save并存储初始值‘frame1’的变量,创建一个名为c的变量,其初始值为2。稍后将会用变量save和c来保存从视频中获得的帧。
file_name = 'output'
save = 'frame 1'
c = 2
  • 使用VideoWriter()方法,显示摄像头看到的内容,将表达式存储在一个名为output的变量中,需要传递文件名、fourcc、每秒显示的帧数和视频捕获窗口的大小(通常为640x480),这里每秒生成24帧。
output = cv2.VideoWriter((file_name+, '.avi'), fourcc, 24.0, (640, 480))
  • 读取相机正在拍摄的视频,使用迭代一个循环来生成帧,知道打开相机,使用Opencv的函数isOpened(),帮助我们检查相机是否打开。
while cap.isOpened():
  • 接下来步骤都在while循环里,从设备的相机读取每一帧,需要2个变量res和frame。使用read()方法读取每一帧,获取的图像存储在frame中,状态存储在res中,变量res中存储True或Flase,指示帧是否已成功读取。
res, frame = cap.read()
  • 设置条件语句,如果变量res不是True,那么显示一条错误消息并从循环中中断。如果没有获得帧,循环内的代码将不会被执行,循环之后的那一行将被执行。
if not res:
       print('Frame Cannot Be Received')
       break
  • 翻转帧,因为相机通常会读取横向倒置的图像,类似于镜子中的图像,使用flip()方法翻转帧,该方法以图像和以度为单位的翻转角度作为参数。
frame = cv2.flip(frame, 90)
  • 使用输出的write()方法和imshow()方法显示帧。其中字符串‘Frame’表示显示视频的窗口的名称是‘Frame’。
output.write(frame)
cv2.imshow('Frame', frame)
  • 将每一帧保存在将要保存python文件的文件夹中,使用imwrite()方法,将帧以.png格式保存,由于需要保存多帧,实现逻辑如下:
cv2.imwrite(save+'.png', frame)
save = 'Frame' + str(c)
c = c+1

save的初始值为‘Frame 1’,第一帧存储为’Frame 1’。现在save的值变为‘Frame 2’,因为我们将c的值(最初等于2)与‘Frame’连接起来,然后将c的值加1,确保在下一次迭代中,save的值为‘Frame 2’,保存的图像为‘Frame 2.png’,c的新值为3,一直持续到按下字母‘x’在键盘上终止循环。

  • 为了关闭视频窗口,需要检查键盘上是否按下了字母‘x’,通过检查当1作为参数传递时opencv的waitKey()函数的返回值是否等于当字符‘x’作为参数传递时的ord()函数的返回值来实现,这意味着当按下’x’时控件将跳出循环。实际上意味着如果在1毫秒内没有收到帧,或者如果按下字母’x’,则循环结束。
if cv2.waitKey(1) == ord('x'):
          break
  • 程序的主逻辑现已完成,跳出循环并通过键入以下代码关闭所有内容。release()方法关闭所有打开的对象(本例中为cap和output),destroyAllWindows()销毁或关闭所有已创建的窗口,这很重要,因为如果从终端运行代码,那么有时所有窗口都不会关闭,除非退出python代码。
cap.release()
output.release()
cv2.destroyAllWindows()

以上就是生成相机捕捉到的帧,以下时完整代码。

// An highlighted bloc
import cv2

# Accessing the camera 
cap = cv2.VideoCapture(0)

# Defining the codec and creating the VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
file_name = 'output'
output = cv.VideoWriter((file_name+'.avi'), fourcc, 24.0, (640,  480))

# Defining the variables save and c
save = 'Frame1'
c = 2;
while cap.isOpened():

    res, frame = cap.read()
    if not res:
        print("Frame Cannot Be Received")
        break
    
    # Flipping the frame horizontally to get correct orientation
    frame = cv2.flip(frame, 90)

    # Displaying the current frame
    output.write(frame)
    cv2.imshow('Frame', frame)

    # Saving the frames
    cv2.imwrite(save+'.png', frame )
    save = "Frame"+ str(c)
    c = c+1

    # If no input is received for 1ms, or if the key 'x' is pressed, interpreter goes outside of the loop
    if cv2.waitKey(1) == ord('x'):
        break

# Releasing everything after coming out of loop
cap.release()
output.release()
cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值