imageio.get_reader()

本文介绍了如何利用imageio库从文件或网络地址读取图像,并通过mode='I'创建一个可以逐帧写入的Writer对象,从而实现GIF动画的生成。步骤包括指定文件路径、选择文件格式和使用get_reader方法。适合初学者了解文件操作和动画制作。

imageio.get_reader(uri, format=None, mode='?', **kwargs)

 

参数

uri:{str, pathlib.Path, file}

读取的源,例如文件名、pathlib.path、http地址或文件对象,

format:str

用于读文件,默认系统基于文件名选择合适的.

mode:{‘i’, ‘I’, ‘v’, ‘V’, ‘?’}

用来读取的文件的格式( “i” 图片, “I” 多个图像, “v” for a volume, “V” for multiple volumes, “?” 不关心格式.)

kwargs:…

其他关键字参数传递给函数

返回

返回一个可用于从指定文件中读取数据和元数据的Reader对象

实例

参考imageio.get_writer(),如下,参考另一篇文章:https://blog.youkuaiyun.com/Crystal_remember/article/details/116865915

anim_file = 'dcgan.gif'

with imageio.get_writer(anim_file, mode='I') as writer:
  filenames = glob.glob('image*.png')
  filenames = sorted(filenames)
  last = -1
  for i,filename in enumerate(filenames):
    frame = 2*(i**0.5)
    if round(frame) > round(last):
      last = frame
    else:
      continue
    image = imageio.imread(filename) #读取图片
    writer.append_data(image) #将图片写入writer,以生成gif
  image = imageio.imread(filename)
  writer.append_data(image)

import IPython
if IPython.version_info > (6,2,0,''):
  display.Image(filename=anim_f

参考文献:官方文档https://imageio.readthedocs.io/en/stable/index.html

 

消除以下代码的语法错误: import os import numpy as np import torch import torch.nn.functional as F # import torchvision.transforms as transforms # import torchvision.transforms.functional as TF import imageio from PIL import Image import cv2 import pandas as pd class VideoProcessor: def __init__(self, input_dir, output_dir, max_num_frames=81, num_frames=81, height=480, width=832): self.input_dir = input_dir self.output_dir = output_dir self.max_num_frames = max_num_frames self.num_frames = num_frames self.height = height self.width = width # self.frame_process = transforms.Compose([ # transforms.CenterCrop(size=(height, width)), # transforms.Resize(size=(height, width), interpolation=transforms.InterpolationMode.BILINEAR), # transforms.ToTensor(), # transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), # ]) def load_frames_using_imageio(self, file_path, max_num_frames, start_frame_id=0, interval=1, num_frames=81, frame_process=None): reader = imageio.get_reader(file_path) if reader.count_frames() < max_num_frames: reader.close() return None frames = [] for frame_id in range(num_frames): frame = reader.get_data(start_frame_id + frame_id * interval) frame = Image.fromarray(frame) # frame = self.crop_and_resize(frame) # if frame_process: # frame = frame_process(frame) frames.append(frame) reader.close() return frames # 返回PIL Image列表 def tensor_to_cv2(self, tensor): # 将 tensor [C x H x W] 转换为 numpy [H x W x C],并反归一化 tensor = (tensor * 0.5 + 0.5).clamp(0, 1) img = tensor.cpu().numpy().transpose(1, 2, 0) img = (img * 255).astype(np.uint8) img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) return img def process_videos(self): os.makedirs(self.output_dir, exist_ok=True) video_files = [f for f in os.listdir(self.input_dir) if f.endswith(('.mp4', '.avi', '.mov'))] print(f"找到 {len(video_files)} 个视频文件,开始处理...") for video_file in video_files: input_path = os.path.join(self.input_dir, video_file) output_path = os.path.join(self.output_dir, video_file) print(f"正在处理: {input_path}") frames = self.load_frames_using_imageio(input_path, self.max_num_frames, start_frame_id=0, interval=1, num_frames=self.num_frames) if frames is None: print(f"无法读取足够帧数: {input_path}") continue # 写入视频 # first_frame = self.tensor_to_cv2(frames[0]) first_frame = frames[0] height, width, _ = first_frame.shape fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, 24.0, (width, height)) for frame in frames: # frame_cv2 = self.tensor_to_cv2(frame) out.write(frame) out.release() print(f"已保存: {output_path}") if __name__ == "__main__": input_dir = "/common-data/kunlin/code/ReCamMaster-main/test_video/videos/" output_dir = "/common-data/kunlin/code/ReCamMaster-main/test_video/processed_videos/" processor = VideoProcessor(input_dir, output_dir) processor.process_videos()
09-20
帮我写一个脚本将以下的数据集函数改造成视频处理脚本,我希望你用里面的取帧函数,将/common-data/kunlin/code/ReCamMaster-main/test_video/videos/ 都取最大帧数,然后重新按照原文件名保存成MP4: class TextVideoCameraDataset(torch.utils.data.Dataset): def __init__(self, base_path, metadata_path, args, max_num_frames=81, frame_interval=1, num_frames=81, height=480, width=832, is_i2v=False): metadata = pd.read_csv(metadata_path) self.path = [os.path.join(base_path, "videos", file_name) for file_name in metadata["file_name"]] self.text = metadata["text"].to_list() self.max_num_frames = max_num_frames self.frame_interval = frame_interval self.num_frames = num_frames self.height = height self.width = width self.is_i2v = is_i2v self.args = args self.cam_type = self.args.cam_type self.frame_process = v2.Compose([ v2.CenterCrop(size=(height, width)), v2.Resize(size=(height, width), antialias=True), v2.ToTensor(), v2.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), ]) def crop_and_resize(self, image): width, height = image.size scale = max(self.width / width, self.height / height) image = torchvision.transforms.functional.resize( image, (round(height*scale), round(width*scale)), interpolation=torchvision.transforms.InterpolationMode.BILINEAR ) return image def load_frames_using_imageio(self, file_path, max_num_frames, start_frame_id, interval, num_frames, frame_process): reader = imageio.get_reader(file_path) if reader.count_frames() < max_num_frames or reader.count_frames() - 1 < start_frame_id + (num_frames - 1) * interval: reader.close() return None frames = [] first_frame = None for frame_id in range(num_frames): frame = reader.get_data(start_frame_id + frame_id * interval) frame = Image.fromarray(frame) frame = self.crop_and_resize(frame) if first_frame is None: first_frame = np.array(frame) frame = frame_process(frame) frames.append(frame) reader.close() frames = torch.stack(frames, dim=0) frames = rearrange(frames, "T C H W -> C T H W") if self.is_i2v: return frames, first_frame else: return frames def is_image(self, file_path): file_ext_name = file_path.split(".")[-1] if file_ext_name.lower() in ["jpg", "jpeg", "png", "webp"]: return True return False def load_video(self, file_path): start_frame_id = torch.randint(0, self.max_num_frames - (self.num_frames - 1) * self.frame_interval, (1,))[0] frames = self.load_frames_using_imageio(file_path, self.max_num_frames, start_frame_id, self.frame_interval, self.num_frames, self.frame_process) return frames def parse_matrix(self, matrix_str): rows = matrix_str.strip().split('] [') matrix = [] for row in rows: row = row.replace('[', '').replace(']', '') matrix.append(list(map(float, row.split()))) return np.array(matrix) def get_relative_pose(self, cam_params): abs_w2cs = [cam_param.w2c_mat for cam_param in cam_params] abs_c2ws = [cam_param.c2w_mat for cam_param in cam_params] cam_to_origin = 0 target_cam_c2w = np.array([ [1, 0, 0, 0], [0, 1, 0, -cam_to_origin], [0, 0, 1, 0], [0, 0, 0, 1] ]) abs2rel = target_cam_c2w @ abs_w2cs[0] ret_poses = [target_cam_c2w, ] + [abs2rel @ abs_c2w for abs_c2w in abs_c2ws[1:]] ret_poses = np.array(ret_poses, dtype=np.float32) return ret_poses def __getitem__(self, data_id): text = self.text[data_id] path = self.path[data_id] video = self.load_video(path) if video is None: raise ValueError(f"{path} is not a valid video.") num_frames = video.shape[1] assert num_frames == 81 data = {"text": text, "video": video, "path": path} # load camera tgt_camera_path = "/common-data/kunlin/code/ReCamMaster-main/example_test_data/cameras/camera_extrinsics.json" with open(tgt_camera_path, 'r') as file: cam_data = json.load(file) cam_idx = list(range(num_frames))[::4] traj = [self.parse_matrix(cam_data[f"frame{idx}"][f"cam{int(self.cam_type):02d}"]) for idx in cam_idx] traj = np.stack(traj).transpose(0, 2, 1) c2ws = [] for c2w in traj: c2w = c2w[:, [1, 2, 0, 3]] c2w[:3, 1] *= -1. c2w[:3, 3] /= 100 c2ws.append(c2w) tgt_cam_params = [Camera(cam_param) for cam_param in c2ws] relative_poses = [] for i in range(len(tgt_cam_params)): relative_pose = self.get_relative_pose([tgt_cam_params[0], tgt_cam_params[i]]) relative_poses.append(torch.as_tensor(relative_pose)[:,:3,:][1]) pose_embedding = torch.stack(relative_poses, dim=0) # 21x3x4 pose_embedding = rearrange(pose_embedding, 'b c d -> b (c d)') data['camera'] = pose_embedding.to(torch.bfloat16) return data def __len__(self): return len(self.path)
最新发布
09-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Alocus_

如果我的内容帮助到你,打赏我吧

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

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

打赏作者

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

抵扣说明:

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

余额充值