Skip to content

Commit bfa9e47

Browse files
committed
updated path to testing_folder
1 parent e032909 commit bfa9e47

17 files changed

Lines changed: 865 additions & 1085 deletions
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
import marimo
2+
3+
__generated_with = "0.21.1"
4+
app = marimo.App()
5+
6+
7+
@app.cell
8+
def _():
9+
import marimo as mo
10+
11+
return (mo,)
12+
13+
14+
@app.cell(hide_code=True)
15+
def _(mo):
16+
mo.md(r"""
17+
# Calibrate with particles
18+
""")
19+
return
20+
21+
22+
@app.cell(hide_code=True)
23+
def _(mo):
24+
mo.md(r"""
25+
The idea is to run PyPTV as usual, and check the box "Use only 4 frames". The result will be in the /res folder with only quadruplets as 3D and the respective indices of 2D targets per image
26+
27+
If we read this dataset into the proper format, we can now reproject every 3D point in rt_is back into the image and then optimize calibration with disparity between the position of the target as detected and the reprojected center.
28+
""")
29+
return
30+
31+
32+
@app.cell
33+
def _():
34+
# -*- coding: utf-8 -*-
35+
# copy of https://github.com/alexlib/pbi/blob/master/ptv/shake.py
36+
"""
37+
BOOM shake shake shake the room!!!
38+
39+
Fine-tune calibration using the "shaking" method of comparing 3D positions
40+
obtained with existing calibration to their 2D projections. It's a kind of a
41+
feedback step over the normal calibration with known points.
42+
43+
Created on Sun Jan 31 13:42:18 2016
44+
45+
@author: Yosef Meller
46+
"""
47+
import numpy as np
48+
import os
49+
from pathlib import Path
50+
from pyptv.ptv import py_start_proc_c
51+
from pyptv.parameters import OrientParams
52+
from optv.orientation import full_calibration
53+
from optv.tracking_framebuf import TargetArray, Frame
54+
from pyptv.ptv import full_scipy_calibration
55+
56+
present_folder = Path.cwd()
57+
58+
working_folder = Path("/home/user/Documents/repos/test_cavity")
59+
par_path = working_folder / "parameters"
60+
working_folder.exists(), par_path.exists()
61+
62+
# we work inside the working folder, all the other paths are relative to this
63+
num_cams = 4
64+
os.chdir(working_folder)
65+
cpar, spar, vpar, track_par, tpar, calibs, epar = py_start_proc_c(num_cams)
66+
assert cpar.get_num_cams() == num_cams
67+
68+
targ_files = [
69+
spar.get_img_base_name(c).decode().split("%d")[0].encode() for c in range(num_cams)
70+
]
71+
72+
print(targ_files)
73+
74+
75+
# recognized names for the flags:
76+
NAMES = ["cc", "xh", "yh", "k1", "k2", "k3", "p1", "p2", "scale", "shear"]
77+
op = OrientParams()
78+
op.read()
79+
flags = [name for name in NAMES if getattr(op, name) == 1]
80+
81+
print(flags)
82+
return (
83+
Frame,
84+
TargetArray,
85+
calibs,
86+
cpar,
87+
flags,
88+
full_calibration,
89+
full_scipy_calibration,
90+
np,
91+
num_cams,
92+
spar,
93+
targ_files,
94+
)
95+
96+
97+
@app.cell
98+
def _(cpar):
99+
def backup_ori_files(cpar):
100+
"""backup ORI/ADDPAR files to the backup_cal directory"""
101+
import shutil
102+
103+
for i_cam in range(cpar.get_num_cams()):
104+
f = cpar.get_cal_img_base_name(i_cam).decode()
105+
print(f"Backing up {f}.ori")
106+
shutil.copyfile(f + ".ori", f + ".ori.bck")
107+
shutil.copyfile(f + ".addpar", f + ".addpar.bck")
108+
109+
110+
# Backup is the first thing to do
111+
backup_ori_files(cpar)
112+
return
113+
114+
115+
@app.cell
116+
def _(calibs, num_cams):
117+
print('Starting from: calibration')
118+
for _cam in range(num_cams):
119+
print(f'cam={_cam!r} {calibs[_cam].get_pos()}, {calibs[_cam].get_angles()}')
120+
return
121+
122+
123+
@app.cell
124+
def _(Frame, cpar, np, spar, targ_files):
125+
# Iterate over frames, loading the big lists of 3D positions and
126+
# respective detections.
127+
all_known = []
128+
all_detected = [[] for c in range(cpar.get_num_cams())]
129+
for frm_num in range(spar.get_first(), spar.get_last() + 1):
130+
frame = Frame(cpar.get_num_cams(), corres_file_base='res/rt_is'.encode(), linkage_file_base='res/ptv_is'.encode(), target_file_base=targ_files, frame_num=frm_num)
131+
all_known.append(frame.positions())
132+
for _cam in range(cpar.get_num_cams()): # all frames for now, think of skipping some
133+
all_detected[_cam].append(frame.target_positions_for_camera(_cam))
134+
# Make into the format needed for full_calibration.
135+
all_known = np.vstack(all_known)
136+
return all_detected, all_known
137+
138+
139+
@app.cell
140+
def _(
141+
TargetArray,
142+
all_detected,
143+
all_known,
144+
calibs,
145+
cpar,
146+
full_calibration,
147+
np,
148+
num_cams,
149+
):
150+
# Calibrate each camera accordingly.
151+
for _cam in range(num_cams):
152+
_detects = np.vstack(all_detected[_cam])
153+
assert _detects.shape[0] == all_known.shape[0]
154+
_have_targets = ~np.isnan(_detects[:, 0])
155+
_used_detects = _detects[_have_targets, :]
156+
_used_known = all_known[_have_targets, :]
157+
_targs = TargetArray(len(_used_detects))
158+
for _tix in range(len(_used_detects)):
159+
_targ = _targs[_tix]
160+
_targ.set_pnr(_tix)
161+
_targ.set_pos(_used_detects[_tix])
162+
try:
163+
_residuals, _targ_ix, _err_est = full_calibration(calibs[_cam], _used_known, _targs, cpar, flags=[])
164+
print(f'After full calibration, {np.sum(_residuals ** 2)}')
165+
print('Camera %d' % (_cam + 1))
166+
print(calibs[_cam].get_pos()) # residuals = full_calibration(calibs[cam], used_known, targs, cpar)
167+
print(calibs[_cam].get_angles())
168+
except Exception as e:
169+
print(f'Error in full_calibration: {e}, run Scipy.optimize')
170+
continue # else: # if args.output is None: # ori = cal_args[cam]['ori_file'] # distort = cal_args[cam]['addpar_file'] # else: # ori = args.output % (cam + 1) + '.ori' # distort = args.output % (cam + 1) + '.addpar' # calibs[cam].write(ori.encode(), distort.encode())
171+
return
172+
173+
174+
@app.cell
175+
def _(
176+
TargetArray,
177+
all_detected,
178+
all_known,
179+
calibs,
180+
cpar,
181+
flags,
182+
full_calibration,
183+
np,
184+
num_cams,
185+
):
186+
# Calibrate each camera accordingly.
187+
for _cam in range(num_cams):
188+
_detects = np.vstack(all_detected[_cam])
189+
assert _detects.shape[0] == all_known.shape[0]
190+
_have_targets = ~np.isnan(_detects[:, 0])
191+
_used_detects = _detects[_have_targets, :]
192+
_used_known = all_known[_have_targets, :]
193+
_targs = TargetArray(len(_used_detects))
194+
for _tix in range(len(_used_detects)):
195+
_targ = _targs[_tix]
196+
_targ.set_pnr(_tix)
197+
_targ.set_pos(_used_detects[_tix])
198+
try:
199+
_residuals, _targ_ix, _err_est = full_calibration(calibs[_cam], _used_known, _targs, cpar, flags=flags)
200+
print(f'After full calibration, {np.sum(_residuals ** 2)}')
201+
print('Camera %d' % (_cam + 1))
202+
print(calibs[_cam].get_pos()) # residuals = full_calibration(calibs[cam], used_known, targs, cpar)
203+
print(calibs[_cam].get_angles())
204+
except Exception as e:
205+
print(f'Error in full_calibration: {e}, run Scipy.optimize')
206+
continue
207+
return
208+
209+
210+
@app.cell
211+
def _(
212+
TargetArray,
213+
all_detected,
214+
all_known,
215+
calibs,
216+
cpar,
217+
flags,
218+
full_scipy_calibration,
219+
np,
220+
num_cams,
221+
):
222+
# Calibrate each camera accordingly.
223+
for _cam in range(num_cams):
224+
_detects = np.vstack(all_detected[_cam])
225+
assert _detects.shape[0] == all_known.shape[0]
226+
_have_targets = ~np.isnan(_detects[:, 0])
227+
_used_detects = _detects[_have_targets, :]
228+
_used_known = all_known[_have_targets, :]
229+
_targs = TargetArray(len(_used_detects))
230+
for _tix in range(len(_used_detects)):
231+
_targ = _targs[_tix]
232+
_targ.set_pnr(_tix)
233+
_targ.set_pos(_used_detects[_tix])
234+
_residuals = full_scipy_calibration(calibs[_cam], _used_known, _targs, cpar, flags=flags)
235+
print(f'After scipy full calibration, {np.sum(_residuals ** 2)}')
236+
print('Camera %d' % (_cam + 1))
237+
print(calibs[_cam].get_pos())
238+
# targ_ix = [t.pnr() for t in targs if t.pnr() != -999]
239+
# targ_ix = np.arange(len(all_detected))
240+
# save the results from calibs[cam]
241+
# _write_ori(i_cam, addpar_flag=True)
242+
print(calibs[_cam].get_angles())
243+
return
244+
245+
246+
if __name__ == "__main__":
247+
app.run()

notebooks/manual_selection.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import marimo
2+
3+
__generated_with = "0.21.1"
4+
app = marimo.App()
5+
6+
7+
@app.cell
8+
def _():
9+
import marimo as mo
10+
11+
return (mo,)
12+
13+
14+
@app.cell(hide_code=True)
15+
def _(mo):
16+
mo.md(r"""
17+
# Ipywidgets GUI for the OpenPTV-Python
18+
""")
19+
return
20+
21+
22+
@app.cell
23+
def _():
24+
# Function to handle clicks on the image
25+
import imageio as iio
26+
import matplotlib.pyplot as plt
27+
28+
# '%matplotlib notebook' command supported automatically in marimo
29+
# Import necessary libraries
30+
from io import BytesIO
31+
32+
import matplotlib.widgets as widgets
33+
from IPython.display import display
34+
35+
36+
# Function to load image
37+
def load_image(change):
38+
global img, ax
39+
file_content = change["new"][0]["content"]
40+
img = iio.imread(BytesIO(file_content))
41+
ax.clear()
42+
ax.imshow(img, cmap="gray")
43+
plt.draw()
44+
45+
46+
# Function to handle clicks on the image
47+
def onclick(event):
48+
global clicks
49+
if event.inaxes != ax:
50+
return
51+
if event.button == 1: # Left click to add point
52+
if len(clicks) < 4:
53+
clicks.append((event.xdata, event.ydata))
54+
ax.plot(event.xdata, event.ydata, "ro")
55+
plt.draw()
56+
if len(clicks) == 4:
57+
print("Clicked points:", clicks)
58+
calibration_data = list(zip(particle_numbers, clicks))
59+
print("Calibration data:", calibration_data)
60+
elif event.button == 3: # Right click to remove last point
61+
if clicks:
62+
clicks.pop()
63+
ax.clear()
64+
ax.imshow(img, cmap="gray")
65+
for click in clicks:
66+
ax.plot(click[0], click[1], "ro")
67+
plt.draw()
68+
69+
70+
# File upload widget
71+
file_upload = widgets.FileUpload(accept="image/*", multiple=False) # type: ignore
72+
file_upload.observe(load_image, names="value")
73+
74+
# Integer input widgets
75+
particle_numbers = [
76+
widgets.IntText(value=i, description=f"Particle {i + 1}")
77+
for i in range(4) # type: ignore
78+
]
79+
80+
# Display widgets
81+
display(file_upload)
82+
83+
for widget in particle_numbers:
84+
display(widget)
85+
86+
# Initialize variables
87+
clicks = []
88+
particle_numbers = [widget.value for widget in particle_numbers]
89+
90+
# Connect the click event
91+
fig, ax = plt.subplots()
92+
cid = fig.canvas.mpl_connect("button_press_event", onclick)
93+
plt.show()
94+
return
95+
96+
97+
if __name__ == "__main__":
98+
app.run()

0 commit comments

Comments
 (0)