zoukankan      html  css  js  c++  java
  • Python opencv提取视频中的图片

    作者:R语言和Python学堂
    链接:https://www.jianshu.com/p/e3c04d4fb5f3

    这个函数就是本文要介绍的video2frames()函数,功能就是从视频中提取图片,名称“video2frames”是我自己取的,还比较形象。现将它分享给大家,感兴趣的小伙伴们可以参考一下,完整代码附在文末。

    1. 主要功能

    这个函数有以下主要功能:

    • 提取特定时间点图片,比如:提取视频第3秒, 第5秒,第9秒图片

    • 设定提取的起始时刻,比如:从视频的第10秒开始提取

    • 设定提取的终止时刻,比如:100秒后的视频不提取图片

    • 设定每隔多少秒提取一张图片,比如:每隔2秒从视频中提取一张图片

    2. 函数参数

    video2frames()函数的原型为:

    video2frames(pathIn='', 
                 pathOut='', 
                 only_output_video_info = False, 
                 extract_time_points = None, 
                 initial_extract_time = 0,
                 end_extract_time = None,
                 extract_time_interval = -1, 
                 output_prefix = 'frame',
                 jpg_quality = 100,
                 isColor = True)

    各参数的意义:

    • pathIn:视频的路径,比如:F:python_tutorials est.mp4

    • pathOut:设定提取的图片保存在哪个文件夹下,比如:F:python_tutorialsframes。如果该文件夹不存在,函数将自动创建它

    • only_output_video_info:如果为True,只输出视频信息(长度、帧数和帧率),不提取图片

    • extract_time_points:提取的时间点,单位为秒,为元组数据,比如,(2, 3, 5)表示只提取视频第2秒, 第3秒,第5秒图片

    • initial_extract_time:提取的起始时刻,单位为秒,默认为0(即从视频最开始提取)

    • end_extract_time:提取的终止时刻,单位为秒,默认为None(即视频终点)

    • extract_time_interval:提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧)

    • output_prefix:图片的前缀名,默认为frame,那么图片的名称将为frame_000001.jpgframe_000002.jpgframe_000003.jpg......

    • jpg_quality:设置图片质量,范围为0100,默认为100(质量最佳)

    • isColor:如果为False,输出的将是黑白图片

    目前只支持输出jpg格式图片

    3. 例子

    下面来测试一下这个函数的功能:

    • 设置only_output_video_infoTrue,将只输出视频信息,不提取图片
    >>> pathIn = 'test.mp4'
    >>> video2frames(pathIn, only_output_video_info=True)
    only output the video information (without extract frames)::::::
    Duration of the video: 5.28 seconds
    Number of frames: 132
    Frames per second (FPS): 25.0

    可以看到,视频test.mp4的长度为5.28秒,共132帧,帧率为25.0

    • 提取所有图片,并保存到指定文件夹下
    • >>> pathIn = 'test.mp4'
      >>> pathOut = './frames1/'
      >>> video2frames(pathIn, pathOut)
      Converting a video into frames......
      Write a new frame: True, 1/132
      Write a new frame: True, 2/132
      ..............................
      Write a new frame: True, 131/132
      Write a new frame: True, 132/132

    可以看到,视频的132帧图片全部提取到frames1文件夹下

    • 设置extract_time_points参数,提取特定时间点的图片
    >>> pathIn = 'test.mp4'
    >>> pathOut = './frames2'
    >>> video2frames(pathIn, pathOut, extract_time_points=(1, 2, 5))
    Write a new frame: True, 1th
    Write a new frame: True, 2th
    Write a new frame: True, 3th

    可以看到,只提取了第1秒,第2秒和第5秒图片

    • 每隔一段时间提取图片,并设置初始时刻和终止时刻
    • >>> pathIn = 'test.mp4'
      >>> pathOut = './frames3'
      >>> video2frames(pathIn, pathOut,
                       initial_extract_time=1,
                       end_extract_time=3,
                       extract_time_interval = 0.5) 
      Converting a video into frames......
      Write a new frame: True, 1th
      Write a new frame: True, 2th
      Write a new frame: True, 3th
      Write a new frame: True, 4th
      Write a new frame: True, 5th

    可以看到,1到3秒内的视频每隔0.5秒提取图片,共5张图片(分别为1s, 1.5s, 2s, 2.5s, 3s时刻的图片)

    • 设置jpg_quality参数,改变输出图片的质量
    • >>> pathOut = './frames4'
      >>> pathIn = 'test.mp4'
      >>> video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), jpg_quality=50)
      Write a new frame: True, 1th
      Write a new frame: True, 2th
    • 设置isColor参数为False,提取的照片将是黑白色
    >>> pathOut = './frames5'
    >>> pathIn = 'test.mp4'
    >>> video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), isColor=False)
    Write a new frame: True, 1th
    Write a new frame: True, 2th

    video2frames()函数的功能测试到此结束。

    4. 完整代码

    函数为通用型的,因此代码较长,可能还存在可以优化的地方,仅供参考。

    完整代码如下:

    # -*- coding: utf-8 -*-
    import os
    import cv2    ##加载OpenCV模块
    
    def video2frames(pathIn='', 
                     pathOut='', 
                     only_output_video_info = False, 
                     extract_time_points = None, 
                     initial_extract_time = 0,
                     end_extract_time = None,
                     extract_time_interval = -1, 
                     output_prefix = 'frame',
                     jpg_quality = 100,
                     isColor = True):
        '''
        pathIn:视频的路径,比如:F:python_tutorials	est.mp4
        pathOut:设定提取的图片保存在哪个文件夹下,比如:F:python_tutorialsframes1。如果该文件夹不存在,函数将自动创建它
        only_output_video_info:如果为True,只输出视频信息(长度、帧数和帧率),不提取图片
        extract_time_points:提取的时间点,单位为秒,为元组数据,比如,(2, 3, 5)表示只提取视频第2秒, 第3秒,第5秒图片
        initial_extract_time:提取的起始时刻,单位为秒,默认为0(即从视频最开始提取)
        end_extract_time:提取的终止时刻,单位为秒,默认为None(即视频终点)
        extract_time_interval:提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧)
        output_prefix:图片的前缀名,默认为frame,图片的名称将为frame_000001.jpg、frame_000002.jpg、frame_000003.jpg......
        jpg_quality:设置图片质量,范围为0到100,默认为100(质量最佳)
        isColor:如果为False,输出的将是黑白图片
        '''
        
        cap = cv2.VideoCapture(pathIn)  ##打开视频文件
        n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))  ##视频的帧数
        fps = cap.get(cv2.CAP_PROP_FPS)  ##视频的帧率
        dur = n_frames/fps  ##视频的时间
        
        ##如果only_output_video_info=True, 只输出视频信息,不提取图片
        if only_output_video_info:
            print('only output the video information (without extract frames)::::::')
            print("Duration of the video: {} seconds".format(dur))
            print("Number of frames: {}".format(n_frames))
            print("Frames per second (FPS): {}".format(fps)) 
        
        ##提取特定时间点图片
        elif extract_time_points is not None:
            if max(extract_time_points) > dur:   ##判断时间点是否符合要求
                raise NameError('the max time point is larger than the video duration....')
            try:
                os.mkdir(pathOut)
            except OSError:
                pass
            success = True
            count = 0
            while success and count < len(extract_time_points):
                cap.set(cv2.CAP_PROP_POS_MSEC, (1000*extract_time_points[count])) 
                success,image = cap.read()
                if success:
                    if not isColor:
                        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  ##转化为黑白图片
                    print('Write a new frame: {}, {}th'.format(success, count+1))
                    cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG file
                    count = count + 1
    
        else:
            ##判断起始时间、终止时间参数是否符合要求
            if initial_extract_time > dur:
                raise NameError('initial extract time is larger than the video duration....')
            if end_extract_time is not None:
                if end_extract_time > dur:
                    raise NameError('end extract time is larger than the video duration....')
                if initial_extract_time > end_extract_time:
                    raise NameError('end extract time is less than the initial extract time....')
            
            ##时间范围内的每帧图片都输出
            if extract_time_interval == -1:
                if initial_extract_time > 0:
                    cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time)) 
                try:
                    os.mkdir(pathOut)
                except OSError:
                    pass
                print('Converting a video into frames......')
                if end_extract_time is not None:
                    N = (end_extract_time - initial_extract_time)*fps + 1
                    success = True
                    count = 0
                    while success and count < N:
                        success,image = cap.read()
                        if success:
                            if not isColor:
                                image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                            print('Write a new frame: {}, {}/{}'.format(success, count+1, n_frames))
                            cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG file
                            count =  count + 1
                else:
                    success = True
                    count = 0
                    while success:
                        success,image = cap.read()
                        if success:
                            if not isColor:
                                image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                            print('Write a new frame: {}, {}/{}'.format(success, count+1, n_frames))
                            cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG file
                            count =  count + 1
    
            ##判断提取时间间隔设置是否符合要求    
            elif extract_time_interval > 0 and extract_time_interval < 1/fps:
                raise NameError('extract_time_interval is less than the frame time interval....')
            elif extract_time_interval > (n_frames/fps):
                raise NameError('extract_time_interval is larger than the duration of the video....')
            
            ##时间范围内每隔一段时间输出一张图片
            else:
                try:
                    os.mkdir(pathOut)
                except OSError:
                    pass
                print('Converting a video into frames......')
                if end_extract_time is not None:
                    N = (end_extract_time - initial_extract_time)/extract_time_interval + 1
                    success = True
                    count = 0
                    while success and count < N:
                        cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time+count*1000*extract_time_interval)) 
                        success,image = cap.read()
                        if success:
                            if not isColor:
                                image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                            print('Write a new frame: {}, {}th'.format(success, count+1))
                            cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG file
                            count = count + 1
                else:
                    success = True
                    count = 0
                    while success:
                        cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time+count*1000*extract_time_interval)) 
                        success,image = cap.read()
                        if success:
                            if not isColor:
                                image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                            print('Write a new frame: {}, {}th'.format(success, count+1))
                            cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG file
                            count = count + 1
    
    
    
    ##### 测试
    pathIn = 'test.mp4'
    video2frames(pathIn, only_output_video_info = True)
    
    pathOut = './frames1/'
    video2frames(pathIn, pathOut)
    
    pathOut = './frames2'
    video2frames(pathIn, pathOut, extract_time_points=(1, 2, 5))
    
    pathOut = './frames3'
    video2frames(pathIn, pathOut,
                 initial_extract_time=1,
                 end_extract_time=3,
                 extract_time_interval = 0.5)   
    
    pathOut = './frames4/'
    video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), isColor = False)
    
    
    pathOut = './frames5/'
    video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), jpg_quality=50)
  • 相关阅读:
    sp2010 升级sp2013 用户无法打开网站
    powerviot install in sharepoint 2013
    can not connect cube in performancce dashboard
    westrac server security configure user info
    添加报表服务在多服务器场
    sharepoint 2013 office web app 2013 文档在线浏览 IE11 浏览器不兼容解决方法
    delete job definition
    目前付款申请单内网打开慢的问题
    item style edit in sharepoint 2013
    Could not load file or assembly '$SharePoint.Project.AssemblyFullName$'
  • 原文地址:https://www.cnblogs.com/-wenli/p/11943523.html
Copyright © 2011-2022 走看看