OpenCV小案例——批量图片合成为视频


# 将某个文件夹下面的图片转化为一个视频
def png_to_video(dir_path):
    fps = 8
    size = (378, 512)
    video = cv2.VideoWriter("/Users/guojun/Desktop/video_test/film_frame.mp4", cv2.VideoWriter_fourcc(*'h264'), fps,
                            size, True)
    for i in os.listdir(dir_path):
        if not i.endswith('.png'):
            continue
        img_path = os.path.join(dir_path, i)
        print(img_path)
        img = cv2.imread(img_path)
        video.write(img)

需求:将挑选好的样本测试集转化为图片。

代码逻辑分析:

  1. 图片测试集中图片尺寸不一样,应该先按照图片尺寸进行图片分类;
  2. 每100张图片合成为一个视频,超过100的或者不足100的也合成一个视频,并标记视频的帧数

代码如下: 

import datetime
import os
import cv2
import shutil
import random


# 生成6位随机字符串
def rand_str():
    random_str = random.sample('zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRSTUVWXYZ', 6)
    random_str = ''.join(random_str)
    return random_str


def classification(dir_path):
    size_dir_path_list = []
    size_list = []
    # 先识别需要建立多少个文件夹
    for i in os.listdir(dir_path):
        if not i.endswith('.png'):
            continue
        img_path = os.path.join(dir_path, i)
        # 读取图片,得到图片尺寸
        img = cv2.imread(img_path)
        h, w, r = img.shape
        # 生成文件夹名字、文件夹路径
        size_dir_name = f'size_{w}_{h}'
        size_dir_path = os.path.join(dir_path, size_dir_name)
        # 判断文件夹存在不存在,如果不存在,则创建文件夹,然后把图片移动到文件夹中
        if not os.path.isdir(size_dir_path):
            os.mkdir(size_dir_path)
            size_dir_path_list.append(size_dir_path)
            size_list.append((w, h))
            shutil.move(img_path, f'{size_dir_path}/{i}')
        # 如果文件夹存在,则直接进行移动
        else:
            shutil.move(img_path, f'{size_dir_path}/{i}')
    # 每秒的帧数
    fps = 8
    for index, size_dir_path in enumerate(size_dir_path_list):
        # 视频尺寸
        size = size_list[index]
        print('视频尺寸:', size)
        # 获取长度来确定做几次视频压缩
        image_list = os.listdir(size_dir_path)
        print('该视频下面所有的图片列表:', image_list)
        count = int(len(image_list) // 100) + 1
        print(f'一共做{count}个视频')
        for i in range(count):
            print(f'开始做第{i + 1}个视频')
            start_index = i * 100
            # print('start_index:', type(start_index), start_index)

            # 如果是第一次循环并且总视频数量不止一个,那么结束索引是循环数量+1,乘以100;非第一次循环,结束索引为循环数量+1,乘以100
            if (i == 0 and count > 1) or i != count - 1:
                end_index = (i + 1) * 100
            # 如果是第一次循环并且总视频数量为1,那么结束索引为空,代表取剩下所有的;最后一次循环,且剩余图片数量不足100帧,结束索引为空,取剩下所有的
            if (i == 0 and count == 1) or (i == count - 1 and i != 0):
                end_index = None
            # 确定本次生成视频的图片列表
            img_name_list = image_list[start_index:end_index]
            # 记下时间戳用于视频名称
            flag = datetime.datetime.strftime(datetime.datetime.now(), '%y%m%d%H%M')
            # 生成随机字符串用于视频名称保证唯一
            flag_01 = rand_str()
            # 满足100帧与不满足100帧时,帧数不一样
            if i == count - 1:
                f_num = len(image_list) % 100

                print(f'不满足100帧视频信息,帧数: {f_num}')
            else:
                f_num = 100
            video_name = f'{flag}_{flag_01}_{f_num}.mp4'
            video_path = f'{size_dir_path}/{video_name}'
            # 视频编码类型
            fourcc = cv2.VideoWriter_fourcc(*'h264')
            video = cv2.VideoWriter(video_path, fourcc,
                                    fps,
                                    size, True)
            # 循环本次的图片合成到视频中
            for img_name in img_name_list:
                if not img_name.endswith('.png'):
                    continue
                img_path = os.path.join(size_dir_path, img_name)
                img = cv2.imread(img_path)
                video.write(img)
            video.release()  # 释放资源
        cv2.destroyAllWindows()  # 释放资源

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值