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}
|