Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -30,10 +30,21 @@ def fourier_transform_drawing(input_image, frames, coefficients, img_size):
|
|
30 |
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
31 |
|
32 |
# find the contour with the largest area
|
33 |
-
largest_contour_idx = np.argmax([cv2.contourArea(c) for c in contours])
|
34 |
-
largest_contour = contours[largest_contour_idx]
|
35 |
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
xs, ys = zip(*verts)
|
39 |
xs, ys = np.asarray(xs), np.asarray(ys)
|
@@ -65,33 +76,19 @@ def fourier_transform_drawing(input_image, frames, coefficients, img_size):
|
|
65 |
coef = np.trapz(f_exp * np.exp(-n * t_values * 1j), t_values) / tau
|
66 |
return coef
|
67 |
|
68 |
-
#
|
69 |
-
|
70 |
|
71 |
N = coefficients
|
72 |
indices = [0] + [j for i in range(1, N + 1) for j in (i, -i)]
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
# Parallelize the computation of coefficients
|
77 |
with ThreadPoolExecutor() as executor:
|
78 |
-
|
|
|
79 |
|
80 |
-
# Ensure the zeroth coefficient is computed only once
|
81 |
coefs = [(coefs[0][0], 0)] + coefs[1:]
|
82 |
|
83 |
-
# def compute_cn(n, t_list, xs, ys):
|
84 |
-
# """
|
85 |
-
# Integrate the contour along axis (-1) using the composite trapezoidal rule.
|
86 |
-
# https://numpy.org/doc/stable/reference/generated/numpy.trapz.html#r7aa6c77779c0-2
|
87 |
-
# """
|
88 |
-
# f_exp = np.interp(t_values, t_list, xs + 1j * ys) * np.exp(-n * t_values * 1j)
|
89 |
-
# coef = np.trapz(f_exp, t_values) / tau
|
90 |
-
# return coef
|
91 |
-
|
92 |
-
# N = coefficients
|
93 |
-
# coefs = [(compute_cn(0, t_list, xs, ys), 0)] + [(compute_cn(j, t_list, xs, ys), j) for i in range(1, N+1) for j in (i, -i)]
|
94 |
-
|
95 |
# animate the drawings
|
96 |
fig, ax = plt.subplots()
|
97 |
circles = [ax.plot([], [], 'b-')[0] for _ in range(-N, N+1)]
|
@@ -106,17 +103,15 @@ def fourier_transform_drawing(input_image, frames, coefficients, img_size):
|
|
106 |
|
107 |
draw_x, draw_y = [], []
|
108 |
|
109 |
-
#
|
110 |
theta = np.linspace(0, tau, 80)
|
111 |
-
coefs_static = [(np.linalg.norm(c), fr) for c, fr in coefs]
|
112 |
|
113 |
def animate(i, coefs, time):
|
114 |
-
t = time[i]
|
115 |
center = (0, 0)
|
116 |
-
|
117 |
-
# Loop over coefficients
|
118 |
for _, (r, fr) in enumerate(coefs_static):
|
119 |
-
c_dynamic = coefs[_][0] * np.exp(1j * (fr * tau *
|
120 |
x, y = center[0] + r * np.cos(theta), center[1] + r * np.sin(theta)
|
121 |
circle_lines[_].set_data([center[0], center[0] + np.real(c_dynamic)], [center[1], center[1] + np.imag(c_dynamic)])
|
122 |
circles[_].set_data(x, y)
|
|
|
30 |
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
31 |
|
32 |
# find the contour with the largest area
|
33 |
+
# largest_contour_idx = np.argmax([cv2.contourArea(c) for c in contours])
|
34 |
+
# largest_contour = contours[largest_contour_idx]
|
35 |
|
36 |
+
# combine contours
|
37 |
+
def combine_all_contours(contours):
|
38 |
+
combined_contour = np.array([], dtype=np.int32).reshape(0, 1, 2)
|
39 |
+
|
40 |
+
for contour in contours:
|
41 |
+
combined_contour = np.vstack((combined_contour, contour))
|
42 |
+
|
43 |
+
return combined_contour
|
44 |
+
|
45 |
+
largest_contour = combine_all_contours(contours)
|
46 |
+
|
47 |
+
verts = [tuple(coord) for coord in largest_contour.squeeze()]
|
48 |
|
49 |
xs, ys = zip(*verts)
|
50 |
xs, ys = np.asarray(xs), np.asarray(ys)
|
|
|
76 |
coef = np.trapz(f_exp * np.exp(-n * t_values * 1j), t_values) / tau
|
77 |
return coef
|
78 |
|
79 |
+
# pre-compute the interpolated values
|
80 |
+
f_precomputed = np.interp(t_values, t_list, xs + 1j * ys)
|
81 |
|
82 |
N = coefficients
|
83 |
indices = [0] + [j for i in range(1, N + 1) for j in (i, -i)]
|
84 |
|
85 |
+
# parallelize the computation of coefficients
|
|
|
|
|
86 |
with ThreadPoolExecutor() as executor:
|
87 |
+
print("Number of threads used:", executor._max_workers)
|
88 |
+
coefs = list(executor.map(lambda n: (compute_cn(f_precomputed, n, t_values), n), indices))
|
89 |
|
|
|
90 |
coefs = [(coefs[0][0], 0)] + coefs[1:]
|
91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
# animate the drawings
|
93 |
fig, ax = plt.subplots()
|
94 |
circles = [ax.plot([], [], 'b-')[0] for _ in range(-N, N+1)]
|
|
|
103 |
|
104 |
draw_x, draw_y = [], []
|
105 |
|
106 |
+
# pre-compute static values outside the animate function
|
107 |
theta = np.linspace(0, tau, 80)
|
108 |
+
coefs_static = [(np.linalg.norm(c), fr) for c, fr in coefs]
|
109 |
|
110 |
def animate(i, coefs, time):
|
|
|
111 |
center = (0, 0)
|
112 |
+
|
|
|
113 |
for _, (r, fr) in enumerate(coefs_static):
|
114 |
+
c_dynamic = coefs[_][0] * np.exp(1j * (fr * tau * time[i]))
|
115 |
x, y = center[0] + r * np.cos(theta), center[1] + r * np.sin(theta)
|
116 |
circle_lines[_].set_data([center[0], center[0] + np.real(c_dynamic)], [center[1], center[1] + np.imag(c_dynamic)])
|
117 |
circles[_].set_data(x, y)
|