@jax.jit def render_chunk(params, o, d, rng): _, out_f, aux = render_rays(params, o, d, rng, deterministic=True) devuelve out_f.ray_values[“rgb”]out_f.ray_ Depth, out_f.ray_alpha, aux def render_image(params, origins, dirs, rng): “””Representación de imagen completa fragmentada con relleno, por lo que solo se compila una forma.””” o = jnp.asarray(origins.reshape(-1, 3)); d = jnp.asarray(dirs.reshape(-1, 3)) R = o.shape[0]; rgb, dep, alp = [], [], []
para i en rango(0, R, cfg.chunk): oc, dc = o[i:i + cfg.chunk]d[i:i + cfg.chunk]
pad = cfg.chunk – oc.forma[0]
si pad: oc = jnp.concatenate([oc, jnp.tile(oc[-1:](pad, 1))], 0) dc = jnp.concatenate([dc, jnp.tile(dc[-1:](pad, 1))], 0) c, dp, a, _ = render_chunk(params, oc, dc, rng) n = cfg.chunk – pad rgb.append(c[:n]); dep.append(dp[:n]); alp.append(a[:n]) s = (cfg.H, cfg.W) return (np.asarray(jnp.concatenate(rgb)).reshape(*s, 3), np.asarray(jnp.concatenate(dep)).reshape(*s), np.asarray(jnp.concatenate(alp)).reshape(*s)) h = np.array(history) plt.figure(tamaño de figura=(6, 3)) plt.plot(h[:, 0],h[:, 1]lw=1.6) plt.xlabel(“paso”); plt.ylabel(“entrenamiento PSNR (dB)”) plt.title(“Entrenamiento PSNR de red fina”); plt.grid(alfa=.3) plt.tight_layout(); plt.show() print(“\nRenderizando vistas de prueba retenidas …”) clave, k_eval = jax.random.split(key) psnrs = []
fig, axes = plt.subplots(cfg.n_test_views, 4, figsize=(11, 2.7 * cfg.n_test_views), squeeze=False) para v en rango(cfg.n_test_views): pred, profundidad, alfa = render_image(state.params, te_o[v]te_d[v]k_eval) p = float(mse_to_psnr(np.mean((pred – te_c[v]) ** 2))); psnrs.append(p) profundidad_vis = profundidad + (1.0 – alfa) * cfg.far para a, (im, ttl, kw) en zip(ejes[v], [
(np.clip(te_c[v]0, 1), “verdad sobre el terreno”, {}), (np.clip(pred, 0, 1), f”NeRF ({p:.2f} dB)”, {}), (profundidad_vis, “profundidad (ray_profundidad)”, dict(cmap=”turbo”, vmin=cfg.near, vmax=cfg.far)), (alpha, “opacity (ray_alpha)”, dict(cmap=”gray”, vmin=0, vmax=1))]): a.imshow(im, **kw); a.set_title(ttl, tamaño de fuente=9); a.axis(“off”) plt.suptitle(f”Síntesis de vista novedosa | mean PSNR = {np.mean(psnrs):.2f} dB”, fontsize=12) plt.tight_layout(); plt.show() print(f” significa PSNR retenido: {np.mean(psnrs):.2f} dB”) cy, cx = cfg.H // 2, cfg.W // 2 o1 = jnp.asarray(te_o[0][cy, cx])[None]; d1 = jnp.asarray(te_d[0][cy, cx])[None]
o1 = jnp.tile(o1, (cfg.chunk, 1)); d1 = jnp.tile(d1, (cfg.chunk, 1)) _, _, _, aux = render_chunk(state.params, o1, d1, k_eval) dc = np.asarray(aux[“depths_c”][0]); wc = np.asarray(aux[“weights_c”][0]) tf = np.asarray(aux[“t_fine”][0]) fig, ax = plt.subplots(figsize=(8, 3)) ax.bar(dc, wc, width=(cfg.far – cfg.near) / cfg.n_coarse * .9, alpha=.55, label=”pesos aproximados (el PDF)”) ax.plot(tf, np.full_like(tf, wc.max() * .06), “|”, ms=16, color=”crimson”, label=”muestras finas (sample_piecewise_constant_pdf)”) ax.set_xlabel(“profundidad a lo largo del rayo”); ax.set_ylabel(“peso”) ax.set_title(“El remuestreo de importancia concentra muestras en la superficie”) ax.legend(fontsize=8); plt.tight_layout(); plt.show() print(“\nRenderizando órbita de 360 grados …”) n_frames = 24 if jax.devices()[0].plataforma! = “cpu” más 8 fotogramas = []
para t en rango (n_frames): az = 2 * np.pi * t / n_frames; el = np.deg2rad(32.0) ojo = cfg.cam_radius * np.array([np.cos(el) * np.cos(az),
np.cos(el) * np.sin(az), np.sin(el)]) o, d = rayos_de_pose(look_at(ojo), cfg.H, cfg.W, FOCAL) rgb, _, _ = render_image(state.params, o, d, k_eval) frames.append((np.clip(rgb, 0, 1) * 255).astype(np.uint8)) gif_path = os.path.join(os.getcwd(), “nerf_orbit.gif”) pil = [Image.fromarray(f).resize((cfg.W * 3, cfg.H * 3), Image.NEAREST) for f in frames]
pil[0].save(gif_path, save_all=True, append_images=pil[1:]duración = 90, bucle = 0) intente: desde IPython.display importe la imagen como IPImage, muestre la pantalla (IPImage (nombre de archivo = ruta_gif)) excepto Excepción: pase print(” save”, gif_path) print(“\nExtrayendo isosuperficie del campo de densidad aprendido …”) intente: desde skimage importe importe g = np.linspace(-1.0, 1.0, cfg.grid_res, dtype=np.float32) X, Y, Z = np.meshgrid(g, g, g, indexing=”ij”) pts = np.stack([X, Y, Z]-1).reshape(-1, 3) @jax.jit def densidad_at(p): s, _ = model.apply(state.params[“fine”]p, jnp.zeros_like(p)) devuelve s vol = np.concatenate([np.asarray(density_at(jnp.asarray(pts[i:i + 65536]))) para i en el rango (0, pts.shape)[0]65536)]) vol = vol.reshape(cfg.grid_res, cfg.grid_res, cfg.grid_res) paso = (cfg.far – cfg.near) / (cfg.n_coarse + cfg.n_fine) nivel = float(-np.log(0.5) / paso) si no (vol.min() < nivel < vol.max()): nivel = float(np.percentile(vol, 99.0)) verts, faces, _, _ = medida.marching_cubes(vol, nivel=nivel) verts = -1.0 + verts * (2.0 / (cfg.grid_res - 1)) fig = plt.figure(figsize=(6, 6)); hacha = fig.add_subplot(111, proyección="3d") ax.plot_trisurf(verts[:, 0]verdes[:, 1]verdes[:, 2]triángulos=caras, cmap="viridis", lw=0.0, antialiased=False, alpha=.95) ax.set_box_aspect((1, 1, 1)) ax.set_xlim(-1, 1); hacha.set_ylim(-1, 1); ax.set_zlim(-1, 1) ax.view_init(elev=24, azim=-58) ax.set_title(f"Cubos marchando en densidad aprendida (sigma = {level:.1f}, " f"{len(faces):,} faces)", fontsize=10) plt.tight_layout(); plt.show() excepto Excepción como e: print(" paso de isosuperficie omitido:", e) print("\n" + "=" * 70) print(f"PSNR FINAL retenido: {np.mean(psnrs):.2f} dB ({n_params/1e6:.2f}M params, " f"{cfg.steps} pasos)") print("funciones jax3d ejercidas: sample_along_rays, volume_rendering, " "sample_piecewise_constant_pdf") print("=" * 70)
para i en rango(0, R, cfg.chunk): oc, dc = o[i:i + cfg.chunk]d[i:i + cfg.chunk]
pad = cfg.chunk – oc.forma[0]
si pad: oc = jnp.concatenate([oc, jnp.tile(oc[-1:](pad, 1))], 0) dc = jnp.concatenate([dc, jnp.tile(dc[-1:](pad, 1))], 0) c, dp, a, _ = render_chunk(params, oc, dc, rng) n = cfg.chunk – pad rgb.append(c[:n]); dep.append(dp[:n]); alp.append(a[:n]) s = (cfg.H, cfg.W) return (np.asarray(jnp.concatenate(rgb)).reshape(*s, 3), np.asarray(jnp.concatenate(dep)).reshape(*s), np.asarray(jnp.concatenate(alp)).reshape(*s)) h = np.array(history) plt.figure(tamaño de figura=(6, 3)) plt.plot(h[:, 0],h[:, 1]lw=1.6) plt.xlabel(“paso”); plt.ylabel(“entrenamiento PSNR (dB)”) plt.title(“Entrenamiento PSNR de red fina”); plt.grid(alfa=.3) plt.tight_layout(); plt.show() print(“\nRenderizando vistas de prueba retenidas …”) clave, k_eval = jax.random.split(key) psnrs = []
fig, axes = plt.subplots(cfg.n_test_views, 4, figsize=(11, 2.7 * cfg.n_test_views), squeeze=False) para v en rango(cfg.n_test_views): pred, profundidad, alfa = render_image(state.params, te_o[v]te_d[v]k_eval) p = float(mse_to_psnr(np.mean((pred – te_c[v]) ** 2))); psnrs.append(p) profundidad_vis = profundidad + (1.0 – alfa) * cfg.far para a, (im, ttl, kw) en zip(ejes[v], [
(np.clip(te_c[v]0, 1), “verdad sobre el terreno”, {}), (np.clip(pred, 0, 1), f”NeRF ({p:.2f} dB)”, {}), (profundidad_vis, “profundidad (ray_profundidad)”, dict(cmap=”turbo”, vmin=cfg.near, vmax=cfg.far)), (alpha, “opacity (ray_alpha)”, dict(cmap=”gray”, vmin=0, vmax=1))]): a.imshow(im, **kw); a.set_title(ttl, tamaño de fuente=9); a.axis(“off”) plt.suptitle(f”Síntesis de vista novedosa | mean PSNR = {np.mean(psnrs):.2f} dB”, fontsize=12) plt.tight_layout(); plt.show() print(f” significa PSNR retenido: {np.mean(psnrs):.2f} dB”) cy, cx = cfg.H // 2, cfg.W // 2 o1 = jnp.asarray(te_o[0][cy, cx])[None]; d1 = jnp.asarray(te_d[0][cy, cx])[None]
o1 = jnp.tile(o1, (cfg.chunk, 1)); d1 = jnp.tile(d1, (cfg.chunk, 1)) _, _, _, aux = render_chunk(state.params, o1, d1, k_eval) dc = np.asarray(aux[“depths_c”][0]); wc = np.asarray(aux[“weights_c”][0]) tf = np.asarray(aux[“t_fine”][0]) fig, ax = plt.subplots(figsize=(8, 3)) ax.bar(dc, wc, width=(cfg.far – cfg.near) / cfg.n_coarse * .9, alpha=.55, label=”pesos aproximados (el PDF)”) ax.plot(tf, np.full_like(tf, wc.max() * .06), “|”, ms=16, color=”crimson”, label=”muestras finas (sample_piecewise_constant_pdf)”) ax.set_xlabel(“profundidad a lo largo del rayo”); ax.set_ylabel(“peso”) ax.set_title(“El remuestreo de importancia concentra muestras en la superficie”) ax.legend(fontsize=8); plt.tight_layout(); plt.show() print(“\nRenderizando órbita de 360 grados …”) n_frames = 24 if jax.devices()[0].plataforma! = “cpu” más 8 fotogramas = []
para t en rango (n_frames): az = 2 * np.pi * t / n_frames; el = np.deg2rad(32.0) ojo = cfg.cam_radius * np.array([np.cos(el) * np.cos(az),
np.cos(el) * np.sin(az), np.sin(el)]) o, d = rayos_de_pose(look_at(ojo), cfg.H, cfg.W, FOCAL) rgb, _, _ = render_image(state.params, o, d, k_eval) frames.append((np.clip(rgb, 0, 1) * 255).astype(np.uint8)) gif_path = os.path.join(os.getcwd(), “nerf_orbit.gif”) pil = [Image.fromarray(f).resize((cfg.W * 3, cfg.H * 3), Image.NEAREST) for f in frames]
pil[0].save(gif_path, save_all=True, append_images=pil[1:]duración = 90, bucle = 0) intente: desde IPython.display importe la imagen como IPImage, muestre la pantalla (IPImage (nombre de archivo = ruta_gif)) excepto Excepción: pase print(” save”, gif_path) print(“\nExtrayendo isosuperficie del campo de densidad aprendido …”) intente: desde skimage importe importe g = np.linspace(-1.0, 1.0, cfg.grid_res, dtype=np.float32) X, Y, Z = np.meshgrid(g, g, g, indexing=”ij”) pts = np.stack([X, Y, Z]-1).reshape(-1, 3) @jax.jit def densidad_at(p): s, _ = model.apply(state.params[“fine”]p, jnp.zeros_like(p)) devuelve s vol = np.concatenate([np.asarray(density_at(jnp.asarray(pts[i:i + 65536]))) para i en el rango (0, pts.shape)[0]65536)]) vol = vol.reshape(cfg.grid_res, cfg.grid_res, cfg.grid_res) paso = (cfg.far – cfg.near) / (cfg.n_coarse + cfg.n_fine) nivel = float(-np.log(0.5) / paso) si no (vol.min() < nivel < vol.max()): nivel = float(np.percentile(vol, 99.0)) verts, faces, _, _ = medida.marching_cubes(vol, nivel=nivel) verts = -1.0 + verts * (2.0 / (cfg.grid_res - 1)) fig = plt.figure(figsize=(6, 6)); hacha = fig.add_subplot(111, proyección="3d") ax.plot_trisurf(verts[:, 0]verdes[:, 1]verdes[:, 2]triángulos=caras, cmap="viridis", lw=0.0, antialiased=False, alpha=.95) ax.set_box_aspect((1, 1, 1)) ax.set_xlim(-1, 1); hacha.set_ylim(-1, 1); ax.set_zlim(-1, 1) ax.view_init(elev=24, azim=-58) ax.set_title(f"Cubos marchando en densidad aprendida (sigma = {level:.1f}, " f"{len(faces):,} faces)", fontsize=10) plt.tight_layout(); plt.show() excepto Excepción como e: print(" paso de isosuperficie omitido:", e) print("\n" + "=" * 70) print(f"PSNR FINAL retenido: {np.mean(psnrs):.2f} dB ({n_params/1e6:.2f}M params, " f"{cfg.steps} pasos)") print("funciones jax3d ejercidas: sample_along_rays, volume_rendering, " "sample_piecewise_constant_pdf") print("=" * 70)