Spaces:
Running
on
Zero
Running
on
Zero
Depth V1 working... probably broken elsewhere
Browse files- README.md +1 -1
- app.py +66 -34
- utils/image_utils.py +0 -1
- web-ui.bat +1 -1
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.16.
|
| 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.16.1
|
| 9 |
app_file: app.py
|
| 10 |
pinned: true
|
| 11 |
short_description: Transform Your Images into Mesmerizing Hexagon Grids
|
app.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
|
| 3 |
import os
|
| 4 |
# Import constants
|
| 5 |
import numpy as np
|
|
@@ -10,7 +10,6 @@ from PIL import Image, ImageFilter
|
|
| 10 |
import cv2
|
| 11 |
import utils.constants as constants
|
| 12 |
|
| 13 |
-
|
| 14 |
from haishoku.haishoku import Haishoku
|
| 15 |
|
| 16 |
from tempfile import NamedTemporaryFile
|
|
@@ -20,7 +19,7 @@ import random
|
|
| 20 |
from transformers import AutoTokenizer , DPTImageProcessor, DPTForDepthEstimation
|
| 21 |
from pathlib import Path
|
| 22 |
import logging
|
| 23 |
-
logging.getLogger("transformers.modeling_utils").setLevel(logging.ERROR)
|
| 24 |
import gc
|
| 25 |
|
| 26 |
IS_SHARED_SPACE = constants.IS_SHARED_SPACE
|
|
@@ -88,6 +87,7 @@ PIPELINE_CLASSES = {
|
|
| 88 |
"FluxControlPipeline": FluxControlPipeline
|
| 89 |
}
|
| 90 |
|
|
|
|
| 91 |
#from utils.depth_estimation import generate_depth_and_3d
|
| 92 |
|
| 93 |
|
|
@@ -299,7 +299,11 @@ class Condition(object):
|
|
| 299 |
type_id = torch.ones_like(ids[:, :1]) * self.type_id
|
| 300 |
return tokens, ids, type_id
|
| 301 |
|
| 302 |
-
@spaces.GPU(duration=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
def generate_image_lowmem(
|
| 304 |
text,
|
| 305 |
neg_prompt=None,
|
|
@@ -501,7 +505,7 @@ def generate_image_lowmem(
|
|
| 501 |
generate_params = {k: v for k, v in generate_params.items() if v is not None}
|
| 502 |
print(f"generate_params: {generate_params}")
|
| 503 |
# Generate the image
|
| 504 |
-
result = pipe
|
| 505 |
image = result.images[0]
|
| 506 |
# Clean up
|
| 507 |
del result
|
|
@@ -697,7 +701,7 @@ depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large", ignore_mi
|
|
| 697 |
|
| 698 |
@spaces.GPU()
|
| 699 |
def estimate_depth(image):
|
| 700 |
-
|
| 701 |
|
| 702 |
# Ensure image is in RGB mode
|
| 703 |
if image.mode != "RGB":
|
|
@@ -740,15 +744,15 @@ def estimate_depth(image):
|
|
| 740 |
return depth_pil, output
|
| 741 |
|
| 742 |
@spaces.GPU()
|
| 743 |
-
def create_3d_model(rgb_image, depth_array, voxel_size_factor=0.01):
|
| 744 |
import open3d as o3d
|
| 745 |
depth_o3d = o3d.geometry.Image(depth_array.astype(np.float32))
|
| 746 |
-
rgb_o3d = o3d.geometry.Image(np.array(rgb_image))
|
| 747 |
|
| 748 |
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
|
| 749 |
rgb_o3d,
|
| 750 |
depth_o3d,
|
| 751 |
-
convert_rgb_to_intensity=
|
| 752 |
)
|
| 753 |
|
| 754 |
# Create a point cloud from the RGBD image
|
|
@@ -765,16 +769,46 @@ def create_3d_model(rgb_image, depth_array, voxel_size_factor=0.01):
|
|
| 765 |
rgbd_image,
|
| 766 |
camera_intrinsic
|
| 767 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 768 |
|
| 769 |
# Voxel downsample
|
| 770 |
-
voxel_size = max(pcd.get_max_bound() - pcd.get_min_bound()) * voxel_size_factor
|
| 771 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 772 |
|
| 773 |
# Save the 3D model to a temporary file
|
| 774 |
temp_dir = Path.cwd() / "temp_models"
|
| 775 |
temp_dir.mkdir(exist_ok=True)
|
| 776 |
-
model_path = temp_dir / "model.
|
| 777 |
-
o3d.io.write_voxel_grid(str(model_path), voxel_grid)
|
|
|
|
| 778 |
|
| 779 |
return str(model_path)
|
| 780 |
|
|
@@ -869,7 +903,7 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 869 |
key="imgInput",
|
| 870 |
image_mode=None,
|
| 871 |
format="PNG",
|
| 872 |
-
show_download_button=True
|
| 873 |
)
|
| 874 |
|
| 875 |
# New code to convert input image to RGBA PNG
|
|
@@ -968,14 +1002,13 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 968 |
# Update map_options to a Dropdown with choices from constants.PROMPTS keys
|
| 969 |
with gr.Row():
|
| 970 |
with gr.Column():
|
| 971 |
-
|
| 972 |
-
|
| 973 |
-
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
|
| 977 |
)
|
| 978 |
-
with gr.Column():
|
| 979 |
# Add Dropdown for sizing of Images, height and width based on selection. Options are 16x9, 16x10, 4x5, 1x1
|
| 980 |
# The values of height and width are based on common resolutions for each aspect ratio
|
| 981 |
# Default to 16x9, 912x512
|
|
@@ -1112,7 +1145,7 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 1112 |
generate_depth_button = gr.Button("Generate Depth Map and 3D Model From Selected Image", elem_classes="solid", variant="secondary")
|
| 1113 |
with gr.Row():
|
| 1114 |
depth_map_output = gr.Image(label="Depth Map", image_mode="L", elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgDepth")
|
| 1115 |
-
model_output = gr.Model3D(label="3D Model", clear_color=[1.0, 1.0, 1.0, 0
|
| 1116 |
with gr.Row():
|
| 1117 |
gr.Examples(examples=[
|
| 1118 |
["assets//examples//hex_map_p1.png", False, True, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 15],
|
|
@@ -1213,23 +1246,22 @@ with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty')
|
|
| 1213 |
scroll_to_output=True
|
| 1214 |
)
|
| 1215 |
|
| 1216 |
-
|
|
|
|
| 1217 |
|
| 1218 |
if __name__ == "__main__":
|
| 1219 |
logging.basicConfig(
|
| 1220 |
format="[%(levelname)s] %(asctime)s %(message)s", level=logging.INFO
|
| 1221 |
)
|
| 1222 |
logging.info("Environment Variables: %s" % os.environ)
|
| 1223 |
-
|
| 1224 |
-
|
| 1225 |
-
|
| 1226 |
-
|
| 1227 |
-
|
| 1228 |
|
| 1229 |
-
|
| 1230 |
-
|
| 1231 |
-
|
| 1232 |
-
|
| 1233 |
|
| 1234 |
-
hexaGrid.queue(default_concurrency_limit=1,max_size=12,api_open=False)
|
| 1235 |
-
hexaGrid.launch(allowed_paths=["assets","/","./assets","images","./images", "./images/prerendered"], favicon_path="./assets/favicon.ico", max_file_size="10mb")
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
|
| 3 |
import os
|
| 4 |
# Import constants
|
| 5 |
import numpy as np
|
|
|
|
| 10 |
import cv2
|
| 11 |
import utils.constants as constants
|
| 12 |
|
|
|
|
| 13 |
from haishoku.haishoku import Haishoku
|
| 14 |
|
| 15 |
from tempfile import NamedTemporaryFile
|
|
|
|
| 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
|
| 24 |
|
| 25 |
IS_SHARED_SPACE = constants.IS_SHARED_SPACE
|
|
|
|
| 87 |
"FluxControlPipeline": FluxControlPipeline
|
| 88 |
}
|
| 89 |
|
| 90 |
+
import spaces
|
| 91 |
#from utils.depth_estimation import generate_depth_and_3d
|
| 92 |
|
| 93 |
|
|
|
|
| 299 |
type_id = torch.ones_like(ids[:, :1]) * self.type_id
|
| 300 |
return tokens, ids, type_id
|
| 301 |
|
| 302 |
+
@spaces.GPU(duration=140, progress=gr.Progress(track_tqdm=True))
|
| 303 |
+
def generate_image(pipe, generate_params, progress=gr.Progress(track_tqdm=True)):
|
| 304 |
+
return pipe(**generate_params)
|
| 305 |
+
|
| 306 |
+
@spaces.GPU()
|
| 307 |
def generate_image_lowmem(
|
| 308 |
text,
|
| 309 |
neg_prompt=None,
|
|
|
|
| 505 |
generate_params = {k: v for k, v in generate_params.items() if v is not None}
|
| 506 |
print(f"generate_params: {generate_params}")
|
| 507 |
# Generate the image
|
| 508 |
+
result = generate_image(pipe,generate_params)
|
| 509 |
image = result.images[0]
|
| 510 |
# Clean up
|
| 511 |
del result
|
|
|
|
| 701 |
|
| 702 |
@spaces.GPU()
|
| 703 |
def estimate_depth(image):
|
| 704 |
+
|
| 705 |
|
| 706 |
# Ensure image is in RGB mode
|
| 707 |
if image.mode != "RGB":
|
|
|
|
| 744 |
return depth_pil, output
|
| 745 |
|
| 746 |
@spaces.GPU()
|
| 747 |
+
def create_3d_model(rgb_image, depth_array, voxel_size_factor=0.01, depth=10):
|
| 748 |
import open3d as o3d
|
| 749 |
depth_o3d = o3d.geometry.Image(depth_array.astype(np.float32))
|
| 750 |
+
rgb_o3d = o3d.geometry.Image(np.array(rgb_image))
|
| 751 |
|
| 752 |
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
|
| 753 |
rgb_o3d,
|
| 754 |
depth_o3d,
|
| 755 |
+
convert_rgb_to_intensity=False
|
| 756 |
)
|
| 757 |
|
| 758 |
# Create a point cloud from the RGBD image
|
|
|
|
| 769 |
rgbd_image,
|
| 770 |
camera_intrinsic
|
| 771 |
)
|
| 772 |
+
# ########
|
| 773 |
+
print("normals\n")
|
| 774 |
+
pcd.normals = o3d.utility.Vector3dVector(
|
| 775 |
+
np.zeros((1, 3))
|
| 776 |
+
) # invalidate existing normals
|
| 777 |
+
pcd.estimate_normals(
|
| 778 |
+
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)
|
| 779 |
+
)
|
| 780 |
+
pcd.orient_normals_towards_camera_location(
|
| 781 |
+
camera_location=np.array([0.0, 0.0, 832.0])
|
| 782 |
+
)
|
| 783 |
+
pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
|
| 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 |
# Voxel downsample
|
| 793 |
+
voxel_size = max(pcd.get_max_bound() - pcd.get_min_bound()) / (max(rgb_image.size) * voxel_size_factor)
|
| 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 |
+
# vertices_to_remove = densities < np.quantile(densities, 0.001)
|
| 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 3D model to a temporary file
|
| 807 |
temp_dir = Path.cwd() / "temp_models"
|
| 808 |
temp_dir.mkdir(exist_ok=True)
|
| 809 |
+
model_path = temp_dir / "model.gltf"
|
| 810 |
+
#o3d.io.write_voxel_grid(str(model_path), voxel_grid)
|
| 811 |
+
o3d.io.write_triangle_mesh(str(model_path), mesh_crop, write_triangle_uvs=True)
|
| 812 |
|
| 813 |
return str(model_path)
|
| 814 |
|
|
|
|
| 903 |
key="imgInput",
|
| 904 |
image_mode=None,
|
| 905 |
format="PNG",
|
| 906 |
+
show_download_button=True
|
| 907 |
)
|
| 908 |
|
| 909 |
# New code to convert input image to RGBA PNG
|
|
|
|
| 1002 |
# Update map_options to a Dropdown with choices from constants.PROMPTS keys
|
| 1003 |
with gr.Row():
|
| 1004 |
with gr.Column():
|
| 1005 |
+
map_options = gr.Dropdown(
|
| 1006 |
+
label="Map Options",
|
| 1007 |
+
choices=list(constants.PROMPTS.keys()),
|
| 1008 |
+
value="Alien Landscape",
|
| 1009 |
+
elem_classes="solid",
|
| 1010 |
+
scale=0
|
| 1011 |
)
|
|
|
|
| 1012 |
# Add Dropdown for sizing of Images, height and width based on selection. Options are 16x9, 16x10, 4x5, 1x1
|
| 1013 |
# The values of height and width are based on common resolutions for each aspect ratio
|
| 1014 |
# Default to 16x9, 912x512
|
|
|
|
| 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 |
depth_map_output = gr.Image(label="Depth Map", image_mode="L", elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgDepth")
|
| 1148 |
+
model_output = gr.Model3D(label="3D Model", clear_color=[1.0, 1.0, 1.0, 1.0], key="Img3D", elem_classes="centered solid imgcontainer")
|
| 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],
|
|
|
|
| 1246 |
scroll_to_output=True
|
| 1247 |
)
|
| 1248 |
|
| 1249 |
+
hexaGrid.queue(default_concurrency_limit=1,max_size=12,api_open=False)
|
| 1250 |
+
hexaGrid.launch(allowed_paths=["assets","/","./assets","images","./images", "./images/prerendered"], favicon_path="./assets/favicon.ico", max_file_size="10mb")
|
| 1251 |
|
| 1252 |
if __name__ == "__main__":
|
| 1253 |
logging.basicConfig(
|
| 1254 |
format="[%(levelname)s] %(asctime)s %(message)s", level=logging.INFO
|
| 1255 |
)
|
| 1256 |
logging.info("Environment Variables: %s" % os.environ)
|
| 1257 |
+
# if _get_output(["nvcc", "--version"]) is None:
|
| 1258 |
+
# logging.info("Installing CUDA toolkit...")
|
| 1259 |
+
# install_cuda_toolkit()
|
| 1260 |
+
# else:
|
| 1261 |
+
# logging.info("Detected CUDA: %s" % _get_output(["nvcc", "--version"]))
|
| 1262 |
|
| 1263 |
+
# logging.info("Installing CUDA extensions...")
|
| 1264 |
+
# setup_runtime_env()
|
| 1265 |
+
#main(os.getenv("DEBUG") == "1")
|
| 1266 |
+
#main()
|
| 1267 |
|
|
|
|
|
|
utils/image_utils.py
CHANGED
|
@@ -7,7 +7,6 @@ import numpy as np
|
|
| 7 |
#from decimal import ROUND_CEILING
|
| 8 |
from PIL import Image, ImageChops, ImageDraw, ImageEnhance, ImageFilter, ImageDraw, ImageOps, ImageMath
|
| 9 |
from typing import List, Union
|
| 10 |
-
#import numpy as np
|
| 11 |
#import math
|
| 12 |
from pathlib import Path
|
| 13 |
from utils.constants import default_lut_example_img
|
|
|
|
| 7 |
#from decimal import ROUND_CEILING
|
| 8 |
from PIL import Image, ImageChops, ImageDraw, ImageEnhance, ImageFilter, ImageDraw, ImageOps, ImageMath
|
| 9 |
from typing import List, Union
|
|
|
|
| 10 |
#import math
|
| 11 |
from pathlib import Path
|
| 12 |
from utils.constants import default_lut_example_img
|
web-ui.bat
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
set NVIDIA_VISIBLE_DEVICES=0
|
| 2 |
set CUDA_VISIBLE_DEVICES=0
|
| 3 |
set CUDA_MODULE_LOADING=LAZY
|
| 4 |
-
|
| 5 |
pause
|
|
|
|
| 1 |
set NVIDIA_VISIBLE_DEVICES=0
|
| 2 |
set CUDA_VISIBLE_DEVICES=0
|
| 3 |
set CUDA_MODULE_LOADING=LAZY
|
| 4 |
+
py -m app
|
| 5 |
pause
|