From 3a39a5178ca13b686c9ccb96ab3fbe78173b2dc3 Mon Sep 17 00:00:00 2001 From: march3 Date: Fri, 10 Nov 2023 19:50:08 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sim_scenes/solar_system/halley_comet_sim.py | 2 +- simulators/ursina/entities/video_recorder.py | 87 ++++++++++++++++---- 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/sim_scenes/solar_system/halley_comet_sim.py b/sim_scenes/solar_system/halley_comet_sim.py index f467c66..31dcfe6 100644 --- a/sim_scenes/solar_system/halley_comet_sim.py +++ b/sim_scenes/solar_system/halley_comet_sim.py @@ -370,7 +370,7 @@ if __name__ == '__main__': cosmic_bg='', show_trail=True, # bg_music='sounds/no_glory.mp3', - # show_camera_info=False, + show_camera_info=False, save_as_video=True, show_control_info=False, timer_enabled=True, diff --git a/simulators/ursina/entities/video_recorder.py b/simulators/ursina/entities/video_recorder.py index 329d7bb..00b58bb 100644 --- a/simulators/ursina/entities/video_recorder.py +++ b/simulators/ursina/entities/video_recorder.py @@ -2,6 +2,7 @@ from ursina import * import os, shutil import builtins import numpy as np +import cv2 class CubeMapVideoRecorder(Entity): @@ -65,6 +66,13 @@ class VideoRecorder(Entity): self.max_frames = int(self.duration * self.fps) self.frames = [] + self.save_name = "video_temp.mp4" + self.video = self.create_video(864, 1536) + + def create_video(self, height, width): + fourcc = cv2.VideoWriter_fourcc(*'mp4v') + video = cv2.VideoWriter(self.save_name, fourcc, self.fps, (width, height)) + return video def start_recording(self): print('start recording,', self.duration, self.file_path) @@ -74,40 +82,85 @@ class VideoRecorder(Entity): self.max_frames = self.duration * self.fps if not self.file_path.exists(): self.file_path.mkdir() - base.movie(namePrefix=f'\\video_temp\\{self.video_name}', duration=2.0, fps=30, format='png', sd=4) + # base.movie(namePrefix=f'\\video_temp\\{self.video_name}', duration=2.0, fps=30, format='png', sd=4) self.recording = True - invoke(self.stop_recording, delay=self.duration) + # invoke(self.stop_recording, delay=self.duration) def stop_recording(self): self.recording = False window.fps_counter.enabled = True window.exit_button.visible = True print('stop recording') - self.convert_to_gif() + self.convert_to_mp4() + + def convert_to_mp4(self): + print("视频保存中") + self.video.release() + cv2.destroyAllWindows() + # crop('video.mp4') + print("视频保存完成") + print(self.save_name) + + def screenshot_to_opencv_img(self, texture): + # 将Texture对象转换为numpy数组 + array = texture.to_array() + # 将数组reshape为4D,以便opencv可以正确读取 + array = np.reshape(array, (texture.height, texture.width, -1)) + # 转换为opencv读取的格式,注意需要先安装opencv库 + img = cv2.cvtColor(array, + cv2.COLOR_RGB2BGR) # 这里的cv2.COLOR_RGB2BGR是将RGB格式转换为BGR格式,因为Ursina使用的是RGB格式,而opencv使用的是BGR格式 + return img def update(self): if not self.recording: return - self.t += time.dt - if self.t >= 1 / 30: - base.screenshot( - namePrefix='\\video_temp\\' + self.video_name + '_' + str(self.i).zfill(4) + '.png', - defaultFilename=0, - ) - self.t = 0 - # # self.frames.append(self.renderToPNM()) - # image = base.win.getScreenshot() - # data = image.getRamImageAs("RGB").getData() - # # from PIL import Image - # # image = Image.fromarray(data) - # # img = data.convert("RGBA") - # data = np.array(data) + self.t += time.dt + if self.t >= 1 / 30: + # base.screenshot( + # namePrefix='\\video_temp\\' + self.video_name + '_' + str(self.i).zfill(4) + '.png', + # defaultFilename=0, + # ) + self.t = 0 + # image = deepcopy(camera.render_texture) + # self.frames.append(self.renderToPNM()) + from PIL import Image + import io + import imageio + image = base.win.getScreenshot() + # image = image.get_internal_image() + + data = image.getRamImageAs("BGR").getData() + np_data = np.frombuffer(data, dtype=np.uint8) # + img_data = np.reshape(np_data, (864, 1536, 3)) + # img = Image.fromarray(img_data) + # img = self.screenshot_to_opencv_img(image) + # img = np.array(data) + # image = Image.open(io.BytesIO(data)) + # image = Image.fromarray(np.array(data)) + # img = data.convert("RGBA") + # data = np.array(data) + # 获取图片的宽和高 + width = img_data.shape[1] + height = img_data.shape[0] + + # 创建一个空的数组,用于存储还原后的图像 + normal_image = np.zeros((height, width, 3), dtype=np.uint8) + + # 将颠倒图像的像素还原到正常图像中 + for i in range(height): + for j in range(width): + normal_image[i, j] = img_data[height - i - 1, j] + # # image = deepcopy(camera.render_texture) # self.frames.append(data) self.i += 1 + # img_bgr = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR) + # if imageNum < self.fps * args.total_time: + # show_image(frame) + self.video.write(normal_image) # store screenshot in memory # def renderToPNM(self): -- GitLab