Skip to content

Commit

Permalink
Merge branch '22-stereo-calib-returns-left-right-points'
Browse files Browse the repository at this point in the history
  • Loading branch information
MattClarkson committed Jul 27, 2020
2 parents cacaa16 + 0217486 commit 63405ae
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 67 deletions.
29 changes: 17 additions & 12 deletions sksurgerycalibration/video/video_calibration_driver_stereo.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,32 @@ def grab_data(self,
but will return empty arrays if no points were detected.
So, no points is not an error. Its an expected condition.
:param left_image: RGB image.
:param right_image: RGB image.
:param left_image: BGR image.
:param right_image: BGR image.
:param device_tracking: transformation for the tracked device
:param calibration_object_tracking: transformation of tracked
calibration object
:return: The number of points grabbed.
"""
number_of_points = 0
number_left = 0
number_right = 0

# This can return None's if none are found.
left_ids, left_object_points, left_image_points = \
self.point_detector.get_points(left_image)

if left_ids is not None and \
left_ids.shape[0] >= self.minimum_points_per_frame:
if left_ids is not None:
number_left = left_ids.shape[0]

if number_left >= self.minimum_points_per_frame:

right_ids, right_object_points, right_image_points = \
self.point_detector.get_points(right_image)

if right_ids is not None and \
right_ids.shape[0] >= self.minimum_points_per_frame:
if right_ids is not None:
number_right = right_ids.shape[0]

if number_right >= self.minimum_points_per_frame:

left_ids, left_image_points, left_object_points = \
cu.convert_pd_to_opencv(left_ids,
Expand All @@ -97,14 +102,14 @@ def grab_data(self,
self.tracking_data.push(device_tracking,
calibration_object_tracking)

number_of_points = \
left_image_points.shape[0] + \
right_image_points.shape[0]
number_of_points = number_left + number_right

LOGGER.info("Grabbed: Returning %s points.",
LOGGER.info("Grabbed: Returning (%s+%s)=%s points.",
str(number_left),
str(number_right),
str(number_of_points))

return number_of_points
return number_left, number_right

def calibrate(self,
flags=cv2.CALIB_USE_INTRINSIC_GUESS,
Expand Down
Binary file removed tests/data/2020_01_20_storz/.DS_Store
Binary file not shown.
10 changes: 5 additions & 5 deletions tests/video/test_charuco_plus_chessboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def test_stereo_davinci():
files.sort()
for file in files:
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
print("Loaded:" + str(file))
left_images.append(image)
assert(len(left_images) == 59)
Expand All @@ -28,7 +27,6 @@ def test_stereo_davinci():
files.sort()
for file in files:
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
print("Loaded:" + str(file))
right_images.append(image)
assert (len(right_images) == 59)
Expand All @@ -38,9 +36,11 @@ def test_stereo_davinci():
calibrator = sc.StereoVideoCalibrationDriver(detector, minimum_number_of_points_per_image)
for i, _ in enumerate(left_images):
try:
number_of_points = calibrator.grab_data(left_images[i], right_images[i])
if number_of_points < 2 * minimum_number_of_points_per_image:
print("Image pair:" + str(i) + ", SKIPPED, due to not enough points")
number_left, number_right = calibrator.grab_data(left_images[i], right_images[i])
if number_left < minimum_number_of_points_per_image:
print("Image pair:" + str(i) + ", left image, SKIPPED, due to not enough points")
if number_right < minimum_number_of_points_per_image:
print("Image pair:" + str(i) + ", right image, SKIPPED, due to not enough points")
except ValueError as ve:
print("Image pair:" + str(i) + ", FAILED, due to:" + str(ve))
except TypeError as te:
Expand Down
32 changes: 9 additions & 23 deletions tests/video/test_chessboard_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import sksurgerycalibration.video.video_calibration_driver_mono as mc
import sksurgerycalibration.video.video_calibration_driver_stereo as sc
import sksurgerycalibration.video.video_calibration_utils as vu
import tests.video.video_testing_utils as vtu


def get_iterative_reference_data():
Expand Down Expand Up @@ -37,7 +38,6 @@ def test_chessboard_mono():
files = glob.glob('tests/data/laparoscope_calibration/left/*.png')
for file in files:
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
images.append(image)

# This illustrates that the PointDetector sub-class holds the knowledge of the model.
Expand Down Expand Up @@ -118,23 +118,8 @@ def test_chessboard_mono():

def test_chessboard_stereo():

left_images = []
files = glob.glob('tests/data/laparoscope_calibration/left/*.png')
files.sort()
for file in files:
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
left_images.append(image)
assert(len(left_images) == 9)

right_images = []
files = glob.glob('tests/data/laparoscope_calibration/right/*.png')
files.sort()
for file in files:
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
right_images.append(image)
assert (len(right_images) == 9)
left_images, right_images \
= vtu.load_left_right_pngs('tests/data/laparoscope_calibration/', 9)

chessboard_detector = \
pd.ChessboardPointDetector((14, 10),
Expand All @@ -147,8 +132,9 @@ def test_chessboard_stereo():

# Repeatedly grab data, until you have enough.
for i, _ in enumerate(left_images):
successful = calibrator.grab_data(left_images[i], right_images[i])
assert successful > 0
number_left, number_right = calibrator.grab_data(left_images[i], right_images[i])
assert number_left > 0
assert number_right > 0
assert not calibrator.is_device_tracked()
assert not calibrator.is_calibration_target_tracked()

Expand All @@ -157,7 +143,7 @@ def test_chessboard_stereo():

# Just for a regression test, checking reprojection error, and recon error.
assert reproj_err < 0.7
assert recon_err < 1.7
assert recon_err < 1.8
print("Stereo, default=" + str(reproj_err) + ", " + str(recon_err))

# Now test rerunning where we optimize the extrinsics with other params fixed.
Expand All @@ -172,7 +158,7 @@ def test_chessboard_stereo():
)

assert reproj_err < 0.7
assert recon_err < 1.7
assert recon_err < 1.8
print("Stereo, extrinsics=" + str(reproj_err) + ", " + str(recon_err))

# Test iterative calibration.
Expand All @@ -183,5 +169,5 @@ def test_chessboard_stereo():
reference_points,
reference_image_size)
assert reproj_err < 0.7
assert recon_err < 1.5
assert recon_err < 1.6
print("Stereo, iterative=" + str(reproj_err) + ", " + str(recon_err))
23 changes: 6 additions & 17 deletions tests/video/test_data_param_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sksurgeryimage.calibration.chessboard_point_detector as pd
import sksurgerycalibration.video.video_calibration_driver_mono as mc
import sksurgerycalibration.video.video_calibration_driver_stereo as sc
import tests.video.video_testing_utils as vtu


def test_chessboard_mono_io():
Expand Down Expand Up @@ -49,21 +50,8 @@ def test_chessboard_mono_io():

def test_chessboard_stereo_io():

left_images = []
files = glob.glob('tests/data/laparoscope_calibration/left/*.png')
files.sort()
for file in files:
image = cv2.imread(file)
left_images.append(image)
assert(len(left_images) == 9)

right_images = []
files = glob.glob('tests/data/laparoscope_calibration/right/*.png')
files.sort()
for file in files:
image = cv2.imread(file)
right_images.append(image)
assert (len(right_images) == 9)
left_images, right_images \
= vtu.load_left_right_pngs('tests/data/laparoscope_calibration/', 9)

chessboard_detector = \
pd.ChessboardPointDetector((14, 10),
Expand All @@ -75,8 +63,9 @@ def test_chessboard_stereo_io():
sc.StereoVideoCalibrationDriver(chessboard_detector, 140)

for i, _ in enumerate(left_images):
successful = calibrator.grab_data(left_images[i], right_images[i], np.eye(4), np.eye(3))
assert successful > 0
num_left, num_right = calibrator.grab_data(left_images[i], right_images[i], np.eye(4), np.eye(3))
assert num_left > 0
assert num_right > 0

# Then do calibration
reproj_err_1, recon_err_1, params_1 = calibrator.calibrate()
Expand Down
27 changes: 17 additions & 10 deletions tests/video/test_hand_eye.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def load_images_from_glob(glob_pattern):

return images


def load_tracking_from_glob(glob_pattern):
""" Load tracking data from files based on a glob pattern. """
tracking = []
Expand All @@ -53,7 +54,8 @@ def load_tracking_from_glob(glob_pattern):


def test_handeye_calibration_mono():
""" Load mono data (only using left channel) and tracking, do video and
"""
Load mono data (only using left channel) and tracking, do video and
handeye calibration, compare results against expected values.
"""
images = load_images_from_glob(
Expand Down Expand Up @@ -96,15 +98,16 @@ def test_handeye_calibration_mono():

# These values are taken from a previous successful run
# Not objective measures of correctness
expected_reproj_error = 14.93867
expected_recon_error = 5.530625
expected_reproj_error = 14.97731
expected_recon_error = 5.434362

assert proj_err == pytest.approx(expected_reproj_error, rel=1e-4)
assert recon_err == pytest.approx(expected_recon_error, rel=1e-4)


def test_handeye_calibration_stereo():
""" Load Stereo data and tracking, do video and
"""
Load Stereo data and tracking, do video and
handeye calibration, compare results against expected values.
"""
left_images = load_images_from_glob(
Expand All @@ -126,7 +129,8 @@ def test_handeye_calibration_stereo():

min_number_of_points_per_image = 50
detector = \
chpd.CharucoPlusChessboardPointDetector(error_if_no_chessboard=False)
chpd.CharucoPlusChessboardPointDetector(charuco_filtering=True,
error_if_no_chessboard=False)

calibrator = \
vidcal.video_calibration_driver_stereo.StereoVideoCalibrationDriver(
Expand All @@ -135,8 +139,12 @@ def test_handeye_calibration_stereo():
# Grab data from images/tracking arrays
for left, right, device, calib_obj in \
zip(left_images, right_images, device_tracking, obj_tracking):
successful = calibrator.grab_data(left, right, device, calib_obj)
assert successful > 0
num_left, num_right = calibrator.grab_data(left,
right,
device,
calib_obj)
assert num_left > 0
assert num_right > 0

reproj_err_1, recon_err_1, _ = calibrator.calibrate()

Expand All @@ -151,8 +159,8 @@ def test_handeye_calibration_stereo():

# These values are taken from a previous successful run
# Not objective measures of correctness
expected_reproj_error = 13.452010
expected_recon_error = 1.394778
expected_reproj_error = 13.543016
expected_recon_error = 1.383223

assert proj_err == pytest.approx(expected_reproj_error, rel=1e-4)
assert recon_err == pytest.approx(expected_recon_error, rel=1e-4)
Expand All @@ -175,4 +183,3 @@ def test_load_data_stereo_calib():
assert len(stereo_calib.tracking_data.calibration_tracking_array) == 10
assert len(stereo_calib.video_data.left_data.images_array) == 10
assert len(stereo_calib.video_data.right_data.images_array) == 10

28 changes: 28 additions & 0 deletions tests/video/video_testing_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-

""" Various utilities to help testing. """

import os
import glob
import cv2


def load_left_right_pngs(dir_name, expected_number):
"""Given a dir_name, loads left/*.png and right/*.png"""
left_images = []
files = glob.glob(os.path.join(dir_name, "left", "*.png"))
files.sort()
for file in files:
image = cv2.imread(file)
left_images.append(image)
assert len(left_images) == expected_number

right_images = []
files = glob.glob(os.path.join(dir_name, "right", "*.png"))
files.sort()
for file in files:
image = cv2.imread(file)
right_images.append(image)
assert len(right_images) == expected_number

return left_images, right_images

0 comments on commit 63405ae

Please sign in to comment.