Spaces:
Build error
Build error
nick-leland
commited on
Commit
·
f148267
1
Parent(s):
b6fa050
Updated the app, reformated the way that the app functions
Browse files
app.py
CHANGED
@@ -10,10 +10,14 @@ import fastai
|
|
10 |
from fastcore.all import *
|
11 |
from fastai.vision.all import *
|
12 |
from ultralytics import YOLO
|
|
|
13 |
|
14 |
def apply_vector_field_transform(image, func, radius, center=(0.5, 0.5), strength=1, edge_smoothness=0.1, center_smoothness=0.20):
|
15 |
rows, cols = image.shape[:2]
|
16 |
max_dim = max(rows, cols)
|
|
|
|
|
|
|
17 |
|
18 |
center_y = int(center[1] * rows)
|
19 |
center_x = int(center[0] * cols)
|
@@ -137,9 +141,6 @@ def create_gradient_vector_field(gx, gy, image_shape, step=20, reverse=False):
|
|
137 |
|
138 |
return vector_field
|
139 |
|
140 |
-
import numpy as np
|
141 |
-
from scipy import interpolate
|
142 |
-
|
143 |
# def invert_gradient_vector_field(gx, gy, image_shape):
|
144 |
# """
|
145 |
# Invert the gradient vector field using a more accurate method.
|
@@ -210,6 +211,57 @@ def apply_gradient_transform(image, gx, gy):
|
|
210 |
|
211 |
return transformed_image
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
#############################
|
214 |
# MAIN FUNCTION HERE
|
215 |
#############################
|
@@ -228,7 +280,23 @@ model = YOLO("bulge_yolo_model.pt")
|
|
228 |
def transform_image(image, func_choice, randomization_check, radius, center_x, center_y, strength, reverse_gradient=True, spiral_frequency=1):
|
229 |
I = np.asarray(Image.open(image))
|
230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
def pinch(x, y):
|
|
|
|
|
|
|
|
|
232 |
return x**2 + y**2
|
233 |
|
234 |
def shift(x, y):
|
@@ -247,40 +315,82 @@ def transform_image(image, func_choice, randomization_check, radius, center_x, c
|
|
247 |
if randomization_check:
|
248 |
radius, location, strength, edge_smoothness = definitions(rng)
|
249 |
center_x, center_y = location
|
|
|
250 |
else:
|
251 |
edge_smoothness, center_smoothness = smooth(rng, strength)
|
252 |
|
253 |
if func_choice == "Pinch":
|
254 |
func = pinch
|
|
|
|
|
|
|
255 |
elif func_choice == "Spiral":
|
256 |
func = shift
|
|
|
|
|
|
|
257 |
elif func_choice == "Bulge":
|
258 |
func = bulge
|
259 |
edge_smoothness = 0
|
260 |
center_smoothness = 0
|
261 |
elif func_choice == "Volcano":
|
262 |
func = bulge
|
|
|
|
|
|
|
263 |
elif func_choice == "Shift Up":
|
264 |
func = lambda x, y: spiral(x, y, frequency=spiral_frequency)
|
|
|
|
|
265 |
|
266 |
|
267 |
print(f"Function choice: {func_choice}")
|
268 |
print(f"Input image shape: {I.shape}")
|
|
|
|
|
|
|
269 |
|
270 |
try:
|
271 |
-
|
272 |
-
|
273 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
print(f"Transformed image shape: {transformed.shape}")
|
275 |
print(f"Inverse transformed image shape: {inverse_transformed.shape}")
|
276 |
-
print(f"Gradient shapes: gx {gx.shape}, gy {gy.shape}")
|
277 |
-
print(f"Gradient ranges: gx [{np.min(gx)}, {np.max(gx)}], gy [{np.min(gy)}, {np.max(gy)}]")
|
278 |
|
279 |
vector_field = create_gradient_vector_field(gx, gy, I.shape[:2], reverse=reverse_gradient)
|
280 |
-
inverted_vector_field = create_gradient_vector_field(
|
281 |
|
282 |
print(f"Vector field shape: {vector_field.shape}")
|
283 |
print(f"Inverted vector field shape: {inverted_vector_field.shape}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
except Exception as e:
|
285 |
print(f"Error in transformation: {str(e)}")
|
286 |
traceback.print_exc()
|
@@ -306,6 +416,7 @@ def transform_image(image, func_choice, randomization_check, radius, center_x, c
|
|
306 |
|
307 |
return transformed, result_bias_final, result_fresh_final, vector_field, inverse_transformed, inverted_vector_field
|
308 |
|
|
|
309 |
demo = gr.Interface(
|
310 |
fn=transform_image,
|
311 |
inputs=[
|
|
|
10 |
from fastcore.all import *
|
11 |
from fastai.vision.all import *
|
12 |
from ultralytics import YOLO
|
13 |
+
import cv2
|
14 |
|
15 |
def apply_vector_field_transform(image, func, radius, center=(0.5, 0.5), strength=1, edge_smoothness=0.1, center_smoothness=0.20):
|
16 |
rows, cols = image.shape[:2]
|
17 |
max_dim = max(rows, cols)
|
18 |
+
print()
|
19 |
+
print(f"Max_dim is {max_dim}")
|
20 |
+
print()
|
21 |
|
22 |
center_y = int(center[1] * rows)
|
23 |
center_x = int(center[0] * cols)
|
|
|
141 |
|
142 |
return vector_field
|
143 |
|
|
|
|
|
|
|
144 |
# def invert_gradient_vector_field(gx, gy, image_shape):
|
145 |
# """
|
146 |
# Invert the gradient vector field using a more accurate method.
|
|
|
211 |
|
212 |
return transformed_image
|
213 |
|
214 |
+
def generate_function_gradient(func, image_shape, radius, center=(0.5, 0.5), strength=1, edge_smoothness=0.1, center_smoothness=0.20):
|
215 |
+
rows, cols = image_shape[:2]
|
216 |
+
max_dim = max(rows, cols)
|
217 |
+
|
218 |
+
y, x = np.mgrid[0:rows, 0:cols].astype(np.float32)
|
219 |
+
y = (y - center[1] * rows) / max_dim
|
220 |
+
x = (x - center[0] * cols) / max_dim
|
221 |
+
|
222 |
+
dist_from_center = np.sqrt(x**2 + y**2)
|
223 |
+
|
224 |
+
z = func(x, y)
|
225 |
+
|
226 |
+
gy, gx = np.gradient(z)
|
227 |
+
|
228 |
+
edge_smoothness = np.maximum(edge_smoothness, 1e-6)
|
229 |
+
center_smoothness = np.maximum(center_smoothness, 1e-6)
|
230 |
+
|
231 |
+
edge_mask = np.clip((radius - dist_from_center) / (radius * edge_smoothness), 0, 1)
|
232 |
+
center_mask = np.clip((dist_from_center - radius * center_smoothness) / (radius * center_smoothness), 0, 1)
|
233 |
+
mask = edge_mask * center_mask
|
234 |
+
|
235 |
+
gx *= mask
|
236 |
+
gy *= mask
|
237 |
+
|
238 |
+
magnitude = np.sqrt(gx**2 + gy**2)
|
239 |
+
max_magnitude = np.max(magnitude)
|
240 |
+
if max_magnitude > 0:
|
241 |
+
gx /= max_magnitude
|
242 |
+
gy /= max_magnitude
|
243 |
+
|
244 |
+
# Increase the base scale factor
|
245 |
+
base_scale = radius * max_dim * 0.2 # Increased from 0.1 to 0.2
|
246 |
+
|
247 |
+
# Apply a non-linear scaling to the strength
|
248 |
+
adjusted_strength = np.power(strength, 1.5) # This will make the effect more pronounced at higher strengths
|
249 |
+
|
250 |
+
# Increase the maximum strength multiplier
|
251 |
+
scale_factor = base_scale * np.clip(adjusted_strength, 0, 3) # Increased max from 2 to 3
|
252 |
+
|
253 |
+
# Apply an additional scaling factor based on image size
|
254 |
+
size_factor = np.log(max_dim) / np.log(1000) # This will be 1 for 1000x1000 images, larger for bigger images
|
255 |
+
scale_factor *= size_factor
|
256 |
+
|
257 |
+
gx *= scale_factor
|
258 |
+
gy *= scale_factor
|
259 |
+
|
260 |
+
print(f"Final scale factor: {scale_factor}")
|
261 |
+
print(f"Final gradient ranges: gx [{np.min(gx)}, {np.max(gx)}], gy [{np.min(gy)}, {np.max(gy)}]")
|
262 |
+
|
263 |
+
return gx, gy
|
264 |
+
|
265 |
#############################
|
266 |
# MAIN FUNCTION HERE
|
267 |
#############################
|
|
|
280 |
def transform_image(image, func_choice, randomization_check, radius, center_x, center_y, strength, reverse_gradient=True, spiral_frequency=1):
|
281 |
I = np.asarray(Image.open(image))
|
282 |
|
283 |
+
# Downsample large images
|
284 |
+
max_size = 1024 # Increased from 512 to allow for more detail
|
285 |
+
if max(I.shape[:2]) > max_size:
|
286 |
+
scale = max_size / max(I.shape[:2])
|
287 |
+
new_size = (int(I.shape[1] * scale), int(I.shape[0] * scale))
|
288 |
+
I = cv2.resize(I, new_size, interpolation=cv2.INTER_AREA)
|
289 |
+
print(f"Downsampled image to {I.shape}")
|
290 |
+
|
291 |
+
##################################
|
292 |
+
# Transformation Functions #
|
293 |
+
##################################
|
294 |
+
|
295 |
def pinch(x, y):
|
296 |
+
r = np.sqrt(x**2 + y**2)
|
297 |
+
return r
|
298 |
+
|
299 |
+
def zoom(x, y):
|
300 |
return x**2 + y**2
|
301 |
|
302 |
def shift(x, y):
|
|
|
315 |
if randomization_check:
|
316 |
radius, location, strength, edge_smoothness = definitions(rng)
|
317 |
center_x, center_y = location
|
318 |
+
center_smoothness = edge_smoothness
|
319 |
else:
|
320 |
edge_smoothness, center_smoothness = smooth(rng, strength)
|
321 |
|
322 |
if func_choice == "Pinch":
|
323 |
func = pinch
|
324 |
+
edge_smoothness = 0
|
325 |
+
center_smoothness = 0
|
326 |
+
|
327 |
elif func_choice == "Spiral":
|
328 |
func = shift
|
329 |
+
edge_smoothness = 0
|
330 |
+
center_smoothness = 0
|
331 |
+
|
332 |
elif func_choice == "Bulge":
|
333 |
func = bulge
|
334 |
edge_smoothness = 0
|
335 |
center_smoothness = 0
|
336 |
elif func_choice == "Volcano":
|
337 |
func = bulge
|
338 |
+
edge_smoothness = 0
|
339 |
+
center_smoothness = 0
|
340 |
+
|
341 |
elif func_choice == "Shift Up":
|
342 |
func = lambda x, y: spiral(x, y, frequency=spiral_frequency)
|
343 |
+
edge_smoothness = 0
|
344 |
+
center_smoothness = 0
|
345 |
|
346 |
|
347 |
print(f"Function choice: {func_choice}")
|
348 |
print(f"Input image shape: {I.shape}")
|
349 |
+
print(f"Radius: {radius}, Center: ({center_x}, {center_y}), Strength: {strength}")
|
350 |
+
|
351 |
+
# strength = strength * 2 # This allows for stronger effects
|
352 |
|
353 |
try:
|
354 |
+
# Generate gradients
|
355 |
+
gx, gy = generate_function_gradient(func, I.shape, radius, (center_x, center_y), strength, edge_smoothness, center_smoothness)
|
356 |
+
|
357 |
+
# Vectorized transformation
|
358 |
+
rows, cols = I.shape[:2]
|
359 |
+
y, x = np.mgrid[0:rows, 0:cols].astype(np.float32)
|
360 |
+
|
361 |
+
x_new = x + gx
|
362 |
+
y_new = y + gy
|
363 |
+
|
364 |
+
x_new = np.clip(x_new, 0, cols - 1)
|
365 |
+
y_new = np.clip(y_new, 0, rows - 1)
|
366 |
+
|
367 |
+
transformed = cv2.remap(I, x_new, y_new, cv2.INTER_LINEAR)
|
368 |
+
|
369 |
+
inv_gx, inv_gy = -gx, -gy
|
370 |
+
x_inv = x + inv_gx
|
371 |
+
y_inv = y + inv_gy
|
372 |
+
x_inv = np.clip(x_inv, 0, cols - 1)
|
373 |
+
y_inv = np.clip(y_inv, 0, rows - 1)
|
374 |
+
|
375 |
+
inverse_transformed = cv2.remap(I, x_inv, y_inv, cv2.INTER_LINEAR)
|
376 |
+
|
377 |
print(f"Transformed image shape: {transformed.shape}")
|
378 |
print(f"Inverse transformed image shape: {inverse_transformed.shape}")
|
|
|
|
|
379 |
|
380 |
vector_field = create_gradient_vector_field(gx, gy, I.shape[:2], reverse=reverse_gradient)
|
381 |
+
inverted_vector_field = create_gradient_vector_field(inv_gx, inv_gy, I.shape[:2], reverse=False)
|
382 |
|
383 |
print(f"Vector field shape: {vector_field.shape}")
|
384 |
print(f"Inverted vector field shape: {inverted_vector_field.shape}")
|
385 |
+
|
386 |
+
# If we downsampled earlier, upsample the results back to original size
|
387 |
+
if max(I.shape[:2]) != max(np.asarray(Image.open(image)).shape[:2]):
|
388 |
+
original_size = np.asarray(Image.open(image)).shape[:2][::-1]
|
389 |
+
transformed = cv2.resize(transformed, original_size, interpolation=cv2.INTER_LINEAR)
|
390 |
+
inverse_transformed = cv2.resize(inverse_transformed, original_size, interpolation=cv2.INTER_LINEAR)
|
391 |
+
vector_field = cv2.resize(vector_field, original_size, interpolation=cv2.INTER_LINEAR)
|
392 |
+
inverted_vector_field = cv2.resize(inverted_vector_field, original_size, interpolation=cv2.INTER_LINEAR)
|
393 |
+
|
394 |
except Exception as e:
|
395 |
print(f"Error in transformation: {str(e)}")
|
396 |
traceback.print_exc()
|
|
|
416 |
|
417 |
return transformed, result_bias_final, result_fresh_final, vector_field, inverse_transformed, inverted_vector_field
|
418 |
|
419 |
+
|
420 |
demo = gr.Interface(
|
421 |
fn=transform_image,
|
422 |
inputs=[
|