Spaces:
Running
on
Zero
Running
on
Zero
Depth Updates
Browse files- README.md +1 -1
- app.py +154 -107
- images/prerendered/Firefly_topographical_moon_1.png +2 -2
- images/prerendered/Genison.png +2 -2
- images/prerendered/{cute3dkawaii.PNG → cute3dkawaii.png} +0 -0
- images/prerendered/donald_park.png +2 -2
- utils/constants.py +3 -3
- utils/depth_estimation.py +147 -1
- utils/version_info.py +8 -0
README.md
CHANGED
|
@@ -5,7 +5,7 @@ colorFrom: yellow
|
|
| 5 |
colorTo: purple
|
| 6 |
sdk: gradio
|
| 7 |
python_version: 3.10.13
|
| 8 |
-
sdk_version: 5.
|
| 9 |
app_file: app.py
|
| 10 |
pinned: true
|
| 11 |
short_description: Transform Your Images into Mesmerizing Hexagon Grids
|
|
|
|
| 5 |
colorTo: purple
|
| 6 |
sdk: gradio
|
| 7 |
python_version: 3.10.13
|
| 8 |
+
sdk_version: 5.17.0
|
| 9 |
app_file: app.py
|
| 10 |
pinned: true
|
| 11 |
short_description: Transform Your Images into Mesmerizing Hexagon Grids
|
app.py
CHANGED
|
@@ -18,6 +18,7 @@ import random
|
|
| 18 |
#import accelerate
|
| 19 |
from transformers import AutoTokenizer , DPTImageProcessor, DPTForDepthEstimation
|
| 20 |
from pathlib import Path
|
|
|
|
| 21 |
import logging
|
| 22 |
#logging.getLogger("transformers.modeling_utils").setLevel(logging.ERROR)
|
| 23 |
import gc
|
|
@@ -88,7 +89,10 @@ PIPELINE_CLASSES = {
|
|
| 88 |
}
|
| 89 |
|
| 90 |
import spaces
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
|
| 94 |
input_image_palette = []
|
|
@@ -695,132 +699,157 @@ def add_border(image, mask_width, mask_height, blank_color):
|
|
| 695 |
|
| 696 |
################################## DEPTH ESTIMATION ##################################
|
| 697 |
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
@spaces.GPU()
|
| 703 |
-
def estimate_depth(image):
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
# Ensure image is in RGB mode
|
| 707 |
-
if image.mode != "RGB":
|
| 708 |
-
image = image.convert("RGB")
|
| 709 |
-
|
| 710 |
-
# Resize the image for the model
|
| 711 |
-
image_resized = image.resize(
|
| 712 |
-
(image.width, image.height),
|
| 713 |
-
Image.Resampling.LANCZOS
|
| 714 |
-
)
|
| 715 |
-
|
| 716 |
-
# Prepare image for the model
|
| 717 |
-
encoding = image_processor(image_resized, return_tensors="pt")
|
| 718 |
-
|
| 719 |
-
# Forward pass
|
| 720 |
-
with torch.no_grad():
|
| 721 |
-
outputs = depth_model(**encoding)
|
| 722 |
-
predicted_depth = outputs.predicted_depth
|
| 723 |
-
|
| 724 |
-
# Interpolate to original size
|
| 725 |
-
prediction = torch.nn.functional.interpolate(
|
| 726 |
-
predicted_depth.unsqueeze(1),
|
| 727 |
-
size=(image.height, image.width),
|
| 728 |
-
mode="bicubic",
|
| 729 |
-
align_corners=False,
|
| 730 |
-
).squeeze()
|
| 731 |
-
|
| 732 |
-
# Convert to depth image
|
| 733 |
-
output = prediction.cpu().numpy()
|
| 734 |
-
depth_min = output.min()
|
| 735 |
-
depth_max = output.max()
|
| 736 |
-
max_val = (2**8) - 1
|
| 737 |
-
|
| 738 |
-
# Normalize and convert to 8-bit image
|
| 739 |
-
depth_image = max_val * (output - depth_min) / (depth_max - depth_min)
|
| 740 |
-
depth_image = depth_image.astype("uint8")
|
| 741 |
-
|
| 742 |
-
depth_pil = Image.fromarray(depth_image)
|
| 743 |
|
| 744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 745 |
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
|
|
|
|
|
|
| 751 |
|
|
|
|
| 752 |
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
|
| 753 |
-
|
| 754 |
-
depth_o3d,
|
| 755 |
-
convert_rgb_to_intensity=False,
|
| 756 |
)
|
| 757 |
|
| 758 |
-
|
|
|
|
|
|
|
| 759 |
camera_intrinsic = o3d.camera.PinholeCameraIntrinsic(
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
fx=
|
| 763 |
-
fy=
|
| 764 |
-
cx=
|
| 765 |
-
cy=
|
| 766 |
)
|
| 767 |
|
| 768 |
-
|
| 769 |
-
|
| 770 |
-
|
| 771 |
-
|
| 772 |
-
|
| 773 |
-
|
| 774 |
-
|
| 775 |
-
|
| 776 |
-
|
|
|
|
|
|
|
| 777 |
pcd.estimate_normals(
|
| 778 |
-
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=
|
| 779 |
)
|
| 780 |
-
pcd.orient_normals_towards_camera_location(
|
| 781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 782 |
)
|
| 783 |
-
|
| 784 |
-
pcd.transform([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
|
| 785 |
-
# ########
|
| 786 |
-
print(f"run Poisson surface reconstruction: depth {depth}")
|
| 787 |
-
with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:
|
| 788 |
-
mesh_raw, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
|
| 789 |
-
pcd, depth=depth, width=0, scale=1.1, linear_fit=True
|
| 790 |
-
)
|
| 791 |
|
| 792 |
-
#
|
| 793 |
-
voxel_size = max(
|
| 794 |
-
print(f"voxel_size = {voxel_size:e}")
|
| 795 |
-
#voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd, voxel_size=voxel_size)
|
| 796 |
mesh = mesh_raw.simplify_vertex_clustering(
|
| 797 |
voxel_size=voxel_size,
|
| 798 |
contraction=o3d.geometry.SimplificationContraction.Average,
|
| 799 |
)
|
|
|
|
| 800 |
|
| 801 |
-
#
|
| 802 |
-
# mesh.remove_vertices_by_mask(vertices_to_remove)
|
| 803 |
bbox = pcd.get_axis_aligned_bounding_box()
|
| 804 |
mesh_crop = mesh.crop(bbox)
|
| 805 |
|
| 806 |
-
# Save the
|
| 807 |
-
temp_dir = Path.cwd() / "
|
| 808 |
temp_dir.mkdir(exist_ok=True)
|
| 809 |
-
|
| 810 |
-
|
| 811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 812 |
|
| 813 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 814 |
|
| 815 |
-
|
| 816 |
-
|
| 817 |
-
resized_image = resize_image_with_aspect_ratio(image, 2688, 1680)
|
| 818 |
-
depth_image, depth_array = estimate_depth(resized_image)
|
| 819 |
-
model_path = create_3d_model(resized_image, depth_array, voxel_size_factor=voxel_size_factor)
|
| 820 |
-
return depth_image, model_path
|
| 821 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 822 |
|
| 823 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 824 |
if depth_image_source == "Input Image":
|
| 825 |
image_path = input_image
|
| 826 |
elif depth_image_source == "Output Image":
|
|
@@ -830,7 +859,7 @@ def generate_depth_button_click(depth_image_source, voxel_size_factor, input_ima
|
|
| 830 |
else:
|
| 831 |
image_path = overlay_image
|
| 832 |
|
| 833 |
-
return generate_depth_and_3d(image_path,
|
| 834 |
|
| 835 |
|
| 836 |
def getVersions():
|
|
@@ -1138,14 +1167,32 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 1138 |
with gr.Accordion("Height Maps and 3D", open = False):
|
| 1139 |
with gr.Row():
|
| 1140 |
with gr.Column():
|
| 1141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1142 |
with gr.Column():
|
| 1143 |
depth_image_source = gr.Radio(label="Depth Image Source", choices=["Input Image", "Output Image", "Overlay Image","Image with Margins"], value="Input Image")
|
| 1144 |
with gr.Row():
|
| 1145 |
generate_depth_button = gr.Button("Generate Depth Map and 3D Model From Selected Image", elem_classes="solid", variant="secondary")
|
| 1146 |
with gr.Row():
|
| 1147 |
-
|
| 1148 |
-
|
|
|
|
|
|
|
|
|
|
| 1149 |
with gr.Row():
|
| 1150 |
gr.Examples(examples=[
|
| 1151 |
["assets//examples//hex_map_p1.png", False, True, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 15],
|
|
@@ -1178,8 +1225,8 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 1178 |
)
|
| 1179 |
generate_depth_button.click(
|
| 1180 |
fn=generate_depth_button_click,
|
| 1181 |
-
inputs=[depth_image_source,
|
| 1182 |
-
outputs=[depth_map_output, model_output], scroll_to_output=True
|
| 1183 |
)
|
| 1184 |
model_textbox.change(
|
| 1185 |
fn=update_prompt_notes,
|
|
|
|
| 18 |
#import accelerate
|
| 19 |
from transformers import AutoTokenizer , DPTImageProcessor, DPTForDepthEstimation
|
| 20 |
from pathlib import Path
|
| 21 |
+
import open3d as o3d
|
| 22 |
import logging
|
| 23 |
#logging.getLogger("transformers.modeling_utils").setLevel(logging.ERROR)
|
| 24 |
import gc
|
|
|
|
| 89 |
}
|
| 90 |
|
| 91 |
import spaces
|
| 92 |
+
#-------------- ------------------------------------------------MODEL INITIALIZATION------------------------------------------------------------#
|
| 93 |
+
# Load models once during module import
|
| 94 |
+
image_processor = DPTImageProcessor.from_pretrained("Intel/dpt-large",)
|
| 95 |
+
depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large", ignore_mismatched_sizes=True)
|
| 96 |
|
| 97 |
|
| 98 |
input_image_palette = []
|
|
|
|
| 699 |
|
| 700 |
################################## DEPTH ESTIMATION ##################################
|
| 701 |
|
| 702 |
+
def create_3d_obj(rgb_image, raw_depth, image_path, depth=10, z_scale=200):
|
| 703 |
+
"""
|
| 704 |
+
Creates a 3D object from RGB and depth images.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 705 |
|
| 706 |
+
Args:
|
| 707 |
+
rgb_image (np.ndarray): The RGB image as a NumPy array.
|
| 708 |
+
raw_depth (np.ndarray): The raw depth data.
|
| 709 |
+
image_path (Path): The path to the original image.
|
| 710 |
+
depth (int, optional): Depth parameter for Poisson reconstruction. Defaults to 10.
|
| 711 |
+
z_scale (float, optional): Scaling factor for the Z-axis. Defaults to 200.
|
| 712 |
|
| 713 |
+
Returns:
|
| 714 |
+
str: The file path to the saved GLTF model.
|
| 715 |
+
"""
|
| 716 |
+
# Normalize the depth image
|
| 717 |
+
depth_image = ((raw_depth - raw_depth.min()) / (raw_depth.max() - raw_depth.min()) * 255).astype("uint8")
|
| 718 |
+
depth_o3d = o3d.geometry.Image(depth_image)
|
| 719 |
+
image_o3d = o3d.geometry.Image(rgb_image)
|
| 720 |
|
| 721 |
+
# Create RGBD image
|
| 722 |
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
|
| 723 |
+
image_o3d, depth_o3d, convert_rgb_to_intensity=False
|
|
|
|
|
|
|
| 724 |
)
|
| 725 |
|
| 726 |
+
height, width = depth_image.shape
|
| 727 |
+
|
| 728 |
+
# Define camera intrinsics
|
| 729 |
camera_intrinsic = o3d.camera.PinholeCameraIntrinsic(
|
| 730 |
+
width,
|
| 731 |
+
height,
|
| 732 |
+
fx=z_scale,
|
| 733 |
+
fy=z_scale,
|
| 734 |
+
cx=width / 2.0,
|
| 735 |
+
cy=height / 2.0,
|
| 736 |
)
|
| 737 |
|
| 738 |
+
# Generate point cloud from RGBD image
|
| 739 |
+
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, camera_intrinsic)
|
| 740 |
+
|
| 741 |
+
# Scale the Z dimension
|
| 742 |
+
points = np.asarray(pcd.points)
|
| 743 |
+
depth_scaled = ((raw_depth - raw_depth.min()) / (raw_depth.max() - raw_depth.min())) * (z_scale*100)
|
| 744 |
+
z_values = depth_scaled.flatten()[:len(points)]
|
| 745 |
+
points[:, 2] *= z_values
|
| 746 |
+
pcd.points = o3d.utility.Vector3dVector(points)
|
| 747 |
+
|
| 748 |
+
# Estimate and orient normals
|
| 749 |
pcd.estimate_normals(
|
| 750 |
+
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=60)
|
| 751 |
)
|
| 752 |
+
pcd.orient_normals_towards_camera_location(camera_location=np.array([0.0, 0.0, 1.5 ]))
|
| 753 |
+
|
| 754 |
+
# Apply transformations
|
| 755 |
+
pcd.transform([[1, 0, 0, 0],
|
| 756 |
+
[0, -1, 0, 0],
|
| 757 |
+
[0, 0, -1, 0],
|
| 758 |
+
[0, 0, 0, 1]])
|
| 759 |
+
pcd.transform([[-1, 0, 0, 0],
|
| 760 |
+
[0, 1, 0, 0],
|
| 761 |
+
[0, 0, 1, 0],
|
| 762 |
+
[0, 0, 0, 1]])
|
| 763 |
+
|
| 764 |
+
# Perform Poisson surface reconstruction
|
| 765 |
+
print(f"Running Poisson surface reconstruction with depth {depth}")
|
| 766 |
+
mesh_raw, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
|
| 767 |
+
pcd, depth=depth, width=0, scale=1.1, linear_fit=True
|
| 768 |
)
|
| 769 |
+
print(f"Raw mesh vertices: {len(mesh_raw.vertices)}, triangles: {len(mesh_raw.triangles)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 770 |
|
| 771 |
+
# Simplify the mesh using vertex clustering
|
| 772 |
+
voxel_size = max(mesh_raw.get_max_bound() - mesh_raw.get_min_bound()) / (max(width, height) * 0.8)
|
|
|
|
|
|
|
| 773 |
mesh = mesh_raw.simplify_vertex_clustering(
|
| 774 |
voxel_size=voxel_size,
|
| 775 |
contraction=o3d.geometry.SimplificationContraction.Average,
|
| 776 |
)
|
| 777 |
+
print(f"Simplified mesh vertices: {len(mesh.vertices)}, triangles: {len(mesh.triangles)}")
|
| 778 |
|
| 779 |
+
# Crop the mesh to the bounding box of the point cloud
|
|
|
|
| 780 |
bbox = pcd.get_axis_aligned_bounding_box()
|
| 781 |
mesh_crop = mesh.crop(bbox)
|
| 782 |
|
| 783 |
+
# Save the mesh as a GLTF file
|
| 784 |
+
temp_dir = Path.cwd() / "models"
|
| 785 |
temp_dir.mkdir(exist_ok=True)
|
| 786 |
+
gltf_path = str(temp_dir / f"{image_path.stem}.gltf")
|
| 787 |
+
o3d.io.write_triangle_mesh(gltf_path, mesh_crop, write_triangle_uvs=True)
|
| 788 |
+
return gltf_path
|
| 789 |
+
|
| 790 |
+
@spaces.GPU()
|
| 791 |
+
def depth_process_image(image_path, resized_width=800, z_scale=208):
|
| 792 |
+
"""
|
| 793 |
+
Processes the input image to generate a depth map and a 3D mesh reconstruction.
|
| 794 |
+
|
| 795 |
+
Args:
|
| 796 |
+
image_path (str): The file path to the input image.
|
| 797 |
|
| 798 |
+
Returns:
|
| 799 |
+
list: A list containing the depth image, 3D mesh reconstruction, and GLTF file path.
|
| 800 |
+
"""
|
| 801 |
+
image_path = Path(image_path)
|
| 802 |
+
if not image_path.exists():
|
| 803 |
+
raise ValueError("Image file not found")
|
| 804 |
+
|
| 805 |
+
# Load and resize the image
|
| 806 |
+
image_raw = Image.open(image_path).convert("RGB")
|
| 807 |
+
print(f"Original size: {image_raw.size}")
|
| 808 |
+
resized_height = int(resized_width * image_raw.size[1] / image_raw.size[0])
|
| 809 |
+
image = image_raw.resize((resized_width, resized_height), Image.Resampling.LANCZOS)
|
| 810 |
+
print(f"Resized size: {image.size}")
|
| 811 |
|
| 812 |
+
# Prepare image for the model
|
| 813 |
+
encoding = image_processor(image, return_tensors="pt")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 814 |
|
| 815 |
+
# Perform depth estimation
|
| 816 |
+
with torch.no_grad():
|
| 817 |
+
outputs = depth_model(**encoding)
|
| 818 |
+
predicted_depth = outputs.predicted_depth
|
| 819 |
|
| 820 |
+
# Interpolate depth to match the image size
|
| 821 |
+
prediction = torch.nn.functional.interpolate(
|
| 822 |
+
predicted_depth.unsqueeze(1),
|
| 823 |
+
size=(image.height, image.width),
|
| 824 |
+
mode="bicubic",
|
| 825 |
+
align_corners=False,
|
| 826 |
+
).squeeze()
|
| 827 |
+
|
| 828 |
+
# Normalize the depth image to 8-bit
|
| 829 |
+
if torch.cuda.is_available():
|
| 830 |
+
prediction = prediction.numpy()
|
| 831 |
+
else:
|
| 832 |
+
prediction = prediction.cpu().numpy()
|
| 833 |
+
depth_min, depth_max = prediction.min(), prediction.max()
|
| 834 |
+
depth_image = ((prediction - depth_min) / (depth_max - depth_min) * 255).astype("uint8")
|
| 835 |
+
|
| 836 |
+
try:
|
| 837 |
+
gltf_path = create_3d_obj(np.array(image), prediction, image_path, depth=10, z_scale=z_scale)
|
| 838 |
+
except Exception:
|
| 839 |
+
gltf_path = create_3d_obj(np.array(image), prediction, image_path, depth=8, z_scale=z_scale)
|
| 840 |
+
|
| 841 |
+
img = Image.fromarray(depth_image)
|
| 842 |
+
|
| 843 |
+
if torch.cuda.is_available():
|
| 844 |
+
torch.cuda.empty_cache()
|
| 845 |
+
torch.cuda.ipc_collect()
|
| 846 |
+
return [img, gltf_path, gltf_path]
|
| 847 |
+
|
| 848 |
+
def generate_depth_and_3d(input_image_path, resize_width=800, z_scale=1.0):
|
| 849 |
+
return depth_process_image(input_image_path, resize_width, z_scale)
|
| 850 |
+
|
| 851 |
+
|
| 852 |
+
def generate_depth_button_click(depth_image_source, resize_width, z_scale, input_image, output_image, overlay_image, bordered_image_output):
|
| 853 |
if depth_image_source == "Input Image":
|
| 854 |
image_path = input_image
|
| 855 |
elif depth_image_source == "Output Image":
|
|
|
|
| 859 |
else:
|
| 860 |
image_path = overlay_image
|
| 861 |
|
| 862 |
+
return generate_depth_and_3d(image_path, resize_width, z_scale)
|
| 863 |
|
| 864 |
|
| 865 |
def getVersions():
|
|
|
|
| 1167 |
with gr.Accordion("Height Maps and 3D", open = False):
|
| 1168 |
with gr.Row():
|
| 1169 |
with gr.Column():
|
| 1170 |
+
resized_width_slider = gr.Slider(
|
| 1171 |
+
minimum=256,
|
| 1172 |
+
maximum=1760,
|
| 1173 |
+
step=16,
|
| 1174 |
+
value=800,
|
| 1175 |
+
label="Resized Width",
|
| 1176 |
+
info="Adjust the width to which the input image is resized."
|
| 1177 |
+
)
|
| 1178 |
+
z_scale_slider = gr.Slider(
|
| 1179 |
+
minimum=0.2,
|
| 1180 |
+
maximum=3.0,
|
| 1181 |
+
step=0.01,
|
| 1182 |
+
value=0.5,
|
| 1183 |
+
label="Z-Scale",
|
| 1184 |
+
info="Adjust the scaling factor for the Z-axis in the 3D model."
|
| 1185 |
+
)
|
| 1186 |
with gr.Column():
|
| 1187 |
depth_image_source = gr.Radio(label="Depth Image Source", choices=["Input Image", "Output Image", "Overlay Image","Image with Margins"], value="Input Image")
|
| 1188 |
with gr.Row():
|
| 1189 |
generate_depth_button = gr.Button("Generate Depth Map and 3D Model From Selected Image", elem_classes="solid", variant="secondary")
|
| 1190 |
with gr.Row():
|
| 1191 |
+
with gr.Column(scale=1):
|
| 1192 |
+
depth_map_output = gr.Image(label="Depth Map", image_mode="L", elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgDepth")
|
| 1193 |
+
with gr.Column(scale=2):
|
| 1194 |
+
model_output = gr.Model3D(label="3D Model", clear_color=[1.0, 1.0, 1.0, 1.0], key="Img3D", elem_classes="centered solid imgcontainer")
|
| 1195 |
+
model_file = gr.File(label="3D GLTF", elem_classes="solid small centered")
|
| 1196 |
with gr.Row():
|
| 1197 |
gr.Examples(examples=[
|
| 1198 |
["assets//examples//hex_map_p1.png", False, True, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 15],
|
|
|
|
| 1225 |
)
|
| 1226 |
generate_depth_button.click(
|
| 1227 |
fn=generate_depth_button_click,
|
| 1228 |
+
inputs=[depth_image_source, resized_width_slider, z_scale_slider, input_image, output_image, overlay_image, bordered_image_output],
|
| 1229 |
+
outputs=[depth_map_output, model_output, model_file], scroll_to_output=True
|
| 1230 |
)
|
| 1231 |
model_textbox.change(
|
| 1232 |
fn=update_prompt_notes,
|
images/prerendered/Firefly_topographical_moon_1.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
images/prerendered/Genison.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
images/prerendered/{cute3dkawaii.PNG → cute3dkawaii.png}
RENAMED
|
File without changes
|
images/prerendered/donald_park.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
utils/constants.py
CHANGED
|
@@ -70,7 +70,7 @@ NEGATIVE_PROMPTS = {
|
|
| 70 |
PRERENDER_DIR = "images/prerendered"
|
| 71 |
|
| 72 |
# List of pre-rendered hexagon map files
|
| 73 |
-
PRE_RENDERED_MAPS = ['alien_orb_land_1.png', 'alien_prarie_1.png', 'alien_world_1.png', 'alien_world_2.png', 'alien_world_3.png', 'alien_world_4.png', 'alien_world_5.png', 'BurntCity.png', 'canyon_water_1.png', 'CONQ_Caustic_Valley.png', 'CONQ_Frozen_City.png', 'CONQ_Hellebore_Springs.png', 'CONQ_Terra_Therma.png', 'CONQ_Viridian_Bog.png', 'cute3dkawaii.
|
| 74 |
|
| 75 |
# Create full paths for pre-rendered maps
|
| 76 |
pre_rendered_maps_paths = [os.path.join(PRERENDER_DIR, map_file).replace("\\", "/") for map_file in PRE_RENDERED_MAPS]
|
|
@@ -82,9 +82,9 @@ PRE_RENDERED_MAPS_JSON = {
|
|
| 82 |
for file in PRE_RENDERED_MAPS
|
| 83 |
}
|
| 84 |
PRE_RENDERED_MAPS_JSON
|
| 85 |
-
{'alien orb land 1': 'images/prerendered/alien_orb_land_1.png', 'alien prarie 1': 'images/prerendered/alien_prarie_1.png', 'alien world 1': 'images/prerendered/alien_world_1.png', 'alien world 2': 'images/prerendered/alien_world_2.png', 'alien world 3': 'images/prerendered/alien_world_3.png', 'alien world 4': 'images/prerendered/alien_world_4.png', 'alien world 5': 'images/prerendered/alien_world_5.png', 'BurntCity': 'images/prerendered/BurntCity.png', 'canyon water 1': 'images/prerendered/canyon_water_1.png', 'CONQ Caustic Valley': 'images/prerendered/CONQ_Caustic_Valley.png', 'CONQ Frozen City': 'images/prerendered/CONQ_Frozen_City.png', 'CONQ Hellebore Springs': 'images/prerendered/CONQ_Hellebore_Springs.png', 'CONQ Terra Therma': 'images/prerendered/CONQ_Terra_Therma.png', 'CONQ Viridian Bog': 'images/prerendered/CONQ_Viridian_Bog.png', 'cute3dkawaii': 'images/prerendered/cute3dkawaii.PNG', 'dark dirt elevations 1': 'images/prerendered/dark_dirt_elevations_1.png', 'donald park': 'images/prerendered/donald_park.png', 'elevated peninsula 1': 'images/prerendered/elevated_peninsula_1.png', 'Firefly alien canyons 1': 'images/prerendered/Firefly_alien_canyons_1.png', 'Firefly alien canyons 2': 'images/prerendered/Firefly_alien_canyons_2.png', 'Firefly alien dry canyons 1': 'images/prerendered/Firefly_alien_dry_canyons_1.png', 'Firefly alien dry canyons 2': 'images/prerendered/Firefly_alien_dry_canyons_2.png', 'Firefly alien map 1': 'images/prerendered/Firefly_alien_map_1.png', 'Firefly hpg terrain 1': 'images/prerendered/Firefly_hpg_terrain_1.png', 'Firefly hpg terrain 2': 'images/prerendered/Firefly_hpg_terrain_2.png', 'Firefly river dry 1': 'images/prerendered/Firefly_river_dry_1.png', 'Firefly river running 1': 'images/prerendered/Firefly_river_running_1.png', 'Firefly topographical alien desert 1': 'images/prerendered/Firefly_topographical_alien_desert_1.png', 'Firefly topographical canyon 1': 'images/prerendered/Firefly_topographical_canyon_1.png', 'Firefly topographical height map 1': 'images/prerendered/Firefly_topographical_height_map_1.png', 'Firefly topographical height map 2': 'images/prerendered/Firefly_topographical_height_map_2.png', 'Firefly topographical height map 3': 'images/prerendered/Firefly_topographical_height_map_3.png', 'Firefly topographical height map 5': 'images/prerendered/Firefly_topographical_height_map_5.png', 'Firefly topographical height map 6': 'images/prerendered/Firefly_topographical_height_map_6.png', 'Firefly topographical marble 1': 'images/prerendered/Firefly_topographical_marble_1.png', 'Firefly topographical moon 1': 'images/prerendered/Firefly_topographical_moon_1.png', 'fractal islands': 'images/prerendered/fractal_islands.png', 'Genison': 'images/prerendered/Genison.png', 'green farming alien world 1': 'images/prerendered/green_farming_alien_world_1.png', 'green farming alien world 2': 'images/prerendered/green_farming_alien_world_2.png', 'grey barren alien world 1': 'images/prerendered/grey_barren_alien_world_1.png', 'grey barren alien world 2': 'images/prerendered/grey_barren_alien_world_2.png', 'grey barren alien world 3': 'images/prerendered/grey_barren_alien_world_3.png', 'grey barren alien world 4': 'images/prerendered/grey_barren_alien_world_4.png', 'grey barren alien world 5': 'images/prerendered/grey_barren_alien_world_5.png', 'grey barren alien world 6': 'images/prerendered/grey_barren_alien_world_6.png', 'grey barren alien world 7': 'images/prerendered/grey_barren_alien_world_7.png', 'grey waterless alien world map': 'images/prerendered/grey_waterless_alien_world_map.png', 'grid 1': 'images/prerendered/grid_1.png', 'Hex gen map': 'images/prerendered/Hex_gen_map.
|
| 86 |
##PRE_RENDERED_MAPS_JSON = { key: { 'file': value, 'quality': 0 } for key, value in PRE_RENDERED_MAPS_JSON.items()}
|
| 87 |
-
PRE_RENDERED_MAPS_JSON_LEVELS = {'alien orb land 1': {'file': 'images/prerendered/alien_orb_land_1.png', 'quality': 0}, 'alien prarie 1': {'file': 'images/prerendered/alien_prarie_1.png', 'quality': 0}, 'alien world 1': {'file': 'images/prerendered/alien_world_1.png', 'quality': 0}, 'alien world 2': {'file': 'images/prerendered/alien_world_2.png', 'quality': 0}, 'alien world 3': {'file': 'images/prerendered/alien_world_3.png', 'quality': 0}, 'alien world 4': {'file': 'images/prerendered/alien_world_4.png', 'quality': 0}, 'alien world 5': {'file': 'images/prerendered/alien_world_5.png', 'quality': 0}, 'BurntCity': {'file': 'images/prerendered/BurntCity.png', 'quality': 0}, 'canyon water 1': {'file': 'images/prerendered/canyon_water_1.png', 'quality': 0}, 'CONQ Caustic Valley': {'file': 'images/prerendered/CONQ_Caustic_Valley.png', 'quality': 0}, 'CONQ Frozen City': {'file': 'images/prerendered/CONQ_Frozen_City.png', 'quality': 0}, 'CONQ Hellebore Springs': {'file': 'images/prerendered/CONQ_Hellebore_Springs.png', 'quality': 0}, 'CONQ Terra Therma': {'file': 'images/prerendered/CONQ_Terra_Therma.png', 'quality': 0}, 'CONQ Viridian Bog': {'file': 'images/prerendered/CONQ_Viridian_Bog.png', 'quality': 0}, 'cute3dkawaii': {'file': 'images/prerendered/cute3dkawaii.
|
| 88 |
|
| 89 |
# Available FLUX model names
|
| 90 |
MODELS = [
|
|
|
|
| 70 |
PRERENDER_DIR = "images/prerendered"
|
| 71 |
|
| 72 |
# List of pre-rendered hexagon map files
|
| 73 |
+
PRE_RENDERED_MAPS = ['alien_orb_land_1.png', 'alien_prarie_1.png', 'alien_world_1.png', 'alien_world_2.png', 'alien_world_3.png', 'alien_world_4.png', 'alien_world_5.png', 'BurntCity.png', 'canyon_water_1.png', 'CONQ_Caustic_Valley.png', 'CONQ_Frozen_City.png', 'CONQ_Hellebore_Springs.png', 'CONQ_Terra_Therma.png', 'CONQ_Viridian_Bog.png', 'cute3dkawaii.png', 'dark_dirt_elevations_1.png', 'donald_park.png', 'elevated_peninsula_1.png', 'Firefly_alien_canyons_1.png', 'Firefly_alien_canyons_2.png', 'Firefly_alien_dry_canyons_1.png', 'Firefly_alien_dry_canyons_2.png', 'Firefly_alien_map_1.png', 'Firefly_hpg_terrain_1.png', 'Firefly_hpg_terrain_2.png', 'Firefly_river_dry_1.png', 'Firefly_river_running_1.png', 'Firefly_topographical_alien_desert_1.png', 'Firefly_topographical_canyon_1.png', 'Firefly_topographical_height_map_1.png', 'Firefly_topographical_height_map_2.png', 'Firefly_topographical_height_map_3.png', 'Firefly_topographical_height_map_5.png', 'Firefly_topographical_height_map_6.png', 'Firefly_topographical_marble_1.png', 'Firefly_topographical_moon_1.png', 'fractal_islands.png', 'Genison.png', 'green_farming_alien_world_1.png', 'green_farming_alien_world_2.png', 'grey_barren_alien_world_1.png', 'grey_barren_alien_world_2.png', 'grey_barren_alien_world_3.png', 'grey_barren_alien_world_4.png', 'grey_barren_alien_world_5.png', 'grey_barren_alien_world_6.png', 'grey_barren_alien_world_7.png', 'grey_waterless_alien_world_map.png', 'grid_1.png', 'Hex_gen_map.png', 'hex_grass_dirty.png', 'hex_military_industrial_alien_world_map.png', 'hex_mixed_elevations_battlefield_1.png', 'hex_mixed_elevations_battlefield_2.png', 'hex_tree_territory.png', 'lake_city.png', 'mickey_lagoon.png', 'mixed_elevations_battlefield_3.png', 'n6W9Hc.png', 'oasis_mixed_elevations_1.png', 'pic526383.png', 'pinecone_islands.png', 'purple_pines.png', 'red_volcanic_alien_1.png', 'red_volcanic_alien_2.png', 'red_volcanic_alien_3.png', 'red_volcanic_alien_4.png', 'roadway_1.png', 'snowy_lake.png', 'snowy_rolling_hills_1.png', 'volcanic_alien_world_map.png', 'war_torn_post_apocalyptic_alien_world_map.png']
|
| 74 |
|
| 75 |
# Create full paths for pre-rendered maps
|
| 76 |
pre_rendered_maps_paths = [os.path.join(PRERENDER_DIR, map_file).replace("\\", "/") for map_file in PRE_RENDERED_MAPS]
|
|
|
|
| 82 |
for file in PRE_RENDERED_MAPS
|
| 83 |
}
|
| 84 |
PRE_RENDERED_MAPS_JSON
|
| 85 |
+
{'alien orb land 1': 'images/prerendered/alien_orb_land_1.png', 'alien prarie 1': 'images/prerendered/alien_prarie_1.png', 'alien world 1': 'images/prerendered/alien_world_1.png', 'alien world 2': 'images/prerendered/alien_world_2.png', 'alien world 3': 'images/prerendered/alien_world_3.png', 'alien world 4': 'images/prerendered/alien_world_4.png', 'alien world 5': 'images/prerendered/alien_world_5.png', 'BurntCity': 'images/prerendered/BurntCity.png', 'canyon water 1': 'images/prerendered/canyon_water_1.png', 'CONQ Caustic Valley': 'images/prerendered/CONQ_Caustic_Valley.png', 'CONQ Frozen City': 'images/prerendered/CONQ_Frozen_City.png', 'CONQ Hellebore Springs': 'images/prerendered/CONQ_Hellebore_Springs.png', 'CONQ Terra Therma': 'images/prerendered/CONQ_Terra_Therma.png', 'CONQ Viridian Bog': 'images/prerendered/CONQ_Viridian_Bog.png', 'cute3dkawaii': 'images/prerendered/cute3dkawaii.PNG', 'dark dirt elevations 1': 'images/prerendered/dark_dirt_elevations_1.png', 'donald park': 'images/prerendered/donald_park.png', 'elevated peninsula 1': 'images/prerendered/elevated_peninsula_1.png', 'Firefly alien canyons 1': 'images/prerendered/Firefly_alien_canyons_1.png', 'Firefly alien canyons 2': 'images/prerendered/Firefly_alien_canyons_2.png', 'Firefly alien dry canyons 1': 'images/prerendered/Firefly_alien_dry_canyons_1.png', 'Firefly alien dry canyons 2': 'images/prerendered/Firefly_alien_dry_canyons_2.png', 'Firefly alien map 1': 'images/prerendered/Firefly_alien_map_1.png', 'Firefly hpg terrain 1': 'images/prerendered/Firefly_hpg_terrain_1.png', 'Firefly hpg terrain 2': 'images/prerendered/Firefly_hpg_terrain_2.png', 'Firefly river dry 1': 'images/prerendered/Firefly_river_dry_1.png', 'Firefly river running 1': 'images/prerendered/Firefly_river_running_1.png', 'Firefly topographical alien desert 1': 'images/prerendered/Firefly_topographical_alien_desert_1.png', 'Firefly topographical canyon 1': 'images/prerendered/Firefly_topographical_canyon_1.png', 'Firefly topographical height map 1': 'images/prerendered/Firefly_topographical_height_map_1.png', 'Firefly topographical height map 2': 'images/prerendered/Firefly_topographical_height_map_2.png', 'Firefly topographical height map 3': 'images/prerendered/Firefly_topographical_height_map_3.png', 'Firefly topographical height map 5': 'images/prerendered/Firefly_topographical_height_map_5.png', 'Firefly topographical height map 6': 'images/prerendered/Firefly_topographical_height_map_6.png', 'Firefly topographical marble 1': 'images/prerendered/Firefly_topographical_marble_1.png', 'Firefly topographical moon 1': 'images/prerendered/Firefly_topographical_moon_1.png', 'fractal islands': 'images/prerendered/fractal_islands.png', 'Genison': 'images/prerendered/Genison.png', 'green farming alien world 1': 'images/prerendered/green_farming_alien_world_1.png', 'green farming alien world 2': 'images/prerendered/green_farming_alien_world_2.png', 'grey barren alien world 1': 'images/prerendered/grey_barren_alien_world_1.png', 'grey barren alien world 2': 'images/prerendered/grey_barren_alien_world_2.png', 'grey barren alien world 3': 'images/prerendered/grey_barren_alien_world_3.png', 'grey barren alien world 4': 'images/prerendered/grey_barren_alien_world_4.png', 'grey barren alien world 5': 'images/prerendered/grey_barren_alien_world_5.png', 'grey barren alien world 6': 'images/prerendered/grey_barren_alien_world_6.png', 'grey barren alien world 7': 'images/prerendered/grey_barren_alien_world_7.png', 'grey waterless alien world map': 'images/prerendered/grey_waterless_alien_world_map.png', 'grid 1': 'images/prerendered/grid_1.png', 'Hex gen map': 'images/prerendered/Hex_gen_map.png', 'hex grass dirty': 'images/prerendered/hex_grass_dirty.png', 'hex military industrial alien world map': 'images/prerendered/hex_military_industrial_alien_world_map.png', 'hex mixed elevations battlefield 1': 'images/prerendered/hex_mixed_elevations_battlefield_1.png', 'hex mixed elevations battlefield 2': 'images/prerendered/hex_mixed_elevations_battlefield_2.png', 'hex tree territory': 'images/prerendered/hex_tree_territory.png', 'lake city': 'images/prerendered/lake_city.png', 'mickey lagoon': 'images/prerendered/mickey_lagoon.png', 'mixed elevations battlefield 3': 'images/prerendered/mixed_elevations_battlefield_3.png', 'n6W9Hc': 'images/prerendered/n6W9Hc.png', 'oasis mixed elevations 1': 'images/prerendered/oasis_mixed_elevations_1.png', 'pic526383': 'images/prerendered/pic526383.png', 'pinecone islands': 'images/prerendered/pinecone_islands.png', 'purple pines': 'images/prerendered/purple_pines.png', 'red volcanic alien 1': 'images/prerendered/red_volcanic_alien_1.png', 'red volcanic alien 2': 'images/prerendered/red_volcanic_alien_2.png', 'red volcanic alien 3': 'images/prerendered/red_volcanic_alien_3.png', 'red volcanic alien 4': 'images/prerendered/red_volcanic_alien_4.png', 'roadway 1': 'images/prerendered/roadway_1.png', 'snowy lake': 'images/prerendered/snowy_lake.png', 'snowy rolling hills 1': 'images/prerendered/snowy_rolling_hills_1.png', 'volcanic alien world map': 'images/prerendered/volcanic_alien_world_map.png', 'war torn post apocalyptic alien world map': 'images/prerendered/war_torn_post_apocalyptic_alien_world_map.png'}
|
| 86 |
##PRE_RENDERED_MAPS_JSON = { key: { 'file': value, 'quality': 0 } for key, value in PRE_RENDERED_MAPS_JSON.items()}
|
| 87 |
+
PRE_RENDERED_MAPS_JSON_LEVELS = {'alien orb land 1': {'file': 'images/prerendered/alien_orb_land_1.png', 'quality': 0}, 'alien prarie 1': {'file': 'images/prerendered/alien_prarie_1.png', 'quality': 0}, 'alien world 1': {'file': 'images/prerendered/alien_world_1.png', 'quality': 0}, 'alien world 2': {'file': 'images/prerendered/alien_world_2.png', 'quality': 0}, 'alien world 3': {'file': 'images/prerendered/alien_world_3.png', 'quality': 0}, 'alien world 4': {'file': 'images/prerendered/alien_world_4.png', 'quality': 0}, 'alien world 5': {'file': 'images/prerendered/alien_world_5.png', 'quality': 0}, 'BurntCity': {'file': 'images/prerendered/BurntCity.png', 'quality': 0}, 'canyon water 1': {'file': 'images/prerendered/canyon_water_1.png', 'quality': 0}, 'CONQ Caustic Valley': {'file': 'images/prerendered/CONQ_Caustic_Valley.png', 'quality': 0}, 'CONQ Frozen City': {'file': 'images/prerendered/CONQ_Frozen_City.png', 'quality': 0}, 'CONQ Hellebore Springs': {'file': 'images/prerendered/CONQ_Hellebore_Springs.png', 'quality': 0}, 'CONQ Terra Therma': {'file': 'images/prerendered/CONQ_Terra_Therma.png', 'quality': 0}, 'CONQ Viridian Bog': {'file': 'images/prerendered/CONQ_Viridian_Bog.png', 'quality': 0}, 'cute3dkawaii': {'file': 'images/prerendered/cute3dkawaii.png', 'quality': 0}, 'dark dirt elevations 1': {'file': 'images/prerendered/dark_dirt_elevations_1.png', 'quality': 0}, 'donald park': {'file': 'images/prerendered/donald_park.png', 'quality': 0}, 'elevated peninsula 1': {'file': 'images/prerendered/elevated_peninsula_1.png', 'quality': 0}, 'Firefly alien canyons 1': {'file': 'images/prerendered/Firefly_alien_canyons_1.png', 'quality': 0}, 'Firefly alien canyons 2': {'file': 'images/prerendered/Firefly_alien_canyons_2.png', 'quality': 0}, 'Firefly alien dry canyons 1': {'file': 'images/prerendered/Firefly_alien_dry_canyons_1.png', 'quality': 0}, 'Firefly alien dry canyons 2': {'file': 'images/prerendered/Firefly_alien_dry_canyons_2.png', 'quality': 0}, 'Firefly alien map 1': {'file': 'images/prerendered/Firefly_alien_map_1.png', 'quality': 0}, 'Firefly hpg terrain 1': {'file': 'images/prerendered/Firefly_hpg_terrain_1.png', 'quality': 0}, 'Firefly hpg terrain 2': {'file': 'images/prerendered/Firefly_hpg_terrain_2.png', 'quality': 0}, 'Firefly river dry 1': {'file': 'images/prerendered/Firefly_river_dry_1.png', 'quality': 0}, 'Firefly river running 1': {'file': 'images/prerendered/Firefly_river_running_1.png', 'quality': 0}, 'Firefly topographical alien desert 1': {'file': 'images/prerendered/Firefly_topographical_alien_desert_1.png', 'quality': 0}, 'Firefly topographical canyon 1': {'file': 'images/prerendered/Firefly_topographical_canyon_1.png', 'quality': 0}, 'Firefly topographical height map 1': {'file': 'images/prerendered/Firefly_topographical_height_map_1.png', 'quality': 0}, 'Firefly topographical height map 2': {'file': 'images/prerendered/Firefly_topographical_height_map_2.png', 'quality': 0}, 'Firefly topographical height map 3': {'file': 'images/prerendered/Firefly_topographical_height_map_3.png', 'quality': 0}, 'Firefly topographical height map 5': {'file': 'images/prerendered/Firefly_topographical_height_map_5.png', 'quality': 0}, 'Firefly topographical height map 6': {'file': 'images/prerendered/Firefly_topographical_height_map_6.png', 'quality': 0}, 'Firefly topographical marble 1': {'file': 'images/prerendered/Firefly_topographical_marble_1.png', 'quality': 0}, 'Firefly topographical moon 1': {'file': 'images/prerendered/Firefly_topographical_moon_1.png', 'quality': 0}, 'fractal islands': {'file': 'images/prerendered/fractal_islands.png', 'quality': 0}, 'Genison': {'file': 'images/prerendered/Genison.png', 'quality': 0}, 'green farming alien world 1': {'file': 'images/prerendered/green_farming_alien_world_1.png', 'quality': 0}, 'green farming alien world 2': {'file': 'images/prerendered/green_farming_alien_world_2.png', 'quality': 0}, 'grey barren alien world 1': {'file': 'images/prerendered/grey_barren_alien_world_1.png', 'quality': 0}, 'grey barren alien world 2': {'file': 'images/prerendered/grey_barren_alien_world_2.png', 'quality': 0}, 'grey barren alien world 3': {'file': 'images/prerendered/grey_barren_alien_world_3.png', 'quality': 0}, 'grey barren alien world 4': {'file': 'images/prerendered/grey_barren_alien_world_4.png', 'quality': 0}, 'grey barren alien world 5': {'file': 'images/prerendered/grey_barren_alien_world_5.png', 'quality': 0}, 'grey barren alien world 6': {'file': 'images/prerendered/grey_barren_alien_world_6.png', 'quality': 0}, 'grey barren alien world 7': {'file': 'images/prerendered/grey_barren_alien_world_7.png', 'quality': 0}, 'grey waterless alien world map': {'file': 'images/prerendered/grey_waterless_alien_world_map.png', 'quality': 0}, 'grid 1': {'file': 'images/prerendered/grid_1.png', 'quality': 0}, 'Hex gen map': {'file': 'images/prerendered/Hex_gen_map.png', 'quality': 0}, 'hex grass dirty': {'file': 'images/prerendered/hex_grass_dirty.png', 'quality': 0}, 'hex military industrial alien world map': {'file': 'images/prerendered/hex_military_industrial_alien_world_map.png', 'quality': 0}, 'hex mixed elevations battlefield 1': {'file': 'images/prerendered/hex_mixed_elevations_battlefield_1.png', 'quality': 0}, 'hex mixed elevations battlefield 2': {'file': 'images/prerendered/hex_mixed_elevations_battlefield_2.png', 'quality': 0}, 'hex tree territory': {'file': 'images/prerendered/hex_tree_territory.png', 'quality': 0}, 'lake city': {'file': 'images/prerendered/lake_city.png', 'quality': 0}, 'mickey lagoon': {'file': 'images/prerendered/mickey_lagoon.png', 'quality': 0}, 'mixed elevations battlefield 3': {'file': 'images/prerendered/mixed_elevations_battlefield_3.png', 'quality': 0}, 'n6W9Hc': {'file': 'images/prerendered/n6W9Hc.png', 'quality': 0}, 'oasis mixed elevations 1': {'file': 'images/prerendered/oasis_mixed_elevations_1.png', 'quality': 0}, 'pic526383': {'file': 'images/prerendered/pic526383.png', 'quality': 0}, 'pinecone islands': {'file': 'images/prerendered/pinecone_islands.png', 'quality': 0}, 'purple pines': {'file': 'images/prerendered/purple_pines.png', 'quality': 0}, 'red volcanic alien 1': {'file': 'images/prerendered/red_volcanic_alien_1.png', 'quality': 0}, 'red volcanic alien 2': {'file': 'images/prerendered/red_volcanic_alien_2.png', 'quality': 0}, 'red volcanic alien 3': {'file': 'images/prerendered/red_volcanic_alien_3.png', 'quality': 0}, 'red volcanic alien 4': {'file': 'images/prerendered/red_volcanic_alien_4.png', 'quality': 0}, 'roadway 1': {'file': 'images/prerendered/roadway_1.png', 'quality': 0}, 'snowy lake': {'file': 'images/prerendered/snowy_lake.png', 'quality': 0}, 'snowy rolling hills 1': {'file': 'images/prerendered/snowy_rolling_hills_1.png', 'quality': 0}, 'volcanic alien world map': {'file': 'images/prerendered/volcanic_alien_world_map.png', 'quality': 0}, 'war torn post apocalyptic alien world map': {'file': 'images/prerendered/war_torn_post_apocalyptic_alien_world_map.png', 'quality': 0}}
|
| 88 |
|
| 89 |
# Available FLUX model names
|
| 90 |
MODELS = [
|
utils/depth_estimation.py
CHANGED
|
@@ -111,4 +111,150 @@ def generate_depth_button_click(depth_image_source, voxel_size_factor, input_ima
|
|
| 111 |
else:
|
| 112 |
image_path = overlay_image
|
| 113 |
|
| 114 |
-
return generate_depth_and_3d(image_path, voxel_size_factor)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
else:
|
| 112 |
image_path = overlay_image
|
| 113 |
|
| 114 |
+
return generate_depth_and_3d(image_path, voxel_size_factor)
|
| 115 |
+
|
| 116 |
+
def create_3d_obj(rgb_image, raw_depth, image_path, depth=10, z_scale=200):
|
| 117 |
+
"""
|
| 118 |
+
Creates a 3D object from RGB and depth images.
|
| 119 |
+
|
| 120 |
+
Args:
|
| 121 |
+
rgb_image (np.ndarray): The RGB image as a NumPy array.
|
| 122 |
+
raw_depth (np.ndarray): The raw depth data.
|
| 123 |
+
image_path (Path): The path to the original image.
|
| 124 |
+
depth (int, optional): Depth parameter for Poisson reconstruction. Defaults to 10.
|
| 125 |
+
z_scale (float, optional): Scaling factor for the Z-axis. Defaults to 200.
|
| 126 |
+
|
| 127 |
+
Returns:
|
| 128 |
+
str: The file path to the saved GLTF model.
|
| 129 |
+
"""
|
| 130 |
+
# Normalize the depth image
|
| 131 |
+
depth_image = ((raw_depth - raw_depth.min()) / (raw_depth.max() - raw_depth.min()) * 255).astype("uint8")
|
| 132 |
+
depth_o3d = o3d.geometry.Image(depth_image)
|
| 133 |
+
image_o3d = o3d.geometry.Image(rgb_image)
|
| 134 |
+
|
| 135 |
+
# Create RGBD image
|
| 136 |
+
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
|
| 137 |
+
image_o3d, depth_o3d, convert_rgb_to_intensity=False
|
| 138 |
+
)
|
| 139 |
+
|
| 140 |
+
height, width = depth_image.shape
|
| 141 |
+
|
| 142 |
+
# Define camera intrinsics
|
| 143 |
+
camera_intrinsic = o3d.camera.PinholeCameraIntrinsic(
|
| 144 |
+
width,
|
| 145 |
+
height,
|
| 146 |
+
fx=z_scale,
|
| 147 |
+
fy=z_scale,
|
| 148 |
+
cx=width / 2.0,
|
| 149 |
+
cy=height / 2.0,
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
# Generate point cloud from RGBD image
|
| 153 |
+
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, camera_intrinsic)
|
| 154 |
+
|
| 155 |
+
# Scale the Z dimension
|
| 156 |
+
points = np.asarray(pcd.points)
|
| 157 |
+
depth_scaled = ((raw_depth - raw_depth.min()) / (raw_depth.max() - raw_depth.min())) * (z_scale*100)
|
| 158 |
+
z_values = depth_scaled.flatten()[:len(points)]
|
| 159 |
+
points[:, 2] *= z_values
|
| 160 |
+
pcd.points = o3d.utility.Vector3dVector(points)
|
| 161 |
+
|
| 162 |
+
# Estimate and orient normals
|
| 163 |
+
pcd.estimate_normals(
|
| 164 |
+
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=60)
|
| 165 |
+
)
|
| 166 |
+
pcd.orient_normals_towards_camera_location(camera_location=np.array([0.0, 0.0, 1.5 ]))
|
| 167 |
+
|
| 168 |
+
# Apply transformations
|
| 169 |
+
pcd.transform([[1, 0, 0, 0],
|
| 170 |
+
[0, -1, 0, 0],
|
| 171 |
+
[0, 0, -1, 0],
|
| 172 |
+
[0, 0, 0, 1]])
|
| 173 |
+
pcd.transform([[-1, 0, 0, 0],
|
| 174 |
+
[0, 1, 0, 0],
|
| 175 |
+
[0, 0, 1, 0],
|
| 176 |
+
[0, 0, 0, 1]])
|
| 177 |
+
|
| 178 |
+
# Perform Poisson surface reconstruction
|
| 179 |
+
print(f"Running Poisson surface reconstruction with depth {depth}")
|
| 180 |
+
mesh_raw, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
|
| 181 |
+
pcd, depth=depth, width=0, scale=1.1, linear_fit=True
|
| 182 |
+
)
|
| 183 |
+
print(f"Raw mesh vertices: {len(mesh_raw.vertices)}, triangles: {len(mesh_raw.triangles)}")
|
| 184 |
+
|
| 185 |
+
# Simplify the mesh using vertex clustering
|
| 186 |
+
voxel_size = max(mesh_raw.get_max_bound() - mesh_raw.get_min_bound()) / (max(width, height) * 0.8)
|
| 187 |
+
mesh = mesh_raw.simplify_vertex_clustering(
|
| 188 |
+
voxel_size=voxel_size,
|
| 189 |
+
contraction=o3d.geometry.SimplificationContraction.Average,
|
| 190 |
+
)
|
| 191 |
+
print(f"Simplified mesh vertices: {len(mesh.vertices)}, triangles: {len(mesh.triangles)}")
|
| 192 |
+
|
| 193 |
+
# Crop the mesh to the bounding box of the point cloud
|
| 194 |
+
bbox = pcd.get_axis_aligned_bounding_box()
|
| 195 |
+
mesh_crop = mesh.crop(bbox)
|
| 196 |
+
|
| 197 |
+
# Save the mesh as a GLTF file
|
| 198 |
+
temp_dir = Path.cwd() / "models"
|
| 199 |
+
temp_dir.mkdir(exist_ok=True)
|
| 200 |
+
gltf_path = str(temp_dir / f"{image_path.stem}.gltf")
|
| 201 |
+
o3d.io.write_triangle_mesh(gltf_path, mesh_crop, write_triangle_uvs=True)
|
| 202 |
+
return gltf_path
|
| 203 |
+
def depth_process_image(image_path, resized_width=800, z_scale=208):
|
| 204 |
+
"""
|
| 205 |
+
Processes the input image to generate a depth map and a 3D mesh reconstruction.
|
| 206 |
+
|
| 207 |
+
Args:
|
| 208 |
+
image_path (str): The file path to the input image.
|
| 209 |
+
|
| 210 |
+
Returns:
|
| 211 |
+
list: A list containing the depth image, 3D mesh reconstruction, and GLTF file path.
|
| 212 |
+
"""
|
| 213 |
+
image_path = Path(image_path)
|
| 214 |
+
if not image_path.exists():
|
| 215 |
+
raise ValueError("Image file not found")
|
| 216 |
+
|
| 217 |
+
# Load and resize the image
|
| 218 |
+
image_raw = Image.open(image_path).convert("RGB")
|
| 219 |
+
print(f"Original size: {image_raw.size}")
|
| 220 |
+
resized_height = int(resized_width * image_raw.size[1] / image_raw.size[0])
|
| 221 |
+
image = image_raw.resize((resized_width, resized_height), Image.Resampling.LANCZOS)
|
| 222 |
+
print(f"Resized size: {image.size}")
|
| 223 |
+
|
| 224 |
+
# Prepare image for the model
|
| 225 |
+
encoding = image_processor(image, return_tensors="pt")
|
| 226 |
+
|
| 227 |
+
# Perform depth estimation
|
| 228 |
+
with torch.no_grad():
|
| 229 |
+
outputs = depth_model(**encoding)
|
| 230 |
+
predicted_depth = outputs.predicted_depth
|
| 231 |
+
|
| 232 |
+
# Interpolate depth to match the image size
|
| 233 |
+
prediction = torch.nn.functional.interpolate(
|
| 234 |
+
predicted_depth.unsqueeze(1),
|
| 235 |
+
size=(image.height, image.width),
|
| 236 |
+
mode="bicubic",
|
| 237 |
+
align_corners=False,
|
| 238 |
+
).squeeze()
|
| 239 |
+
|
| 240 |
+
# Normalize the depth image to 8-bit
|
| 241 |
+
if torch.cuda.is_available():
|
| 242 |
+
prediction = prediction.numpy()
|
| 243 |
+
else:
|
| 244 |
+
prediction = prediction.cpu().numpy()
|
| 245 |
+
depth_min, depth_max = prediction.min(), prediction.max()
|
| 246 |
+
depth_image = ((prediction - depth_min) / (depth_max - depth_min) * 255).astype("uint8")
|
| 247 |
+
|
| 248 |
+
try:
|
| 249 |
+
gltf_path = create_3d_obj(np.array(image), prediction, image_path, depth=10, z_scale=z_scale)
|
| 250 |
+
except Exception:
|
| 251 |
+
gltf_path = create_3d_obj(np.array(image), prediction, image_path, depth=8, z_scale=z_scale)
|
| 252 |
+
|
| 253 |
+
img = Image.fromarray(depth_image)
|
| 254 |
+
|
| 255 |
+
if torch.cuda.is_available():
|
| 256 |
+
torch.cuda.empty_cache()
|
| 257 |
+
torch.cuda.ipc_collect()
|
| 258 |
+
return [img, gltf_path, gltf_path]
|
| 259 |
+
|
| 260 |
+
|
utils/version_info.py
CHANGED
|
@@ -45,6 +45,12 @@ def get_diffusers_version():
|
|
| 45 |
return diffusers.__version__
|
| 46 |
except Exception:
|
| 47 |
return "<none>"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
def get_torch_info():
|
| 50 |
from torch import __version__ as torch_version_, version, cuda, backends
|
|
@@ -109,6 +115,8 @@ def versions_html():
|
|
| 109 |
 • 
|
| 110 |
safetensors: {get_safetensors_version()}
|
| 111 |
 • 
|
|
|
|
|
|
|
| 112 |
gradio: {gr.__version__}
|
| 113 |
 • 
|
| 114 |
{toggle_dark_link}
|
|
|
|
| 45 |
return diffusers.__version__
|
| 46 |
except Exception:
|
| 47 |
return "<none>"
|
| 48 |
+
def get_open3d_version():
|
| 49 |
+
try:
|
| 50 |
+
import open3d
|
| 51 |
+
return f"{open3d.__version__} cuda:{open3d.core.cuda.is_available()}"
|
| 52 |
+
except Exception:
|
| 53 |
+
return "<none>"
|
| 54 |
|
| 55 |
def get_torch_info():
|
| 56 |
from torch import __version__ as torch_version_, version, cuda, backends
|
|
|
|
| 115 |
 • 
|
| 116 |
safetensors: {get_safetensors_version()}
|
| 117 |
 • 
|
| 118 |
+
open3d: {get_open3d_version()}
|
| 119 |
+
 • 
|
| 120 |
gradio: {gr.__version__}
|
| 121 |
 • 
|
| 122 |
{toggle_dark_link}
|