用opencv-python捕捉并保存usb摄像头拍摄的视频

背景:为了做一个滴水检测的demo,自己配置了滴水装置的实验环境,需要用摄像头实时拍摄滴水画面,进行检测,生成滴水位置的bbox,保存检测后的视频。opencv可以实时捕捉usb摄像头拍摄的画面,因此稍微学习了一下

用摄像机捕捉视频

通常,我们必须用摄像机捕捉直播。OpenCV提供了一个非常简单的接口来实现这一点。让我们从相机捕捉视频(我使用的是usb摄像头),将其转换成灰度视频并显示出来。

VideoCapture对象cap

要捕获视频,需要创建VideoCapture的对象cap。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像头的数字。通常电脑内置摄像头的设备索引是0,外接的usb摄像头是1,以此类推。之后就可以逐帧捕获usb摄像头拍摄的视频。任务的最后,要release VideoCapture的对象cap。

VideoWriter对象out

要保存视频,我们需要创建一个VideoWriter对象out。传入的参数包括:输出文件名(例如:output.avi)、FourCC代码(详见下一段)。然后每秒帧数(fps)、帧大小。最后一个是isColor的flag,如果为True,表示输入视频编码器的是color frame,否则使用greyscale frame。

FourCC是一个4字节的代码,用来指定视频的编码解码器。对于XVID格式的编码解码器,传递cv.VideoWriter_fourcc('M','J','P','G')cv.VideoWriter_fourcc(*'MJPG')。一般我们使用XVID格式的编码解码器,对应的视频后缀是.avi

代码流程

有时,cap可能没有初始化。我们可以通过cap.isOpened()方法检查它是否被初始化,如果是False,使用cap.open()打开它。

cap.get(propId)方法访问本视频的一些属性,比如fps和分辨率,其中propId可以是一个从0到18的数字,每个数字表示视频的一个属性,也可以直接是属性的名称,比如cv2.CAP_PROP_FPS表示帧速率。

cap.set(propId, value)可以修改视频的属性,比如帧速、分辨率,value是你想要的新值。

import cv2
import numpy as np

# 创建VideoCapture的对象cap。传入的参数可以是设备索引1,也可以是自己本地的视频
cap = cv2.VideoCapture(1)
video_path = 'C:\\Users\\HP\\Desktop\\Accusefive.mp4'
#cap = cv2.VideoCapture(video_path)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
fps = cap.get(cv2.CAP_PROP_FPS) #获取视频的帧率

# 生成fourcc code
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# 需要保存,创建VideoWriter对象out
out = cv2.VideoWriter('C:\\Users\\HP\\Desktop\\vv.avi', fourcc, 20.0, (640, 480))

# 确保cap打开了
if not cap.isOpened():
    print("cap is not opened, open the cap")
    cap.open()
    exit()
else:
    print('cap is opened, read the video stream...')

# 使用一个While循环不间断地对usb摄像头进行读取,一直到遇到键盘终止事件时break掉
while cap.isOpened():
	# 使用cap.read()从摄像头读取一帧
    ret, frame = cap.read()
    # 用read()返回的布尔值ret判断有没有正确读取到
    if not ret:
        print(' cannot receive frames(stream end?). Exiting...')
        break
    # frame = cv.flip()
	
	# 写入对象out调用write()写入这一帧
    out.write(frame)

	# 同时,把我们写入视频的这一帧显示出来,这样能实时看到我们处理和保存的内容
    cv2.imshow('frame', frame)
    # 等待1ms按键事件,如果未在规定时间按键,返回-1.如果在规定时间按键,返回所按键的ascII码值
    if cv2.waitKey(1) == ord('q'):
        break

# release你的cap对象和out对象
cap.release()
out.release()
cv2.destroyAllWindows() # 销毁所有打开的HighGUI窗口。

cap.read() 实时地从摄像机读取一个视频帧,read()返回一个布尔值和读取的帧,如果视频帧正确地读取了,该布尔值为True,否则为False。因此我们可以通过判断这个布尔值确定if the frame is received correctly.

out.write(frame) 把当前的帧frame写入目的视频中,VideoWriter对象out调用write()方法

cv2.imshow(‘frame’, frame) 传入一张图片,通过窗口显示这张图片,第一个参数是窗口的名称。

cv2.waitKey(1) 程序会卡在这里,等待一个按键的事件,等待时间即为传入的t毫秒。
retval = cv.waitKey( [,delay])
当delay≤0时,函数waitKey无限等待键事件(即按下按键),当delay>0时,等待正数时长的延迟(单位:毫秒)。如果在延迟时长之内有按键,则返回该按键的ASCII码,如果在延迟时长内没有按键发生,返回-1。
因此在显示的窗口中播放的视频的速率,限制因素不是视频的fps,而是等待代码waitKey(10)所花费的时间,该代码使程序在每帧之间等待10ms。如果设为150,窗口中视频将看起来非常慢。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值