Skip to content

Commit

Permalink
Probe detection is done on two screens, a pair that gives the lowest …
Browse files Browse the repository at this point in the history
…reprojection error
  • Loading branch information
hannalee2 committed May 3, 2024
1 parent c71fddb commit 7e5b98d
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 78 deletions.
66 changes: 36 additions & 30 deletions parallax/calibration_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,34 +259,18 @@ def __init__(
self.retval, self.R_AB, self.T_AB, self.E_AB, self.F_AB = None, None, None, None, None
self.P_A, self.P_B = None, None

def calibrate_stereo(self):
"""Calibrate stereo cameras.
Returns:
tuple: Stereo calibration results (retval, R_AB, T_AB, E_AB, F_AB).
"""
self.retval, _, _, _, _, self.R_AB, self.T_AB, self.E_AB, self.F_AB = (
cv2.stereoCalibrate(
self.objpoints,
self.imgpointsA,
self.imgpointsB,
self.mtxA,
self.distA,
self.mtxB,
self.distB,
SIZE,
criteria=self.criteria,
flags=self.flags,
)
)

def print_calibrate_stereo_results(self):
if self.retval is None or self.R_AB is None or self.T_AB is None:
return
print("\n== Stereo Calibration ==")
print("AB")
print(self.retval)
print(f"R: \n{self.R_AB}")
print(f"T: \n{self.T_AB}")
print(np.linalg.norm(self.T_AB))

if self.F_AB is None or self.E_AB is None:
return
formatted_F = (
"F_AB:\n"
+ "\n".join(
Expand All @@ -300,6 +284,26 @@ def calibrate_stereo(self):
print(formatted_F)
print(formatted_E)

def calibrate_stereo(self):
"""Calibrate stereo cameras.
Returns:
tuple: Stereo calibration results (retval, R_AB, T_AB, E_AB, F_AB).
"""
self.retval, _, _, _, _, self.R_AB, self.T_AB, self.E_AB, self.F_AB = (
cv2.stereoCalibrate(
self.objpoints,
self.imgpointsA,
self.imgpointsB,
self.mtxA,
self.distA,
self.mtxB,
self.distB,
SIZE,
criteria=self.criteria,
flags=self.flags,
)
)
self.P_A = self.mtxA @ np.hstack((np.eye(3), np.zeros((3, 1))))
self.P_B = self.mtxB @ np.hstack((self.R_AB, self.T_AB.reshape(-1, 1)))

Expand Down Expand Up @@ -457,7 +461,7 @@ def test_x_y_z_performance(self, points_3d_G):
f"x: {l2_x*1000}µm³, y: {l2_y*1000}µm³, z:{l2_z*1000}µm³"
)

def test_performance(self, camA, coordA, camB, coordB):
def test_performance(self, camA, coordA, camB, coordB, print_results=False):
"""Test stereo calibration.
Args:
Expand All @@ -482,19 +486,21 @@ def test_performance(self, camA, coordA, camB, coordB):
points_3d_G = self.change_coords_system_from_camA_to_global_iterative(
points_3d_AB
)
print("\n=solvePnP SOLVEPNP_ITERATIVE=")

differences = points_3d_G - self.objpoints[0]
squared_distances = np.sum(np.square(differences), axis=1)
euclidean_distances = np.sqrt(squared_distances)
average_L2_distance = np.mean(euclidean_distances)
print(
f"(Reprojection error) Object points L2 diff: \
{average_L2_distance*1000} µm³"
)
self.test_x_y_z_performance(points_3d_G)
print(f"Object points predict:\n{np.around(points_3d_G, decimals=5)}")
if print_results:
print("\n=solvePnP SOLVEPNP_ITERATIVE=")
print(
f"(Reprojection error) Object points L2 diff: \
{average_L2_distance*1000} µm³"
)
self.test_x_y_z_performance(points_3d_G)
print(f"Object points predict:\n{np.around(points_3d_G, decimals=5)}")

self.test_pixel_error()
self.test_pixel_error()
return average_L2_distance

def test_pixel_error(self):
Expand Down
6 changes: 6 additions & 0 deletions parallax/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ def add_probe_detector(self, probeDetector):
"""Add a probe detector."""
self.probeDetectors.append(probeDetector)

def reset_coords_intrinsic_extrinsic(self):
"""Reset coordinates intrinsic extrinsic."""
self.coords_axis = {}
self.camera_intrinsic = {}
self.camera_extrinsic = {}

def add_coords_axis(self, camera_name, coords):
"""Add coordinates axis."""
self.coords_axis[camera_name] = coords
Expand Down
2 changes: 2 additions & 0 deletions parallax/screen_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ def found_reticle_coords(self, x_coords, y_coords, mtx, dist):
def reset_reticle_coords(self):
"""Reset reticle coordinates."""
self.reticle_coords = None
self.mtx = None
self.dist = None

def found_probe_coords(self, timestamp, probe_sn, stage_info, tip_coords):
"""Store the found probe coordinates and related information."""
Expand Down
Loading

0 comments on commit 7e5b98d

Please sign in to comment.