NightRaven109 commited on
Commit
5319ec3
·
verified ·
1 Parent(s): 1e0e767

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -9
app.py CHANGED
@@ -12,6 +12,110 @@ model_configs = {
12
  'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024]}
13
  }
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def get_image_intensity(img, gamma_correction=1.0):
16
  """
17
  Extract intensity map from an image using HSV color space
@@ -43,6 +147,34 @@ def blend_numpy_images(image1, image2, blend_factor=0.4, mode="normal"):
43
  blended = (blended * 255.0).clip(0, 255).astype(np.uint8)
44
  return blended
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  # Initialize model globally
47
  def initialize_model():
48
  encoder = 'vitl'
@@ -73,10 +205,10 @@ MODEL = initialize_model()
73
  @spaces.GPU
74
  def process_image(input_image):
75
  """
76
- Process the input image and return depth maps, intensity map, and blended result
77
  """
78
  if input_image is None:
79
- return None, None, None, None
80
 
81
  # Move model to GPU for processing
82
  MODEL.to('cuda')
@@ -110,16 +242,19 @@ def process_image(input_image):
110
  mode="normal"
111
  )
112
 
113
- return depth_normalized, depth_colormap, intensity_map, blended_result
 
 
 
114
 
115
  @spaces.GPU
116
  def gradio_interface(input_img):
117
  try:
118
- depth_raw, depth_colored, intensity, blended = process_image(input_img)
119
- return [input_img, depth_raw, depth_colored, intensity, blended]
120
  except Exception as e:
121
  print(f"Error processing image: {str(e)}")
122
- return [input_img, None, None, None, None]
123
 
124
  # Define interface
125
  iface = gr.Interface(
@@ -130,10 +265,11 @@ iface = gr.Interface(
130
  gr.Image(label="Raw Depth Map"),
131
  gr.Image(label="Colored Depth Map"),
132
  gr.Image(label="Intensity Map"),
133
- gr.Image(label="Blended (Depth + Intensity)")
 
134
  ],
135
- title="Depth and Intensity Estimation",
136
- description="Upload an image to generate its depth map, intensity map, and blended result.",
137
  examples=["image.jpg"]
138
  )
139
 
 
12
  'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024]}
13
  }
14
 
15
+ class NormalMapSimple:
16
+ @classmethod
17
+ def INPUT_TYPES(s):
18
+ return {
19
+ "required": {
20
+ "images": ("IMAGE",),
21
+ "scale_XY": ("FLOAT",{"default": 1, "min": 0, "max": 100, "step": 0.001}),
22
+ },
23
+ }
24
+
25
+ RETURN_TYPES = ("IMAGE",)
26
+ FUNCTION = "normal_map"
27
+
28
+ CATEGORY = "image/filters"
29
+
30
+ def normal_map(self, images, scale_XY):
31
+ t = images.detach().clone().cpu().numpy().astype(np.float32)
32
+ L = np.mean(t[:,:,:,:3], axis=3)
33
+ for i in range(t.shape[0]):
34
+ t[i,:,:,0] = cv2.Scharr(L[i], -1, 1, 0, cv2.BORDER_REFLECT) * -1
35
+ t[i,:,:,1] = cv2.Scharr(L[i], -1, 0, 1, cv2.BORDER_REFLECT)
36
+ t[:,:,:,2] = 1
37
+ t = torch.from_numpy(t)
38
+ t[:,:,:,:2] *= scale_XY
39
+ t[:,:,:,:3] = torch.nn.functional.normalize(t[:,:,:,:3], dim=3) / 2 + 0.5
40
+ return (t,)
41
+
42
+ class ConvertNormals:
43
+ @classmethod
44
+ def INPUT_TYPES(s):
45
+ return {
46
+ "required": {
47
+ "normals": ("IMAGE",),
48
+ "input_mode": (["BAE", "MiDaS", "Standard", "DirectX"],),
49
+ "output_mode": (["BAE", "MiDaS", "Standard", "DirectX"],),
50
+ "scale_XY": ("FLOAT",{"default": 1, "min": 0, "max": 100, "step": 0.001}),
51
+ "normalize": ("BOOLEAN", {"default": True}),
52
+ "fix_black": ("BOOLEAN", {"default": True}),
53
+ },
54
+ "optional": {
55
+ "optional_fill": ("IMAGE",),
56
+ },
57
+ }
58
+
59
+ RETURN_TYPES = ("IMAGE",)
60
+ FUNCTION = "convert_normals"
61
+
62
+ CATEGORY = "image/filters"
63
+
64
+ def convert_normals(self, normals, input_mode, output_mode, scale_XY, normalize, fix_black, optional_fill=None):
65
+ try:
66
+ t = normals.detach().clone()
67
+
68
+ if input_mode == "BAE":
69
+ t[:,:,:,0] = 1 - t[:,:,:,0] # invert R
70
+ elif input_mode == "MiDaS":
71
+ t[:,:,:,:3] = torch.stack([1 - t[:,:,:,2], t[:,:,:,1], t[:,:,:,0]], dim=3) # BGR -> RGB and invert R
72
+ elif input_mode == "DirectX":
73
+ t[:,:,:,1] = 1 - t[:,:,:,1] # invert G
74
+
75
+ if fix_black:
76
+ key = torch.clamp(1 - t[:,:,:,2] * 2, min=0, max=1)
77
+ if optional_fill is None:
78
+ t[:,:,:,0] += key * 0.5
79
+ t[:,:,:,1] += key * 0.5
80
+ t[:,:,:,2] += key
81
+ else:
82
+ fill = optional_fill.detach().clone()
83
+ if fill.shape[1:3] != t.shape[1:3]:
84
+ fill = torch.nn.functional.interpolate(fill.movedim(-1,1), size=(t.shape[1], t.shape[2]), mode='bilinear').movedim(1,-1)
85
+ if fill.shape[0] != t.shape[0]:
86
+ fill = fill[0].unsqueeze(0).expand(t.shape[0], -1, -1, -1)
87
+ t[:,:,:,:3] += fill[:,:,:,:3] * key.unsqueeze(3).expand(-1, -1, -1, 3)
88
+
89
+ t[:,:,:,:2] = (t[:,:,:,:2] - 0.5) * scale_XY + 0.5
90
+
91
+ if normalize:
92
+ # Transform to [-1, 1] range
93
+ t_norm = t[:,:,:,:3] * 2 - 1
94
+
95
+ # Calculate the length of each vector
96
+ lengths = torch.sqrt(torch.sum(t_norm**2, dim=3, keepdim=True))
97
+
98
+ # Avoid division by zero
99
+ lengths = torch.clamp(lengths, min=1e-6)
100
+
101
+ # Normalize each vector to unit length
102
+ t_norm = t_norm / lengths
103
+
104
+ # Transform back to [0, 1] range
105
+ t[:,:,:,:3] = (t_norm + 1) / 2
106
+
107
+ if output_mode == "BAE":
108
+ t[:,:,:,0] = 1 - t[:,:,:,0] # invert R
109
+ elif output_mode == "MiDaS":
110
+ t[:,:,:,:3] = torch.stack([t[:,:,:,2], t[:,:,:,1], 1 - t[:,:,:,0]], dim=3) # invert R and BGR -> RGB
111
+ elif output_mode == "DirectX":
112
+ t[:,:,:,1] = 1 - t[:,:,:,1] # invert G
113
+
114
+ return (t,)
115
+ except Exception as e:
116
+ print(f"Error in convert_normals: {str(e)}")
117
+ return (normals,)
118
+
119
  def get_image_intensity(img, gamma_correction=1.0):
120
  """
121
  Extract intensity map from an image using HSV color space
 
147
  blended = (blended * 255.0).clip(0, 255).astype(np.uint8)
148
  return blended
149
 
150
+ def process_normal_map(image):
151
+ """
152
+ Process image through NormalMapSimple and ConvertNormals
153
+ """
154
+ # Convert numpy image to torch tensor with batch dimension
155
+ image_tensor = torch.from_numpy(image).unsqueeze(0).float() / 255.0
156
+
157
+ # Create instances of the classes
158
+ normal_map_generator = NormalMapSimple()
159
+ normal_converter = ConvertNormals()
160
+
161
+ # Generate initial normal map
162
+ normal_map = normal_map_generator.normal_map(image_tensor, scale_XY=1.0)[0]
163
+
164
+ # Convert normal map from Standard to DirectX
165
+ converted_normal = normal_converter.convert_normals(
166
+ normal_map,
167
+ input_mode="Standard",
168
+ output_mode="DirectX",
169
+ scale_XY=1.0,
170
+ normalize=True,
171
+ fix_black=True
172
+ )[0]
173
+
174
+ # Convert back to numpy array
175
+ result = (converted_normal.squeeze(0).numpy() * 255).astype(np.uint8)
176
+ return result
177
+
178
  # Initialize model globally
179
  def initialize_model():
180
  encoder = 'vitl'
 
205
  @spaces.GPU
206
  def process_image(input_image):
207
  """
208
+ Process the input image and return depth maps, intensity map, blended result, and normal map
209
  """
210
  if input_image is None:
211
+ return None, None, None, None, None
212
 
213
  # Move model to GPU for processing
214
  MODEL.to('cuda')
 
242
  mode="normal"
243
  )
244
 
245
+ # Generate normal map from blended result
246
+ normal_map = process_normal_map(blended_result)
247
+
248
+ return depth_normalized, depth_colormap, intensity_map, blended_result, normal_map
249
 
250
  @spaces.GPU
251
  def gradio_interface(input_img):
252
  try:
253
+ depth_raw, depth_colored, intensity, blended, normal = process_image(input_img)
254
+ return [input_img, depth_raw, depth_colored, intensity, blended, normal]
255
  except Exception as e:
256
  print(f"Error processing image: {str(e)}")
257
+ return [input_img, None, None, None, None, None]
258
 
259
  # Define interface
260
  iface = gr.Interface(
 
265
  gr.Image(label="Raw Depth Map"),
266
  gr.Image(label="Colored Depth Map"),
267
  gr.Image(label="Intensity Map"),
268
+ gr.Image(label="Blended (Depth + Intensity)"),
269
+ gr.Image(label="Normal Map")
270
  ],
271
+ title="Depth, Intensity, and Normal Map Estimation",
272
+ description="Upload an image to generate its depth map, intensity map, blended result, and normal map.",
273
  examples=["image.jpg"]
274
  )
275