当前位置: 首页 > news >正文

视频mp4垂直拼接 水平拼接

视频mp4垂直拼接 水平拼接

pinjie_v.py

import imageio
import numpy as np
import os
import cv2

def pinjie_v(dir1,dir2,out_dir):

    os.makedirs(out_dir, exist_ok=True)
    # 获取目录下的所有视频文件
    video_files_1 = [f for f in os.listdir(dir1) if f.endswith('.mp4')]
    video_files_2 = [f for f in os.listdir(dir2) if f.endswith('.mp4')]

    # 确保两个目录下的视频文件是同名的
    common_files = set(video_files_1).intersection(video_files_2)

    # 如果没有同名视频,退出
    if not common_files:
        print("没有同名的视频文件。")
        exit()

    for video_name in common_files:
        print(f"处理视频: {video_name}")

        # if "user-4fd103ee-38d4-43c5-bb2a-f496d2fe065e" not in video_name:
        #     continue
        # 打开视频文件
        video_path_1 = os.path.join(dir1, video_name)
        video_path_2 = os.path.join(dir2, video_name)

        reader1 = imageio.get_reader(video_path_1)
        reader2 = imageio.get_reader(video_path_2)

        # 获取视频信息(假设两个视频有相同帧数)
        fps = reader1.get_meta_data()['fps']
        num_frames = min(reader1.count_frames(), reader2.count_frames())

        # 创建输出文件
        output_path = os.path.join(out_dir, f"v_{video_name}")
        # writer = imageio.get_writer(output_path, fps=fps)
        if os.path.exists(output_path):
            continue
        outs = []
        # 逐帧处理
        for i in range(num_frames):
            frame1 = reader1.get_data(i)
            frame2 = reader2.get_data(i)

            # 获取帧的高度和宽度
            height1, width1, _ = frame1.shape
            height2, width2, _ = frame2.shape
            if height1 > width1:
                if height1 != height2:
                    y_scale = height1 / height2
                    frame2 = cv2.resize(frame2, (int(width2 * y_scale), height1), interpolation=cv2.INTER_AREA)
            elif height1 <= width1:
                if width1 != width2:
                    x_scale = width1 / width2
                    frame2 = cv2.resize(frame2, (width1, int(height2 * x_scale)), interpolation=cv2.INTER_AREA)

            if height1 > width1:
                frame = np.hstack([frame1, frame2])
            else:
                frame = np.vstack([frame1, frame2])

            outs.append(frame)
        try:
            imageio.mimsave(f'{output_path}', outs, fps=fps, macro_block_size=None)
        except Exception as e:
            print(e)
        # writer.close()
        print(f"视频 {video_name} 拼接完成,保存在 {output_path}")

if __name__ == '__main__':

    # 设置目录路径
    dir1 = r'E:\project\smpl\render_blender\linux\hmr_res'
    dir2 = r'E:\project\smpl\render_blender\linux\hmr2_res'

    dir1 = r'E:\project\smpl\render_blender\linux\val_out_depth_any_color'
    dir2 = r'E:\project\smpl\render_blender\linux\val_out_video'

    dir1 = r'E:\project\smpl\render_blender\linux\val_out_depth_any_color'
    dir2 = r'E:\project\smpl\render_blender\linux\val_out_video'

    dir1=r'E:\project\smpl\render_blender\linux\test_lbg_o'
    dir2 =r'E:\project\smpl\render_blender\linux\test_lbg6'

    out_dir = 'track_diff'
    pinjie_v(dir1,dir2,out_dir)

http://www.dtcms.com/a/31213.html

相关文章:

  • 高级系统架构师--第七章:安全架构设计理论与实践
  • Nginx Embedded Variables 嵌入式变量解析(4)
  • Gradio全解11——使用transformers.agents构建Gradio UI(4)
  • Windows 权限结构和原理:深入浅出
  • 基于flask+vue框架的的医院预约挂号系统i1616(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • React Router v5 vs v6 路由配置对比
  • Vue 中 nextTick 的原理详解
  • DeepSeek掘金——快速集成DeepSeek满血版 搭建智能运维助手
  • 黑马点评自学03
  • Spring MVC 对象转换器:初级开发者入门指南
  • 图书管理系统
  • C++ 设计模式-访问者模式
  • python中的异常-模块-包
  • 基于Spring Boot的农事管理系统设计与实现(LW+源码+讲解)
  • Vue 和 React 响应式的区别
  • 波兰发布世界首个双足肌肉骨骼机器人,细节高度模拟人类生物特征
  • 远离手机APP——数字排毒,回归生活本真
  • 边缘安全加速(ESA)套餐
  • 图解MySQL【日志】——Binlog
  • Web Scraper,强大的浏览器爬虫插件!
  • 前端开发的适配方案
  • grafana 忘记登陆密码
  • 【学习】验证数独的正确性
  • 从零开始玩转TensorFlow:小明的机器学习故事 2
  • [C++ ]使用std::string作为函数参数时的注意事项
  • 【Java 优选算法】位运算
  • Vmware虚拟机Ubantu安装Docker、k8s、kuboard
  • 银行IT治理——安全架构定义
  • 企业组网IP规划与先关协议分析
  • overflow-x: auto 使用鼠标实现横向滚动,区分触摸板和鼠标滚动事件的方法