twanghcmut's picture
download
raw
3.56 kB
import argparse
import json
from pathlib import Path
import cv2
import mujoco
import numpy as np
from real2sim import video
from real2sim.geometry import MUJOCO_CAMERA_FROM_OPENCV, look_at_xyaxes, quat_wxyz
def main():
parser = argparse.ArgumentParser()
parser.add_argument("asset", type=Path)
args = parser.parse_args()
with np.load(args.asset) as saved:
vertices, faces, colors = (
saved["world_vertices"],
saved["faces"],
saved["colors"],
)
camera, intrinsics = saved["T_world_camera"], saved["intrinsics"]
spec = mujoco.MjSpec()
spec.visual.global_.offwidth, spec.visual.global_.offheight = 960, 640
spec.visual.headlight.ambient = [0.6, 0.6, 0.6]
spec.visual.headlight.diffuse = [0.4, 0.4, 0.4]
center = vertices.mean(axis=0)
spec.add_mesh(
name="object", uservert=(vertices - center).ravel(), userface=faces.ravel()
)
spec.worldbody.add_geom(
name="object",
type=mujoco.mjtGeom.mjGEOM_MESH,
meshname="object",
pos=center,
contype=0,
conaffinity=0,
rgba=[*np.mean(colors / 255, axis=0), 1],
)
mount = spec.worldbody.add_body(name="camera", mocap=True)
mount.add_camera(name="view", fovy=45)
model, data = spec.compile(), None
data = mujoco.MjData(model)
radius = max(np.linalg.norm(np.ptp(vertices, axis=0)), 0.03)
frames = []
with mujoco.Renderer(model, height=640, width=960) as renderer:
for angle in np.linspace(0, 2 * np.pi, 90, endpoint=False):
eye = center + radius * np.array(
[1.6 * np.cos(angle), 1.6 * np.sin(angle), 0.9]
)
xyaxes = np.asarray(look_at_xyaxes(eye, center)).reshape(2, 3)
matrix = np.column_stack((xyaxes[0], xyaxes[1], np.cross(*xyaxes)))
data.mocap_pos[0] = eye
data.mocap_quat[0] = quat_wxyz(matrix)
mujoco.mj_forward(model, data)
renderer.update_scene(data, camera="view")
frames.append(renderer.render().copy())
output = args.asset.parent
video.write(output / "object_orbit.mp4", frames, 30)
cv2.imwrite(
str(output / "object_preview.png"), cv2.cvtColor(frames[10], cv2.COLOR_RGB2BGR)
)
model.cam_fovy[0] = np.degrees(2 * np.arctan(294 / (2 * intrinsics[1, 1])))
data.mocap_pos[0] = camera[:3, 3]
data.mocap_quat[0] = quat_wxyz(camera[:3, :3] @ MUJOCO_CAMERA_FROM_OPENCV)
mujoco.mj_forward(model, data)
with mujoco.Renderer(model, height=294, width=518) as renderer:
renderer.enable_segmentation_rendering()
renderer.update_scene(data, camera="view")
mask = renderer.render()[..., 0] == model.geom("object").id
rgba = cv2.imread(str(output / "input.png"), cv2.IMREAD_UNCHANGED)
target = rgba[..., 3] > 0
metrics_path = output / "metrics.json"
metrics = json.loads(metrics_path.read_text())
metrics.update(
source_mask_iou=float(
np.count_nonzero(mask & target) / max(np.count_nonzero(mask | target), 1)
),
source_mask_pixels=int(np.count_nonzero(target)),
rendered_mask_pixels=int(np.count_nonzero(mask)),
)
metrics_path.write_text(json.dumps(metrics, indent=2) + "\n")
image = cv2.cvtColor(rgba[..., :3], cv2.COLOR_BGR2RGB)
image[mask] = (0.5 * image[mask] + 0.5 * np.array([255, 80, 80])).astype(np.uint8)
cv2.imwrite(str(output / "alignment.png"), cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
if __name__ == "__main__":
main()

Xet Storage Details

Size:
3.56 kB
·
Xet hash:
54a269694fca63a8b9fcfb7f199d9fceb7f6376610265f854098d5b753b6e8f0

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.