40 lines
1.9 KiB
Python
40 lines
1.9 KiB
Python
import torch
|
|
import numpy as np
|
|
import math
|
|
|
|
def compute_f_pixels(camera_angle_x: float, resolution: int) -> float:
|
|
focal_length = 16.0 / torch.tan(torch.tensor(camera_angle_x / 2.0))
|
|
f_pixels = focal_length * resolution / 32.0
|
|
return float(f_pixels.item())
|
|
|
|
def distance_from_fov(camera_angle_x, grid_point, target_point, mesh_scale, image_resolution):
|
|
rotation_matrix = torch.tensor([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]])
|
|
gp = grid_point.to(torch.float32) @ rotation_matrix.T
|
|
gp = gp / mesh_scale / 2
|
|
xw, yw, zw = gp[0].item(), gp[1].item(), gp[2].item()
|
|
xt, yt = float(target_point[0].item()), float(target_point[1].item())
|
|
f_pixels = compute_f_pixels(camera_angle_x, image_resolution)
|
|
x_ndc = xt - image_resolution / 2.0
|
|
y_ndc = -(yt - image_resolution / 2.0)
|
|
distance_x = f_pixels * xw / x_ndc - yw
|
|
return {"distance_from_x": float(distance_x), "f_pixels": float(f_pixels)}
|
|
|
|
def get_camera_params_wild_moge(pil_image, moge_model, device="cuda", mesh_scale=1.0, extend_pixel=0, image_resolution=512):
|
|
#pil_image = Image.open(image_path).convert("RGB")
|
|
width, height = pil_image.size
|
|
image_np = np.array(pil_image).astype(np.float32) / 255.0
|
|
image_tensor = torch.from_numpy(image_np).permute(2, 0, 1).to(device)
|
|
with torch.no_grad():
|
|
output = moge_model.infer(image_tensor)
|
|
intrinsics = output["intrinsics"].squeeze().cpu().numpy()
|
|
fx_normalized = intrinsics[0, 0]
|
|
fx = fx_normalized * width
|
|
camera_angle_x = 2 * math.atan(width / (2 * fx))
|
|
|
|
grid_point = torch.tensor([-1.0, 0.0, 0.0])
|
|
distance = distance_from_fov(
|
|
camera_angle_x, grid_point,
|
|
torch.tensor([0 - extend_pixel, image_resolution - 1 + extend_pixel]),
|
|
mesh_scale, image_resolution
|
|
)["distance_from_x"]
|
|
return {'camera_angle_x': camera_angle_x, 'distance': distance, 'mesh_scale': mesh_scale} |