读取视频中的全部帧,并把每一帧保存成图片

近期有个任务需要实时检测出视频中的某个目标,这里我用的是神经网络,所以需要有训练样本,那就将视频的每一帧提取出来保存成图像去进行学习。

首先最先想到的是Opencv中的cv2.VideoCapture(video_path).read(),我是这样写的:

import cv2 as cv

def totalnumber_of_videoframes(video_path):
    capture = cv.VideoCapture(video_path)
    len_video_frame = int(capture.get(cv.CAP_PROP_FRAME_COUNT))
    print('total number of video frames :', len_video_frame)
    n = 0
    loss_frames = []
    for i in range(len_video_frame):
        ret,frame = capture.read() #ret返回的是True或者False,代表有没有读取到图像
        if ret:
            n += 1
        else:
            print("loss this frame")
            loss_frames.append(i)
    print('index :{}, read: {}'.format(i, n))
    print(loss_frames)
    
def vidio_frame_extract(video_path,save_path,index):
    capture = cv.VideoCapture(video_path)
    while capture.isOpened():
        ret,frame = capture.read()#frame是BGR格式
        if not ret:
            print('loss this frame')
        if frame is None:
            break
        print(frame.shape) #(795, 1055, 3)
        cv.imshow('frame',frame)
        save_frame = "{}/{:>03d}.bmp".format(save_path, index)
        cv.imwrite(save_frame,frame)
        index = index+1
    capture.release()
    cv.destroyAllWindows()

if __name__ == "__main__":
    video_path = "F:\object_detection\dog.avi"
    save_path = "F:\object_detection\dog"
    index = 0
    totalnumber_of_videoframes(video_path)#先看一下视频本身实际有多少帧,再看真正保存的视频帧有多少
    vidio_frame_extract(video_path, save_path, index)

结果发现我提取出来的视频帧数与视频本身实际的帧数不相同!!!即OpenCV使用VideoCapture处理视频时会丢失掉最后一些帧。

原因:可能是因为VideoCapture会忽略掉重复的帧,所以在调用VideoCapture时实际得到的帧数会近似等于视频实际的总帧数减去重复帧数。

解决方法:

利用python的一个视频处理库scikit-video,使用skvideo.io.vreader()可以逐帧加载任意视频

首先 pip install scikit-video

import cv2 as cv
import skvideo
from skvideo import io

def vidio_frame_extract(video_path,save_path,index):
    capture = skvideo.io.vreader(video_path)
    for frame in capture:#frame是RGB格式
        frame = cv.cvtColor(frame,cv.COLOR_RGB2BGR)
        cv.imshow("frame",frame)
        save_frame = "{}/{:>03d}.bmp".format(save_path, index)
        cv.imwrite(save_frame,frame)#注意cv.imwrite只有对frame为BGR空间时,才写出正确颜色空间图片
        index = index+1

if __name__ == "__main__":
    video_path = "F:\object_detection\dog.avi"
    save_path = "F:\object_detection\dog"
    index = 0
    vidio_frame_extract(video_path, save_path, index)

小插曲:这里出现了一个报错: AssertionError: Cannot find installation of ffmpeg.

解决:conda install ffmpeg(不知道为什么pip install ffmpeg没有用)

 

 

 

 

 

 
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在MATLAB,可以使用`VideoReader`函读取YUV文件,并使用`imwrite`函将每一帧图片保存为文件。 首先,需要创建一个`VideoReader`对象,指定YUV文件的路径和格式(如420Planar、YUV422等): ```matlab videoObj = VideoReader('path/to/your/video.yuv', 'VideoFormat', 'YUV420_8'); ``` 接下来,可以使用`hasFrame`函来检查是否还有可读的,然后使用`readFrame`函读取一帧,并使用`imwrite`函将其保存图片文件: ```matlab frameNum = 1; while hasFrame(videoObj) frame = readFrame(videoObj); imwrite(frame, sprintf('frame_%d.jpg', frameNum)); frameNum = frameNum + 1; end ``` 在上面的代码,`videoObj`是`VideoReader`对象,`frame`是读取到的据。`imwrite`函将传入的保存为以序号命名的图片文件,如`frame_1.jpg`、`frame_2.jpg`等。 要注意的是,YUV文件一帧的尺寸和颜色空间可能不同,因此在读取一帧之前,需要根据文件的格式进行适当的设置。另外,需要根据实际情况调整保存图片的格式和路径。 希望这个回答对您有帮助! ### 回答2: MATLAB可以使用VideoReader函读取YUV文件,并使用imwrite函将每一帧保存图片文件。 首先,需要使用VideoReader函创建一个视频读取对象,指定输入的YUV文件名: ```matlab v = VideoReader('input.yuv'); ``` 接下来,可以使用readFrame函读取YUV文件的图像,并使用imwrite函将每一帧保存图片文件。可以通过循环来读取文件的所有保存: ```matlab frameIndex = 1; % 用于追踪的索引 while hasFrame(v) frame = readFrame(v); % 读取一帧图像 filename = sprintf('frame%d.jpg', frameIndex); % 根据索引生保存的文件名 imwrite(frame, filename); % 保存图像为JPEG文件 frameIndex = frameIndex + 1; % 索引自增 end ``` 上述代码,使用sprintf函一帧保存的文件名,命名为frame1.jpg、frame2.jpg等。imwrite函将每一帧图像保存为JPEG文件。 最终,代码将会读取YUV文件的每一帧图像,并将每一帧保存为以索引命名的图片文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值