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
|