wzhouxiff
refined gradio
399e1c1
Raw
History Blame Contribute Delete
9.74 kB
import gradio as gr
from PIL import Image
import numpy as np
from copy import deepcopy
import cv2
from objctrl_2_5d.utils.vis_camera import vis_camera_rescale
from objctrl_2_5d.utils.objmask_util import trajectory_to_camera_poses_v1
from objctrl_2_5d.utils.customized_cam import rotation, clockwise, pan_and_zoom
CAMERA_MODE = ["None", "ZoomIn", "ZoomOut", "PanRight", "PanLeft", "TiltUp", "TiltDown", "ClockWise", "Anti-CW", "Rotate60"]
zc_threshold = 0.2
depth_scale_ = 5.2
center_margin = 10
height, width = 320, 576
num_frames = 14
intrinsics = np.array([[float(width), float(width), float(width) / 2, float(height) / 2]])
intrinsics = np.repeat(intrinsics, num_frames, axis=0) # [n_frame, 4]
fx = intrinsics[0, 0] / width
fy = intrinsics[0, 1] / height
cx = intrinsics[0, 2] / width
cy = intrinsics[0, 3] / height
def process_image(raw_image):
image, points = raw_image['image'], raw_image['points']
try:
assert(len(points)) == 1, "Please select only one point"
[x1, y1, _, x2, y2, _] = points[0]
image = image.crop((x1, y1, x2, y2))
image = image.resize((width, height))
except:
image = image.resize((width, height))
return image, gr.update(value={'image': image})
# -------------- general UI functionality --------------
def get_subject_points(canvas):
return canvas["image"], canvas["points"]
def mask_image(image,
mask,
color=[255,0,0],
alpha=0.5):
""" Overlay mask on image for visualization purpose.
Args:
image (H, W, 3) or (H, W): input image
mask (H, W): mask to be overlaid
color: the color of overlaid mask
alpha: the transparency of the mask
"""
out = deepcopy(image)
img = deepcopy(image)
img[mask == 1] = color
out = cv2.addWeighted(img, alpha, out, 1-alpha, 0, out)
return out
def get_points(img,
sel_pix,
evt: gr.SelectData):
# collect the selected point
img = np.array(img)
img = deepcopy(img)
sel_pix.append(evt.index)
# only draw the last two points
# if len(sel_pix) > 2:
# sel_pix = sel_pix[-2:]
points = []
for idx, point in enumerate(sel_pix):
if idx % 2 == 0:
# draw a red circle at the handle point
cv2.circle(img, tuple(point), 10, (255, 0, 0), -1)
else:
# draw a blue circle at the handle point
cv2.circle(img, tuple(point), 10, (0, 0, 255), -1)
points.append(tuple(point))
# draw an arrow from handle point to target point
# if len(points) == idx + 1:
if idx > 0:
line_length = np.sqrt((points[idx][0] - points[idx-1][0])**2 + (points[idx][1] - points[idx-1][1])**2)
arrow_head_length = 10
tip_length = arrow_head_length / line_length
cv2.arrowedLine(img, points[idx-1], points[idx], (0, 255, 0), 4, tipLength=tip_length)
# points = []
return img if isinstance(img, np.ndarray) else np.array(img), sel_pix
# clear all handle/target points
def undo_points(original_image):
return original_image, []
def interpolate_points(points, num_points):
x = points[:, 0]
y = points[:, 1]
# Interpolating the points
t = np.linspace(0, 1, len(points))
t_new = np.linspace(0, 1, num_points)
x_new = np.interp(t_new, t, x)
y_new = np.interp(t_new, t, y)
return np.vstack((x_new, y_new)).T # []
def traj2cam(traj, depth, rescale):
if len(traj) == 0:
return None, None, 0.0, gr.update(value=CAMERA_MODE[0])
traj = np.array(traj)
trajectory = interpolate_points(traj, num_frames)
center_h_margin, center_w_margin = center_margin, center_margin
depth_center = np.mean(depth[height//2-center_h_margin:height//2+center_h_margin, width//2-center_w_margin:width//2+center_w_margin])
if rescale == 0:
rescale = 1
depth_rescale = round(depth_scale_ * rescale / depth_center, 2)
r_depth = depth * depth_rescale
zc = []
for i in range(num_frames):
zc.append(r_depth[int(trajectory[i][1]), int(trajectory[i][0])])
# print(f'zc: {zc}')
## norm zc
zc_norm = np.array(zc)
zc_grad = zc_norm[1:] - zc_norm[:-1]
zc_grad = np.abs(zc_grad)
zc_grad = zc_grad[1:] - zc_grad[:-1]
zc_grad_std = np.std(zc_grad)
if zc_grad_std > zc_threshold:
zc = [zc[0]] * num_frames
# print(f'zc_grad_std: {zc_grad_std}, zc_threshold: {zc_threshold}')
# print(f'zc: {zc}')
traj_w2c = trajectory_to_camera_poses_v1(trajectory, intrinsics, num_frames, zc=zc) # numpy: [n_frame, 4, 4]
RTs = traj_w2c[:, :3]
fig = vis_camera_rescale(RTs)
return RTs, fig, rescale, gr.update(value=CAMERA_MODE[0])
def get_rotate_cam(angle, depth):
# mean_depth = np.mean(depth * mask)
center_h_margin, center_w_margin = center_margin, center_margin
depth_center = np.mean(depth[height//2-center_h_margin:height//2+center_h_margin, width//2-center_w_margin:width//2+center_w_margin])
# print(f'rotate depth_center: {depth_center}')
RTs = rotation(num_frames, angle, depth_center, depth_center)
fig = vis_camera_rescale(RTs)
return RTs, fig
def get_clockwise_cam(angle, depth, mask):
# mask = mask.astype(np.float32) # [0, 1]
# mean_depth = np.mean(depth * mask)
# center_h_margin, center_w_margin = center_margin, center_margin
# depth_center = np.mean(depth[height//2-center_h_margin:height//2+center_h_margin, width//2-center_w_margin:width//2+center_w_margin])
RTs = clockwise(angle, num_frames)
# RTs[:, -1, -1] = mean_depth
fig = vis_camera_rescale(RTs)
return RTs, fig
def get_translate_cam(Tx, Ty, Tz, depth, mask, speed):
# mask = mask.astype(np.float32) # [0, 1]
# mean_depth = np.mean(depth * mask)
T = np.array([Tx, Ty, Tz])
T = T.reshape(3, 1)
T = T[None, ...].repeat(num_frames, axis=0)
RTs = pan_and_zoom(T, speed, n=num_frames)
# RTs[:, -1, -1] += mean_depth
fig = vis_camera_rescale(RTs)
return RTs, fig
def get_camera_pose(camera_mode):
# camera_mode = ["None", "ZoomIn", "ZoomOut", "PanLeft", "PanRight", "TiltUp", "TiltDown", "ClockWise", "Anti-CW", "Rotate60"]
def trigger_camera_pose(camera_option, depth, mask, rescale, angle, speed):
if camera_option == camera_mode[0]: # None
RTs = None
fig = None
elif camera_option == camera_mode[1]: # ZoomIn
RTs, fig = get_translate_cam(0, 0, -1, depth, mask, speed)
elif camera_option == camera_mode[2]: # ZoomOut
RTs, fig = get_translate_cam(0, 0, 1, depth, mask, speed)
elif camera_option == camera_mode[3]: # PanLeft
RTs, fig = get_translate_cam(-1, 0, 0, depth, mask, speed)
elif camera_option == camera_mode[4]: # PanRight
RTs, fig = get_translate_cam(1, 0, 0, depth, mask, speed)
elif camera_option == camera_mode[5]: # TiltUp
RTs, fig = get_translate_cam(0, 1, 0, depth, mask, speed)
elif camera_option == camera_mode[6]: # TiltDown
RTs, fig = get_translate_cam(0, -1, 0, depth, mask, speed)
elif camera_option == camera_mode[7]: # ClockWise
RTs, fig = get_clockwise_cam(-angle, depth, mask)
elif camera_option == camera_mode[8]: # Anti-CW
RTs, fig = get_clockwise_cam(angle, depth, mask)
else: # Rotate60
RTs, fig = get_rotate_cam(angle, depth)
rescale = 0.0
return RTs, fig, rescale
return trigger_camera_pose
import os
from glob import glob
import json
def get_mid_params(raw_input, canvas, mask, selected_points, camera_option, bg_mode, shared_wapring_latents, generated_video):
output_dir = "./assets/examples"
os.makedirs(output_dir, exist_ok=True)
# folders = sorted(glob(output_dir + "/*"))
folders = os.listdir(output_dir)
folders = [int(folder) for folder in folders if os.path.isdir(os.path.join(output_dir, folder))]
num = sorted(folders)[-1] + 1 if folders else 0
fout = open(os.path.join(output_dir, f'examples.json'), 'a+')
cur_folder = os.path.join(output_dir, f'{num:05d}')
os.makedirs(cur_folder, exist_ok=True)
raw_image = raw_input['image']
raw_points = raw_input['points']
seg_image = canvas['image']
seg_points = canvas['points']
mask = Image.fromarray(mask)
mask_path = os.path.join(cur_folder, 'mask.png')
mask.save(mask_path)
raw_image_path = os.path.join(cur_folder, 'raw_image.png')
seg_image_path = os.path.join(cur_folder, 'seg_image.png')
raw_image.save(os.path.join(cur_folder, 'raw_image.png'))
seg_image.save(os.path.join(cur_folder, 'seg_image.png'))
gen_path = os.path.join(cur_folder, 'generated_video.mp4')
cmd = f"cp {generated_video} {gen_path}"
os.system(cmd)
# data = [{'image': raw_image_path, 'points': raw_points},
# {'image': seg_image_path, 'points': seg_points},
# mask_path,
# str(selected_points),
# camera_option,
# bg_mode,
# gen_path]
data = {f'{num:05d}': [{'image': raw_image_path},
str(raw_points),
{'image': seg_image_path},
str(seg_points),
mask_path,
str(selected_points),
camera_option,
bg_mode,
shared_wapring_latents,
gen_path]}
fout.write(json.dumps(data) + '\n')
fout.close()