Open ryou128hr opened 1 month ago
TensorRT 10.2.0
import os import tkinter as tk from tkinter import filedialog, messagebox import torch from ffstream.ffstream import FFStream import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
def build_engine(onnx_file_path, engine_file_path): print("Starting to build the engine...") with trt.Builder(TRT_LOGGER) as builder, \ builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) as network, \ trt.OnnxParser(network, TRT_LOGGER) as parser: config = builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB config.set_flag(trt.BuilderFlag.FP16)
print("Parsing ONNX file...")
with open(onnx_file_path, 'rb') as model:
if not parser.parse(model.read()):
print('Failed to parse the ONNX file.')
for error in range(parser.num_errors):
print(parser.get_error(error))
return None
print("Creating optimization profile...")
profile = builder.create_optimization_profile()
input_name = network.get_input(0).name
profile.set_shape(input_name, min=(1, 3, 64, 64), opt=(1, 3, 1080, 1920), max=(1, 3, 2160, 3840))
config.add_optimization_profile(profile)
print("Building the engine...")
engine_bytes = builder.build_serialized_network(network, config)
if engine_bytes is None:
print('Failed to create engine')
sys.exit(1)
print("Deserializing the engine...")
with trt.Runtime(TRT_LOGGER) as runtime:
engine = runtime.deserialize_cuda_engine(engine_bytes)
print("Engine built successfully.")
save_engine(engine, engine_file_path)
return engine
def save_engine(engine, file_path): with open(file_path, 'wb') as f: f.write(engine.serialize())
def load_engine(runtime, file_path): with open(file_path, 'rb') as f: engine_data = f.read() return runtime.deserialize_cuda_engine(engine_data)
def allocate_buffers(engine, context, input_shape): inputs = [] outputs = [] bindings = [] stream = cuda.Stream()
for i in range(engine.num_io_tensors):
tensor_name = engine.get_tensor_name(i)
if engine.get_tensor_mode(tensor_name) == trt.TensorIOMode.INPUT:
context.set_input_shape(tensor_name, input_shape)
shape = context.get_tensor_shape(tensor_name)
size = trt.volume(shape)
dtype = trt.nptype(engine.get_tensor_dtype(tensor_name))
host_mem = cuda.pagelocked_empty(size, dtype)
device_mem = cuda.mem_alloc(host_mem.nbytes)
bindings.append(int(device_mem))
if engine.get_tensor_mode(tensor_name) == trt.TensorIOMode.INPUT:
inputs.append({'host': host_mem, 'device': device_mem, 'shape': shape})
else:
outputs.append({'host': host_mem, 'device': device_mem, 'shape': shape})
return inputs, outputs, bindings, stream
def do_inference(context, bindings, inputs, outputs, stream): [cuda.memcpy_htod_async(inp['device'], inp['host'], stream) for inp in inputs] context.execute_v2(bindings=bindings) [cuda.memcpy_dtoh_async(out['host'], out['device'], stream) for out in outputs] stream.synchronize() return [out['host'] for out in outputs]
def process_with_ai_engine(frame_rgb, engine, context, inputs, outputs, bindings, stream): print("Processing frame with AI engine...") frame_rgb_np = frame_rgb.cpu().numpy().ravel() input_shape = inputs[0]['shape'] print(f"Input tensor shape: {input_shape}, Frame shape: {frame_rgb_np.shape}") if frame_rgb_np.size != np.prod(input_shape): raise ValueError(f"Size mismatch: input tensor has {np.prod(input_shape)} elements but frame has {frame_rgb_np.size} elements.") np.copyto(inputs[0]['host'], frame_rgb_np) output = do_inference(context, bindings, inputs, outputs, stream) output_shape = outputs[0]['shape'] output_tensor = torch.from_numpy(output[0]).view(*output_shape).cuda() return output_tensor
def select_video(): file_path = filedialog.askopenfilename(filetypes=[("Video files", ".mp4;.avi;.mov;.mkv;.m2ts;.h264")]) if file_path: video_path.set(file_path)
def select_model(): file_path = filedialog.askopenfilename(filetypes=[("ONNX files", "*.onnx")]) if file_path: model_path.set(file_path)
def process_and_play_video_ffstream(): video_path_str = video_path.get() model_path_str = model_path.get() engine_file_path = "model.engine"
if not video_path_str or not model_path_str:
messagebox.showerror("Error", "Please select both video file and model file")
return
device = torch.device('cuda')
if not os.path.exists(engine_file_path):
engine = build_engine(model_path_str, engine_file_path)
else:
with trt.Runtime(TRT_LOGGER) as runtime:
engine = load_engine(runtime, engine_file_path)
context = engine.create_execution_context()
input_shape = (1, 3, 1080, 1920) # ここで正しい入力シェイプを設定
inputs, outputs, bindings, stream = allocate_buffers(engine, context, input_shape)
ff = FFStream(video_path_str, None, crf=20, pix_fmt='yuv420p', copy_audio_stream=False, device=device)
while True:
frame_rgb = ff.get_rgb()
if frame_rgb is None:
break
frame_rgb = process_with_ai_engine(frame_rgb, engine, context, inputs, outputs, bindings, stream)
# Print the shape of the frame for debugging
print(f"Processed frame shape: {frame_rgb.shape}")
# Adjust the shape for visualization
frame_rgb = frame_rgb.squeeze(0) # Remove batch dimension if necessary
img = frame_rgb.cpu().numpy().transpose(1, 2, 0)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.imshow('Video', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
ff.close()
cv2.destroyAllWindows()
app = tk.Tk() app.title("Video Processing App")
video_path = tk.StringVar() model_path = tk.StringVar()
tk.Label(app, text="Select Video File:").grid(row=0, column=0, padx=10, pady=10) tk.Entry(app, textvariable=video_path, width=50).grid(row=0, column=1, padx=10, pady=10) tk.Button(app, text="Browse", command=select_video).grid(row=0, column=2, padx=10, pady=10)
tk.Label(app, text="Select ONNX Model File:").grid(row=1, column=0, padx=10, pady=10) tk.Entry(app, textvariable=model_path, width=50).grid(row=1, column=1, padx=10, pady=10) tk.Button(app, text="Browse", command=select_model).grid(row=1, column=2, padx=10, pady=10)
tk.Button(app, text="Process and Play Video", command=process_and_play_video_ffstream).grid(row=2, columnspan=3, padx=10, pady=20)
app.mainloop()
This is the 2xCompact model. It's black.
This is real-time playback.
TensorRT 10.2.0
def process_with_ai_engine(frame_rgb, engine):
↓ Traceback (most recent call last): File "C:\Users\ryou\AppData\Local\Programs\Python\Python311\Lib\tkinter__init.py", line 1948, in call__ return self.func(*args) ^^^^^^^^^^^^^^^^ File "C:\Smooth Video\video_degradation_app\main.py", line 133, in process_and_play_video_ffstream frame_rgb = process_with_ai_engine(frame_rgb, engine) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Smooth Video\video_degradation_app\main.py", line 72, in process_with_ai_engine input_binding_index = engine.get_binding_index(input_name) ^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'tensorrt_bindings.tensorrt.ICudaEngine' object has no attribute 'get_binding_index'
I don't understand this.