Instructions to use phi-lab-rice/GRADE with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use phi-lab-rice/GRADE with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("phi-lab-rice/GRADE", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
File size: 5,729 Bytes
0e150d6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | """
Helper to convert depth images (millimeters) to point clouds (meters)
using Open3D and the same pinhole camera model as pc_offiline.py
(verified accuracy). Intrinsics are scaled when depth resolution
differs from the reference 1280x720.
"""
import numpy as np
try:
import open3d as o3d
except ImportError:
o3d = None
class PointCloudConverter:
"""
Converts depth images (mm) to point clouds (m) using Open3D's
create_from_depth_image and pinhole model (same as pc_offiline.py).
Intrinsics are for the rectified left ZED camera at 1280x720.
"""
def __init__(self):
# ZED intrinsics at reference resolution 1280x720 (from calibrator.K_zed)
self._K = np.array(
[
[521.581604, 0.0, 636.33398438],
[0.0, 521.581604, 373.10964966],
[0.0, 0.0, 1.0],
],
dtype=np.float64,
)
self._ref_w = 1280
self._ref_h = 720
def scale_intrinsics(self, width: int, height: int) -> np.ndarray:
"""
Scale intrinsics to a different image size (e.g. when depth is not 1280x720).
Same scaling as pc_offiline (fx, fy, cx, cy scaled by width/ref_w and height/ref_h).
Parameters:
width: Image width (pixels).
height: Image height (pixels).
Returns:
K: 3x3 intrinsic matrix for the given resolution, dtype float64.
"""
sx = width / self._ref_w
sy = height / self._ref_h
K_scaled = np.array(
[
[self._K[0, 0] * sx, 0.0, self._K[0, 2] * sx],
[0.0, self._K[1, 1] * sy, self._K[1, 2] * sy],
[0.0, 0.0, 1.0],
],
dtype=np.float64,
)
return K_scaled
def depth_pixel_to_point(self, u: float, v: float, depth_m: float, width: int, height: int) -> np.ndarray:
"""
Back-project one depth pixel into metric camera coordinates.
Returns [x_right, y_down, z_forward] in meters.
"""
K = self.scale_intrinsics(width, height)
fx, fy = K[0, 0], K[1, 1]
cx, cy = K[0, 2], K[1, 2]
x = (float(u) - cx) * float(depth_m) / fx
y = (float(v) - cy) * float(depth_m) / fy
z = float(depth_m)
return np.array([x, y, z], dtype=np.float32)
def project_point_cloud_to_depth_image(
self,
points_xyz: np.ndarray,
width: int,
height: int,
depth_scale: float = 1000.0,
depth_max: float = 10.6,
) -> np.ndarray:
"""
Project camera-centered points [x_right, y_up, z_forward] to a depth image.
Returns a float32 depth image in meters on the requested image grid.
"""
if o3d is None:
raise ImportError("open3d is required for project_point_cloud_to_depth_image but is not installed")
if points_xyz.size == 0:
return np.zeros((height, width), dtype=np.float32)
points_cam = np.asarray(points_xyz, dtype=np.float32).copy()
points_cam[:, 1] *= -1.0 # Open3D pinhole projection uses image-space y-down.
pcd = o3d.t.geometry.PointCloud()
pcd.point["positions"] = o3d.core.Tensor(points_cam, dtype=o3d.core.Dtype.Float32)
intrinsics = o3d.core.Tensor(self.scale_intrinsics(width, height).astype(np.float32))
extrinsics = o3d.core.Tensor.eye(4, o3d.core.Dtype.Float32)
depth = pcd.project_to_depth_image(
width=width,
height=height,
intrinsics=intrinsics,
extrinsics=extrinsics,
depth_scale=float(depth_scale),
depth_max=float(depth_max),
)
depth_np = depth.as_tensor().numpy()
depth_np = np.asarray(depth_np).squeeze().astype(np.float32)
if depth_np.size == 0:
return np.zeros((height, width), dtype=np.float32)
if np.nanmax(depth_np) > depth_max + 1.0:
depth_np = depth_np / float(depth_scale)
return depth_np.astype(np.float32)
def depth_to_point_cloud(
self,
depth_mm: np.ndarray,
depth_scale: float = 1000.0,
max_depth_meters: float = 11.2,
) -> object:
"""
Convert depth image to point cloud using Open3D's pinhole back-projection
(same method as pc_offiline.depth_to_point_cloud_open3d). Depth in millimeters,
output points in meters.
Parameters:
depth_mm: Depth image, shape (H, W), dtype float (millimeters).
Invalid depth (0, NaN, inf, or > depth_trunc) is skipped.
Returns:
Open3D PointCloud with points in meters. Uses the same
depth_scale=depth_scale and depth_trunc=max_depth_meters.
"""
if o3d is None:
raise ImportError("open3d is required for depth_to_point_cloud but is not installed")
h, w = depth_mm.shape[:2]
K = self.scale_intrinsics(w, h)
fx, fy = K[0, 0], K[1, 1]
cx, cy = K[0, 2], K[1, 2]
o3d_intrinsic = o3d.camera.PinholeCameraIntrinsic(
width=w,
height=h,
fx=fx,
fy=fy,
cx=cx,
cy=cy,
)
depth_o3d = o3d.geometry.Image(depth_mm.astype(np.float32))
pcd = o3d.geometry.PointCloud.create_from_depth_image(
depth_o3d,
o3d_intrinsic,
depth_scale=depth_scale,
depth_trunc=max_depth_meters,
project_valid_depth_only=True,
)
return pcd
|