opencv(python)视频按帧切片/cv2.VideoCapture()用法

一、介绍

cv2.VideoCapture是OpenCV中一个用于捕捉视频的类。它可以访问计算机的摄像头,或从视频文件中读取图像。通过cv2.VideoCapture,用户可以轻松地捕捉、保存、编辑和传输视频流数据。

使用cv2.VideoCapture可以实现以下功能:

1. 打开计算机的摄像头,实时捕捉摄像头的视频流数据。
2. 读取视频文件,逐帧解码并输出视频流数据。
3. 控制帧率,调整视频的播放速度。
4. 控制视频的长宽和分辨率。
5. 编辑视频流数据,比如添加水印、合并视频等操作。
6. 传输视频数据,可以通过网络传输视频流数据。

cv2.VideoCapture中最常用的方法有:

1. read():读取视频流数据中的一帧。
2. isOpened():检查当前的cv2.VideoCapture是否已经打开。
3. release():释放cv2.VideoCapture对象占用的资源。

例如以下代码展示如何使用cv2.VideoCapture对象打开计算机的摄像头并捕获实时视频:


import cv2

cap = cv2.VideoCapture(0)  # 打开计算机的摄像头

while True:
    ret, frame = cap.read()  # 读取视频流数据中的一帧

    cv2.imshow('frame', frame)  # 显示捕获的视频流数据

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

cap.release()  # 释放占用的资源
cv2.destroyAllWindows()

二、cv2.VideoCapture()视频的获取操作

1、从文件读取视频

参数是视频文件路径,打开方式如下:

videoCapture = cv2.VideoCapture(“../test1.mp4”) #.avi等视频文件

2、从摄像头读取视频

 VideoCapture(0)中参数是0,表示打开笔记本的内置摄像头,如果有多个摄像头,往上加就可。

videoCapture = cv2.VideoCapture(0)
如果要读取监控摄像头的视频流,需要知道指定摄像头的ip等信息。
# 使用rtsp流打开相机
videoCapture = cv2.VideoCapture(f'rtsp://{username}:{password}@{ip}:{port}/h264/ch1/main/av_stream')

三、videoCapture.read()按帧读内容

# 读帧
success, frame = videoCapture.read()
print(success)
print(frame)
success,frame是获.read()方法的两个返回值。 其中success是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。

下面这个示例中,我们使用了默认摄像头(设备编号为0)作为输入,然后使用while循环逐帧读取视频并在窗口中显示。如果按下 'q' 键或无法读取视频,则退出循环并释放资源。

import cv2

# 创建 VideoCapture 对象
cap = cv2.VideoCapture(0)

# 循环读取视频流
while True:
    # 逐帧读取视频
    ret, frame = cap.read()

    # 如果不能读取视频,退出循环
    if not ret:
        break

    # 在窗口中显示视频帧
    cv2.imshow("frame", frame)

    # 检测键盘输入,按 'q' 键退出循环
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

# 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()

什么是帧,帧的快慢是什么,影响什么
        视频的基本组成部分是帧(frame),即一系列静态图像,这些图像在一定速率下以连续的方式播放,形成动态图像,例如30帧/秒。视频每秒的帧数被称为帧率(Frame Rate),通常用“fps”(Frames Per Second)表示。例如,30fps表示视频每秒钟包含30帧图像。帧率决定了视频的流畅度和真实感。较高的帧率可以使视频看起来更加流畅,因为它们可以更快地刷新图像。例如,60fps的视频比30fps的视频看起来更加流畅。此外,较高的帧率还可以减少视频中的模糊和颤动,因为它们可以更好地捕捉运动。但较高的帧率会导致文件变大和编解码更复杂,因为需要处理更多的帧图像。
————————————————
https://blog.csdn.net/cvxiayixiao/article/details/130519349

四、实例

import os
import cv2


# 定义保存图片函数
# image:要保存的图片
# pic_address:图片保存地址
# num: 图片后缀名,用于区分图片,int 类型
def save_image(image, address, num):
    pic_address = address + str(num) + '.jpg'
    cv2.imwrite(pic_address, image)


def video_to_pic(video_path, save_path, frame_rate):
    # 读取视频文件
    # video_path为视频路径,save_path为保存图片路径,frame_rate可以设置多少帧切一张图

    global videoCap
    #这里将videoCapture加global意思是设置成了全局变量,后面释放摄像头要用到这个变量

    videoCap = cv2.VideoCapture(video_path)

    if videoCap.isOpened():
        print("摄像头or视频打开成功")
    if not videoCap.isOpened():
        print("找不到摄像头or视频")
        exit()

 
    # 读帧
    success, frame = videoCap.read()
    """success,frame是获.read()方法的两个返回值。 
    其中success是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。
    frame就是每一帧的图像,是个三维矩阵。"""
    # print(success)
    # print(frame)
    if videoCap.open(video_path):
        print("视频提取成功")
    if not videoCap.open(video_path):
        print("can not open the video")

    j = 0
    i = 0
    while success:
        i = i + 1
        # 每隔固定帧保存一张图片
        if i % frame_rate == 0:
            j = j + 1
            save_image(frame, save_path, j)
            print('图片保存地址:', save_path + str(j) + '.jpg')
        success, frame = videoCap.read()
        # if cv2.waitKey(1) & 0xFF == ord('q'):
        #     break


if __name__ == '__main__':


    # 视频文件和图片保存地址
    SAMPLE_VIDEO = 'F:/Capture/dist/video/sc0914.mp4'
  
    SAVE_PATH = 'F:/Capture/dist/VideotoImages/sc0914/'
    #注意保存本地路径不能有中文,save_image()以及imwrite、cv2.imread()均不支持有中文的路径

    if not os.path.exists(SAVE_PATH):
        os.makedirs(SAVE_PATH)

    # 设置固定帧率
    FRAME_RATE = 10
    video_to_pic(SAMPLE_VIDEO, SAVE_PATH, FRAME_RATE)


# 调用release()释放摄像头
# 调用destroyAllWindows()关闭所有图像窗口。
videoCap.release()
cv2.destroyAllWindows()

import timefrom serial import Serialimport serial.tools.list_portsimport cv2import numpy as npcap1 = cv2.VideoCapture("/Users/yankaipan/Desktop/stand.mp4")cap2 = cv2.VideoCapture("/Users/yankaipan/Desktop/apple.mp4")cap3 = cv2.VideoCapture("/Users/yankaipan/Desktop/bamboo.mp4")cap4 = cv2.VideoCapture("/Users/yankaipan/Desktop/rubbish.mp4")port_list = list(serial.tools.list_ports.comports())port_list_1 = list(port_list[2])port_serial = port_list_1[0]arduinoData = serial.Serial(port_serial, 9600)time.sleep(1)while True: while (arduinoData.inWaiting() == 0): pass dataPacket = arduinoData.readline() dataPacket = dataPacket.decode().strip() print(dataPacket) time.sleep(3) if dataPacket == "a": while cap1.isOpened(): ret, frame = cap1.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: cap1.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "b": while cap2.isOpened(): ret, frame = cap2.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: cap2.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "c": while cap3.isOpened(): ret, frame = cap3.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: cap3.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "d": while cap4.isOpened(): ret, frame = cap4.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: cap4.set(cv2.CAP_PROP_POS_FRAMES, 0)cv2.destroyAllWindows()怎样修改代码能够在其中一个a视频播放时,接收到arduino发送的消息时能够触发另一视频b或c或d并播放?
05-21
可以使用一个变量来记录当前正在播放的视频,当接收到新的消息时,根据消息内容判断应该播放哪个视频,并将当前正在播放的视频暂停或关闭,然后切换到新的视频播放。 以下是修改后的代码: ``` import time from serial import Serial import serial.tools.list_ports import cv2 import numpy as np cap1 = cv2.VideoCapture("/Users/yankaipan/Desktop/stand.mp4") cap2 = cv2.VideoCapture("/Users/yankaipan/Desktop/apple.mp4") cap3 = cv2.VideoCapture("/Users/yankaipan/Desktop/bamboo.mp4") cap4 = cv2.VideoCapture("/Users/yankaipan/Desktop/rubbish.mp4") port_list = list(serial.tools.list_ports.comports()) port_list_1 = list(port_list[2]) port_serial = port_list_1[0] arduinoData = serial.Serial(port_serial, 9600) time.sleep(1) current_video = None # 记录当前正在播放的视频 while True: while (arduinoData.inWaiting() == 0): pass dataPacket = arduinoData.readline() dataPacket = dataPacket.decode().strip() print(dataPacket) time.sleep(3) if dataPacket == "a": if current_video != cap1: # 判断是否需要切换视频 if current_video is not None: current_video.release() current_video = cap1 while current_video.isOpened(): ret, frame = current_video.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: current_video.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "b": if current_video != cap2: if current_video is not None: current_video.release() current_video = cap2 while current_video.isOpened(): ret, frame = current_video.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: current_video.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "c": if current_video != cap3: if current_video is not None: current_video.release() current_video = cap3 while current_video.isOpened(): ret, frame = current_video.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: current_video.set(cv2.CAP_PROP_POS_FRAMES, 0) elif dataPacket == "d": if current_video != cap4: if current_video is not None: current_video.release() current_video = cap4 while current_video.isOpened(): ret, frame = current_video.read() if ret == True: cv2.imshow('Frame', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: current_video.set(cv2.CAP_PROP_POS_FRAMES, 0) cv2.destroyAllWindows() ``` 注意,在切换视频时需要将上一个视频释放掉,否则会导致内存泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彩色面团儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值