Xallt commited on
Commit
10d8e71
·
1 Parent(s): c5e7a3b

Add notebook

Browse files
Files changed (1) hide show
  1. Vis.ipynb +388 -0
Vis.ipynb ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "%load_ext autoreload\n",
10
+ "%autoreload 2\n",
11
+ "import pandas as pd\n",
12
+ "import dotenv\n",
13
+ "import matplotlib.pyplot as plt\n",
14
+ "\n",
15
+ "dotenv.load_dotenv(\".env\")"
16
+ ]
17
+ },
18
+ {
19
+ "cell_type": "code",
20
+ "execution_count": 11,
21
+ "metadata": {},
22
+ "outputs": [],
23
+ "source": [
24
+ "from dataset import load_hoho_dataset\n",
25
+ "from process_sample import process_sample, read_colmap_rec\n",
26
+ "from example_solutions_copy import *"
27
+ ]
28
+ },
29
+ {
30
+ "cell_type": "code",
31
+ "execution_count": null,
32
+ "metadata": {},
33
+ "outputs": [],
34
+ "source": [
35
+ "dataset = load_hoho_dataset(testing=False)"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "code",
40
+ "execution_count": null,
41
+ "metadata": {},
42
+ "outputs": [],
43
+ "source": [
44
+ "from hoho2025.metric_helper import hss"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": null,
50
+ "metadata": {},
51
+ "outputs": [],
52
+ "source": [
53
+ "results = []\n",
54
+ "for i, sample in enumerate(dataset[\"train\"]):\n",
55
+ " gt = {\"wf_vertices\": sample[\"wf_vertices\"], \"wf_edges\": sample[\"wf_edges\"]}\n",
56
+ " \n",
57
+ " res = process_sample(sample, handle_error=False)\n",
58
+ " sample_good = convert_entry_to_human_readable(sample)\n",
59
+ " results.append(res)\n",
60
+ " print(\"LOSS\", hss(res[\"wf_vertices\"], res[\"wf_edges\"], gt[\"wf_vertices\"], gt[\"wf_edges\"]))\n",
61
+ " if i + 1 == 1:\n",
62
+ " break"
63
+ ]
64
+ },
65
+ {
66
+ "cell_type": "code",
67
+ "execution_count": null,
68
+ "metadata": {},
69
+ "outputs": [],
70
+ "source": [
71
+ "results = []\n",
72
+ "for i, sample in enumerate(dataset[\"train\"]):\n",
73
+ " gt = {\"wf_vertices\": sample[\"wf_vertices\"], \"wf_edges\": sample[\"wf_edges\"]}\n",
74
+ " \n",
75
+ " res = process_sample(sample, handle_error=False)\n",
76
+ " sample_good = convert_entry_to_human_readable(sample)\n",
77
+ " results.append(res)\n",
78
+ " print(\"LOSS\", hss(res[\"wf_vertices\"], res[\"wf_edges\"], gt[\"wf_vertices\"], gt[\"wf_edges\"]))\n",
79
+ " if i + 1 == 1:\n",
80
+ " break"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": 26,
86
+ "metadata": {},
87
+ "outputs": [],
88
+ "source": [
89
+ "good_entry = sample_good\n",
90
+ "rec = sample_good['colmap_binary']\n",
91
+ "for i, (gest, depth, K, R, t, img_id, ade_seg) in enumerate(\n",
92
+ " zip(\n",
93
+ " good_entry[\"gestalt\"],\n",
94
+ " good_entry[\"depth\"],\n",
95
+ " good_entry[\"K\"],\n",
96
+ " good_entry[\"R\"],\n",
97
+ " good_entry[\"t\"],\n",
98
+ " good_entry[\"image_ids\"],\n",
99
+ " good_entry[\"ade\"], # Added ade20k segmentation\n",
100
+ " )\n",
101
+ "):\n",
102
+ " if i == 1:\n",
103
+ " break"
104
+ ]
105
+ },
106
+ {
107
+ "cell_type": "code",
108
+ "execution_count": null,
109
+ "metadata": {},
110
+ "outputs": [],
111
+ "source": [
112
+ "plt.plot(contour[:, 0, 0], contour[:, 0, 1], c='r')\n",
113
+ "plt.scatter(contour[:, 0, 0], contour[:, 0, 1], c='g')\n",
114
+ "plt.show()\n",
115
+ "angles = []\n",
116
+ "for i in range(len(contour)):\n",
117
+ " vprev, vcur, vnext = contour[i-1, 0], contour[i, 0], contour[(i+1) % len(contour), 0]\n",
118
+ " vecprev, vecnext = vcur - vprev, vnext - vcur\n",
119
+ " vecprev = vecprev / np.linalg.norm(vecprev)\n",
120
+ " vecnext = vecnext / np.linalg.norm(vecnext)\n",
121
+ "\n",
122
+ " # curvature angle\n",
123
+ " angle = np.degrees(np.arctan2(np.cross(vecprev, vecnext), np.dot(vecprev, vecnext)))\n",
124
+ " angles.append(angle)\n",
125
+ "angles = np.array(angles)\n",
126
+ "plt.plot(angles)\n",
127
+ "plt.show()\n",
128
+ "\n",
129
+ "conv = 10\n",
130
+ "angles_convolved = np.array([np.sum(angles[i: i+conv]) for i in range(len(angles))])\n",
131
+ "plt.plot(angles_convolved)\n",
132
+ "plt.show()\n"
133
+ ]
134
+ },
135
+ {
136
+ "cell_type": "code",
137
+ "execution_count": 163,
138
+ "metadata": {},
139
+ "outputs": [],
140
+ "source": [
141
+ "angle_len = cv2.arcLength(contour, True) / 50\n",
142
+ "interesting_points = []\n",
143
+ "\n",
144
+ "for i in range(len(angles)):\n",
145
+ " j = i + 1\n",
146
+ " while True:\n",
147
+ " cur_len = cv2.arcLength(slice_arr(contour, i, j), False)\n",
148
+ " if cur_len > angle_len:\n",
149
+ " break\n",
150
+ " j += 1\n",
151
+ " # i:j is smaller than angle_len\n",
152
+ " turns = np.cumsum(slice_arr(angles, i, j))\n",
153
+ " if np.abs(turns).max() > 70:\n",
154
+ " interesting_points.append(i)"
155
+ ]
156
+ },
157
+ {
158
+ "cell_type": "code",
159
+ "execution_count": 52,
160
+ "metadata": {},
161
+ "outputs": [],
162
+ "source": [
163
+ "def get_turn_angles(contour):\n",
164
+ " angles = []\n",
165
+ " vcur = contour[:, 0] # (N, 2)\n",
166
+ " vprev = np.concatenate([vcur[-1, None], vcur[:-1]]) # (N, 2)\n",
167
+ " vnext = np.concatenate([vcur[1:], vcur[0, None]]) # (N, 2)\n",
168
+ "\n",
169
+ " vecprev, vecnext = vcur - vprev, vnext - vcur\n",
170
+ " vecprev = vecprev / np.linalg.norm(vecprev, axis=1, keepdims=True)\n",
171
+ " vecnext = vecnext / np.linalg.norm(vecnext, axis=1, keepdims=True)\n",
172
+ "\n",
173
+ " def dot(a, b):\n",
174
+ " return (a * b).sum(axis=-1)\n",
175
+ " angles = np.degrees(np.arctan2(np.cross(vecprev, vecnext), dot(vecprev, vecnext)))\n",
176
+ " return angles\n",
177
+ "def slice_arr(arr, i, j):\n",
178
+ " if i <= j:\n",
179
+ " if j <= len(arr):\n",
180
+ " return arr[i:j]\n",
181
+ " else:\n",
182
+ " return np.concatenate([arr[i:], arr[:j-len(arr)]])\n",
183
+ " else:\n",
184
+ " return np.concatenate([arr[i:], arr[:j]])\n",
185
+ "\n",
186
+ "def group_segments(segments):\n",
187
+ " segments = sorted(segments, key=lambda x: x[0])\n",
188
+ " grouped = []\n",
189
+ " for i in range(len(segments)):\n",
190
+ " if i == 0:\n",
191
+ " grouped.append(segments[i])\n",
192
+ " else:\n",
193
+ " if segments[i][0] <= grouped[-1][1]:\n",
194
+ " grouped[-1] = (grouped[-1][0], max(grouped[-1][1], segments[i][1]))\n",
195
+ " else:\n",
196
+ " grouped.append(segments[i])\n",
197
+ " return grouped\n",
198
+ "\n",
199
+ "def get_contour_interesting_points_indices(contour):\n",
200
+ " angles = get_turn_angles(contour)\n",
201
+ " angle_len = cv2.arcLength(contour, True) / 20\n",
202
+ "\n",
203
+ " interesting_segments = []\n",
204
+ " interesting_points = []\n",
205
+ " for i in range(len(angles)):\n",
206
+ " j = i + 1\n",
207
+ " while True:\n",
208
+ " cur_len = cv2.arcLength(slice_arr(contour, i, j), False)\n",
209
+ " if cur_len > angle_len:\n",
210
+ " break\n",
211
+ " j += 1\n",
212
+ " # i:j is smaller than angle_len\n",
213
+ " turns = np.cumsum(slice_arr(angles, i, j))\n",
214
+ " k = 2\n",
215
+ " if len(turns) > k and np.abs(turns[k:]).max() > 70:\n",
216
+ " matching_i = np.where(np.abs(turns[k:]) > 70)[0][0] + k + i\n",
217
+ " interesting_segments.append((i, int(matching_i)))\n",
218
+ " interesting_points.append(i)\n",
219
+ " \n",
220
+ " grouped_segments = group_segments(interesting_segments)\n",
221
+ " return [((i + j) // 2) % len(contour) for i, j in grouped_segments]\n",
222
+ " # return interesting_points\n",
223
+ "def get_contour_interesting_wireframe(contour):\n",
224
+ " indices = get_contour_interesting_points_indices(contour)\n",
225
+ " connections = []\n",
226
+ " for i in range(len(indices)):\n",
227
+ " i1, i2 = indices[i], indices[(i+1) % len(indices)]\n",
228
+ " segment_len = np.linalg.norm(contour[i1, 0] - contour[i2, 0])\n",
229
+ " points_side1 = slice_arr(contour[:, 0], i1, i2)\n",
230
+ " points_side2 = slice_arr(contour[:, 0], i2, i1)\n",
231
+ " points_side1_distances = np.array([point_to_segment_dist(p, contour[i1, 0], contour[i2, 0]) for p in points_side1])\n",
232
+ " points_side2_distances = np.array([point_to_segment_dist(p, contour[i2, 0], contour[i1, 0]) for p in points_side2])\n",
233
+ " dist_side_1 = points_side1_distances.max()\n",
234
+ " dist_side_2 = points_side2_distances.max()\n",
235
+ " factor = 0.1\n",
236
+ " if dist_side_1 <= segment_len * factor or dist_side_2 <= segment_len * factor:\n",
237
+ " connections.append((i, (i + 1) % len(indices)))\n",
238
+ " return contour[indices, 0], np.array(connections)\n"
239
+ ]
240
+ },
241
+ {
242
+ "cell_type": "code",
243
+ "execution_count": null,
244
+ "metadata": {},
245
+ "outputs": [],
246
+ "source": [
247
+ "angles = get_turn_angles(contour)\n",
248
+ "interesting_points, interesting_connections = get_contour_interesting_wireframe(contour)\n",
249
+ "ip_draw = np.concatenate([interesting_points, [interesting_points[0]]])\n",
250
+ "plt.axis('equal')\n",
251
+ "plt.plot(contour[:, 0, 0], contour[:, 0, 1], c='r')\n",
252
+ "for connection in interesting_connections:\n",
253
+ " plt.plot(ip_draw[connection, 0], ip_draw[connection, 1], c='g')\n",
254
+ "for i in range(len(interesting_points)):\n",
255
+ " plt.text(interesting_points[i][0], interesting_points[i][1], str(i), c='b')\n",
256
+ "plt.show()\n",
257
+ "\n"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": null,
263
+ "metadata": {},
264
+ "outputs": [],
265
+ "source": [
266
+ "np.asarray(gest).shape"
267
+ ]
268
+ },
269
+ {
270
+ "cell_type": "code",
271
+ "execution_count": null,
272
+ "metadata": {},
273
+ "outputs": [],
274
+ "source": [
275
+ "all_contours = []\n",
276
+ "keys_segments = [\"eave\", \"ridge\", \"rake\", \"valley\"]\n",
277
+ "all_mask = combine_segs(keys_segments, np.asarray(gest))\n",
278
+ "for key in keys_segments:\n",
279
+ " mask = combine_segs([key], np.asarray(gest))\n",
280
+ " contours, _ = cv2.findContours(\n",
281
+ " mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS\n",
282
+ " )\n",
283
+ " all_contours.extend(contours)\n",
284
+ "# contours = contours[::-1]\n",
285
+ "plt.imshow(all_mask)\n",
286
+ "for contour in all_contours[3:4]:\n",
287
+ " area = cv2.contourArea(contour, oriented=True)\n",
288
+ " if area < 0:\n",
289
+ " contour = contour[::-1]\n",
290
+ "\n",
291
+ " print()\n",
292
+ " # plt.plot(contour[:, 0, 0], contour[:, 0, 1], c='r')\n",
293
+ " # plt.scatter(contour[:, 0, 0], contour[:, 0, 1], c='g', s=3)\n",
294
+ " interesting_points, interesting_connections = get_contour_interesting_wireframe(contour)\n",
295
+ " if len(interesting_points) > 0 and len(interesting_connections) > 0:\n",
296
+ " for connection in interesting_connections:\n",
297
+ " plt.plot(interesting_points[connection, 0], interesting_points[connection, 1], c='b')\n",
298
+ " else:\n",
299
+ " continue\n",
300
+ " # plt.show()\n"
301
+ ]
302
+ },
303
+ {
304
+ "cell_type": "code",
305
+ "execution_count": null,
306
+ "metadata": {},
307
+ "outputs": [],
308
+ "source": [
309
+ "results = []\n",
310
+ "\n",
311
+ "for i, sample in enumerate(dataset[\"train\"]):\n",
312
+ " gt = {\"wf_vertices\": sample[\"wf_vertices\"], \"wf_edges\": sample[\"wf_edges\"]}\n",
313
+ " \n",
314
+ " res = process_sample(sample, handle_error=False)\n",
315
+ " sample = convert_entry_to_human_readable(sample)\n",
316
+ " results.append(res)\n",
317
+ " print(\"LOSS\", hss(res[\"wf_vertices\"], res[\"wf_edges\"], gt[\"wf_vertices\"], gt[\"wf_edges\"]))\n",
318
+ " if i + 1 == 1:\n",
319
+ " break"
320
+ ]
321
+ },
322
+ {
323
+ "cell_type": "code",
324
+ "execution_count": null,
325
+ "metadata": {},
326
+ "outputs": [],
327
+ "source": [
328
+ "results = []\n",
329
+ "for i, sample in enumerate(dataset[\"train\"]):\n",
330
+ " gt = {\"wf_vertices\": sample[\"wf_vertices\"], \"wf_edges\": sample[\"wf_edges\"]}\n",
331
+ " \n",
332
+ " res = process_sample(sample, handle_error=False)\n",
333
+ " sample = convert_entry_to_human_readable(sample)\n",
334
+ " results.append(res)\n",
335
+ " print(\"LOSS\", hss(res[\"wf_vertices\"], res[\"wf_edges\"], gt[\"wf_vertices\"], gt[\"wf_edges\"]))\n",
336
+ " if i + 1 == 1:\n",
337
+ " break"
338
+ ]
339
+ },
340
+ {
341
+ "cell_type": "code",
342
+ "execution_count": null,
343
+ "metadata": {},
344
+ "outputs": [],
345
+ "source": [
346
+ "from hoho2025.viz3d import *\n",
347
+ "def read_colmap_rec(colmap_data):\n",
348
+ " import pycolmap\n",
349
+ " import tempfile,zipfile\n",
350
+ " import io\n",
351
+ " with tempfile.TemporaryDirectory() as tmpdir:\n",
352
+ " with zipfile.ZipFile(io.BytesIO(colmap_data), \"r\") as zf:\n",
353
+ " zf.extractall(tmpdir) # unpacks cameras.txt, images.txt, etc. to tmpdir\n",
354
+ " # Now parse with pycolmap\n",
355
+ " rec = pycolmap.Reconstruction(tmpdir)\n",
356
+ " return rec\n",
357
+ " \n",
358
+ "fig3d = init_figure()\n",
359
+ "plot_reconstruction(fig3d, read_colmap_rec(sample['colmap_binary']))\n",
360
+ "plot_wireframe(fig3d, sample['wf_vertices'], sample['wf_edges'], None, color='red')\n",
361
+ "plot_wireframe(fig3d, res['wf_vertices'], res['wf_edges'], None, color='blue')\n",
362
+ "plot_bpo_cameras_from_entry(fig3d, sample)\n",
363
+ "fig3d"
364
+ ]
365
+ }
366
+ ],
367
+ "metadata": {
368
+ "kernelspec": {
369
+ "display_name": ".venv",
370
+ "language": "python",
371
+ "name": "python3"
372
+ },
373
+ "language_info": {
374
+ "codemirror_mode": {
375
+ "name": "ipython",
376
+ "version": 3
377
+ },
378
+ "file_extension": ".py",
379
+ "mimetype": "text/x-python",
380
+ "name": "python",
381
+ "nbconvert_exporter": "python",
382
+ "pygments_lexer": "ipython3",
383
+ "version": "3.10.17"
384
+ }
385
+ },
386
+ "nbformat": 4,
387
+ "nbformat_minor": 4
388
+ }