def test_on_static_muti_tag(): """ connect track and close with multi tag, reqs: 03, 04 ,05, 07 """ config = { 'video source': 'data/12markers.avi', 'aruco dictionary': 'DICT_6X6_250' } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 12 for tagid in range(1, 13): tag_name = str('DICT_6X6_250:' + str(tagid)) assert tag_name in port_handles regression_array6 = np.array([[1., 0., 0., 262.5], [0., 1., 0., 241.5], [0., 0., 1., -151.32085], [0., 0., 0., 1.]]) assert np.allclose(tracking[port_handles.index('DICT_6X6_250:6')], regression_array6) tracker.stop_tracking() tracker.close()
def test_on_video_with_debug(): """ connect track and close with single tag, with debug flag on debug should open a separate window showing the image capture reqs: 03, 04 ,05 """ config = {'video source': 'data/output.avi', 'debug': True} tracker = ArUcoTracker(config) tracker.start_tracking() for frame in range(2): (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 1 assert port_handles[0] == 'DICT_4X4_50:0' assert framenumbers[0] == frame assert quality[0] == 1.0 tracker.stop_tracking() tracker.close()
def test_no_video_single_tag(): """ raises a value error when no video and no image passed. works on static images reqs: 03, 04 ,05 """ config = {'video source': 'none'} tracker = ArUcoTracker(config) assert not tracker.has_capture() tracker.start_tracking() with pytest.raises(ValueError): tracker.get_frame() capture = VideoCapture('data/output.avi') for frame in range(2): _, image = capture.read() (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame(image) assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 1 assert port_handles[0] == 'DICT_4X4_50:0' assert framenumbers[0] == frame assert quality[0] == 1.0 tracker.stop_tracking() tracker.close()
def test_on_video_with_calib(): """ connect track and close with single tag, and calibrated camera reqs: 03, 04 ,05 """ config1 = { 'video source': 'data/output.avi', 'calibration': 'data/calibration.txt', 'marker size': 50, } tracker = ArUcoTracker(config1) tracker.start_tracking() for frame in range(10): (port_handles, _timestamps, _framenumbers, tracking, _quality) = tracker.get_frame() if frame == 1: regression_array = np.array( [[0.99928828, -0.02261964, 0.03018762, 1.7609988e+01], [-0.02280416, -0.99972323, 0.00578211, 2.5085676e+01], [0.03004847, -0.00646639, -0.99952753, 2.1036779e+02], [0., 0., 0., 1.]]) assert np.allclose(tracking[port_handles.index('DICT_4X4_50:0')], regression_array) tracker.stop_tracking() tracker.close()
def test_with_tool_desc_and_calib(): """ connect track and close with multitags, defined rigid bodies, and camera calibration reqs: 03, 04 ,05, 07 """ config = { 'video source': 'data/multipattern.avi', 'calibration': 'data/calibration.txt', 'rigid bodies': [{ 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'tag width': 49.50 }, { 'name': 'pointer', 'filename': 'data/pointer.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }] } tracker = ArUcoTracker(config) tracker.start_tracking() assert tracker.has_capture() (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 4 #there is an extraneous marker (1000) assert 'reference' in port_handles assert 'pointer' in port_handles assert 'DICT_4X4_50:0' in port_handles reference_index = port_handles.index('reference') pointer_index = port_handles.index('pointer') assert np.isclose(quality[reference_index], 0.91666666) assert np.isclose(quality[pointer_index], 0.83333333) ref_regression = np.array( [[-0.84701057, 0.51884094, -0.11565978, -8.22903442e+01], [-0.48733129, -0.67100208, 0.55880625, 4.85032501e+01], [0.21232361, 0.52967943, 0.82119327, 2.43992401e+02], [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]], dtype=np.float32) assert np.allclose(tracking[reference_index], ref_regression) tracker.stop_tracking() tracker.close()
def test_getframe_no_tracking(): """ Tests that value error is thrown when get frame called without tracking. reqs: """ config = {'video source': 'data/output.avi'} tracker = ArUcoTracker(config) with pytest.raises(ValueError): (_port_handles, _timestamps, _framenumbers, _tracking, _quality) = tracker.get_frame() tracker.close()
def test_stop_tracking_throws(): """ Tests that value error is thrown when stop tracking called when not tracking. reqs: """ config = {'video source': 'data/12markers.avi'} tracker = ArUcoTracker(config) with pytest.raises(ValueError): tracker.stop_tracking() tracker.close()
def test_get_tool_descriptions(): """ Tests that get too descriptions. If no tool descriptions have been set it should return "No tools defined", otherwise it should return a list of tool names reqs: """ config = {'video source': 'data/output.avi'} tracker = ArUcoTracker(config) assert tracker.get_tool_descriptions() == "No tools defined" tracker.close()
def test_with_no_tags_and_calib(): """ connect track and close with multitags, defined rigid bodies, but no tags visible, should return an NaN matrix for each undetected body reqs: 03, 04 ,05, 07 """ config = { 'calibration': 'data/calibration.txt', 'video source': 'none', 'rigid bodies': [{ 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_4X4_50' }, { 'name': 'pointer', 'filename': 'data/pointer.txt', 'aruco dictionary': 'DICT_4X4_50' }] } tracker = ArUcoTracker(config) tracker.start_tracking() image = np.zeros((640, 480, 3), dtype=np.uint8) (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame(image) assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 2 assert 'reference' in port_handles assert 'pointer' in port_handles reference_index = port_handles.index('reference') pointer_index = port_handles.index('pointer') assert quality[reference_index] == 0 assert quality[pointer_index] == 0 assert np.all(np.isnan(tracking[reference_index][0:3, 0:4])) assert np.all(np.isnan(tracking[pointer_index][0:3, 0:4])) tracker.stop_tracking() tracker.close()
def test_no_video_no_tag(): """ no errors when no tags detected works on static images reqs: 03, 04 ,05 """ config = {'video source': 'none'} tracker = ArUcoTracker(config) tracker.start_tracking() image = np.zeros((640, 480, 3), dtype=np.uint8) (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame(image) assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 0 tracker.stop_tracking() tracker.close()
def test_setting_capture_properties(): """ connect track and close with multi tag, reqs: 03, 04 ,05, 07 """ config = { 'video source': 'data/12markers.avi', 'aruco dictionary': 'DICT_6X6_250', "capture properties": { "CAP_PROP_FRAME_WIDTH": 1280, "CAP_PROP_FRAME_HEIGHT": 1024 } } tracker = ArUcoTracker(config) tracker.start_tracking() (_port_handles, _timestamps, _framenumbers, _tracking, _quality) = tracker.get_frame() tracker.stop_tracking() tracker.close()
def test_on_video_with_single_tag(): """ connect track and close with single tag, reqs: 03, 04 ,05 """ config = {'video source': 'data/output.avi'} tracker = ArUcoTracker(config) tracker.start_tracking() for frame in range(10): (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 1 assert port_handles[0] == 'DICT_4X4_50:0' assert framenumbers[0] == frame assert quality[0] == 1.0 tracker.stop_tracking() tracker.close()
def test_vs_solve_pnp_singletag(): """ This checks whether the tracking result using skarucotracker matches that when using the solvePnP approach as originally implemented by scikit-surgeryBARAD, with the addition of tracking smoothing """ calib_mtx = np.array([[608.67179504, 0.00000000, 323.12263928], [0.00000000, 606.13421375, 231.29247171], [0.0, 0.0, 1.0]], dtype = np.float64) distortion = np.array([-0.02191634, -0.14300148, -0.00395124, -0.00044941, 0.19656551], dtype = np.float64) videofile = 'data/output.avi' config = {'video source' : 'none', 'camera projection' : calib_mtx, 'camera distortion' : distortion, 'aruco dictionary' : 'DICT_ARUCO_ORIGINAL', 'smoothing buffer' : 5, 'rigid bodies' : [ { 'name' : 'reference', 'filename' : 'data/tag_0.txt', 'aruco dictionary' : 'DICT_4X4_50' } ] } config2 = {'video source' : 'none', 'camera projection' : calib_mtx, 'camera distortion' : distortion, 'aruco dictionary' : 'DICT_4X4_50', 'marker size' : 33, 'smoothing buffer' : 5, } capture = cv.VideoCapture(videofile) #set up skarucotracker tracker = ArUcoTracker(config) tracker.start_tracking() tracker2 = ArUcoTracker(config2) tracker2.start_tracking() #set up solvepnp three_d_points = np.loadtxt('data/tag_0.txt') three_d_points = three_d_points.reshape(1, 16) three_d_points = ccw_to_cw(three_d_points) reference_register = Registration2D3D(three_d_points, calib_mtx, distortion, buffer_size=5) for _frame in range(10): _, image = capture.read() (port_handles, _timestamps, _framenumbers, tracking, _quality) = tracker.get_frame(image) assert 'reference' in port_handles reference_index = port_handles.index('reference') aruco_reference_tracking = tracking[reference_index] (port_handles, _timestamps, _framenumbers, tracking, _quality) = tracker2.get_frame(image) assert 'DICT_4X4_50:0' in port_handles reference_index = port_handles.index('DICT_4X4_50:0') aruco_reference_tracking2= tracking[reference_index] #now try again using our own implementation using cv.solvepnp as #formerly implemented in BARD marker_corners, ids, _ = aruco.detectMarkers(image, aruco.getPredefinedDictionary( aruco.DICT_4X4_50)) success, modelreference2camera = \ reference_register.get_matrix( ids, marker_corners) assert success assert np.allclose(modelreference2camera, aruco_reference_tracking) assert np.allclose(aruco_reference_tracking2, aruco_reference_tracking) tracker.stop_tracking() tracker.close() capture.release()
def test_arucotracker_vs_solve_pnp(): """ This checks whether the tracking result using skarucotracker matches that when using the solvePnP approach as originally implemented by scikit-surgeryBARD """ calib_mtx = np.array([[608.67179504, 0.00000000, 323.12263928], [0.00000000, 606.13421375, 231.29247171], [0.0, 0.0, 1.0]], dtype = np.float64) distortion = np.array([-0.02191634, -0.14300148, -0.00395124, -0.00044941, 0.19656551], dtype = np.float64) videofile = 'data/multipattern.avi' config = {'video source' : 'none', 'camera projection' : calib_mtx, 'camera distortion' : distortion, 'aruco dictionary' : 'DICT_ARUCO_ORIGINAL', 'rigid bodies' : [ { 'name' : 'reference', 'filename' : 'data/reference.txt', 'aruco dictionary' : 'DICT_ARUCO_ORIGINAL' } ] } tracker = ArUcoTracker(config) tracker.start_tracking() capture = cv.VideoCapture(videofile) _, image = capture.read() (port_handles, _timestamps, _framenumbers, tracking, quality) = tracker.get_frame(image) assert 'reference' in port_handles reference_index = port_handles.index('reference') assert np.isclose(quality[reference_index], 0.91666666) ref_regression = np.array([ [-0.85007277, 0.51807849, -0.09471516, -8.06235428e+01], [-0.46167221, -0.64647658, 0.60739345, 5.07177658e+01], [ 0.25344635, 0.56005599, 0.78873458, 2.50268387e+02], [ 0.0000e+00, 0.00000e+00, 0.00000e+00, 1.00000000e+00]], dtype=np.float32) aruco_reference_tracking = tracking[reference_index] assert np.allclose(aruco_reference_tracking, ref_regression) tracker.stop_tracking() tracker.close() #now try again using our own implementation using cv.solvepnp as #formerly implemented in BARD three_d_points = np.loadtxt('data/reference.txt') reference_register = Registration2D3D(three_d_points, calib_mtx, distortion, buffer_size=1) marker_corners, ids, _ = aruco.detectMarkers(image, aruco.getPredefinedDictionary( aruco.DICT_ARUCO_ORIGINAL)) success, modelreference2camera = \ reference_register.get_matrix( ids, marker_corners) assert success assert np.allclose(modelreference2camera, ref_regression) capture.release()
def test_with_tool_descriptions(): """ connect track and close with multitags and defined rigid bodies, reqs: 03, 04 ,05, 07 """ #test first with no tool descriptions config = {'video source': 'data/multipattern.avi'} tracker = ArUcoTracker(config) tracker.start_tracking() #with nothing set we'll only detect tag ID 0, the others #are from a different dictionary. (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 1 assert 'DICT_4X4_50:0' in port_handles tracker.stop_tracking() tracker.close() #try again with the right dictionary for the bard marker tags config = { 'video source': 'data/multipattern.avi', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' } tracker = ArUcoTracker(config) tracker.start_tracking() #with nothing set we'll only detect tag ID 0, the others #are from a different dictionary. (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 17 assert 'DICT_ARUCO_ORIGINAL:1' in port_handles #we should load the tag info and check that all tags are found tracker.stop_tracking() tracker.close() config = { 'video source': 'data/multipattern.avi', 'rigid bodies': [{ 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, { 'name': 'pointer', 'filename': 'data/pointer.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 4 #there is an extraneous marker (1000) assert 'reference' in port_handles assert 'pointer' in port_handles assert 'DICT_4X4_50:0' in port_handles reference_index = port_handles.index('reference') ref_regression = np.array([[1., 0., 0., 135.38637], [0., 1., 0., 272.5], [0., 0., 1., -57.1915], [0., 0., 0., 1.]], dtype=np.float32) assert np.allclose(tracking[reference_index], ref_regression) assert np.isclose(quality[reference_index], 0.91666666) pointer_index = port_handles.index('pointer') assert np.isclose(quality[pointer_index], 0.83333333) tracker.stop_tracking() tracker.close() #check that tag 0 is not detected when we use only #DICT_ARUCO_ORIGINAL config = { 'video source': 'data/multipattern.avi', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'rigid bodies': [{ 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, { 'name': 'pointer', 'filename': 'data/pointer.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, timestamps, framenumbers, tracking, quality) = tracker.get_frame() assert len(port_handles) == len(timestamps) assert len(port_handles) == len(framenumbers) assert len(port_handles) == len(tracking) assert len(port_handles) == len(quality) assert len(port_handles) == 3 #there is an extraneous marker (1000) assert 'reference' in port_handles assert 'pointer' in port_handles assert 'DICT_4X4_50:0' not in port_handles
def test_tool_desc_and_float64(): """ connect track and close with multitags, defined rigid bodies, and camera calibration, defined with different data types, issue #31 reqs: 03, 04 ,05, 07 """ config = { 'video source': 'data/multipattern.avi', 'calibration': 'data/calibration.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'rigid bodies': [ { 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, ] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, _timestamps, _framenumbers, tracking, quality) = tracker.get_frame() assert 'reference' in port_handles reference_index = port_handles.index('reference') assert np.isclose(quality[reference_index], 0.91666666) ref_regression = np.array( [[-0.84701057, 0.51884094, -0.11565978, -8.22903442e+01], [-0.48733129, -0.67100208, 0.55880625, 4.85032501e+01], [0.21232361, 0.52967943, 0.82119327, 2.43992401e+02], [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]], dtype=np.float32) assert np.allclose(tracking[reference_index], ref_regression) tracker.stop_tracking() tracker.close() port_handles = None tracking = None quality = None #again, but this time set calibration and distortion separately calib_mtx = np.array( [[560.0, 0.0, 320.0], [0.0, 560.0, 240.0], [0.0, 0.0, 1.0]], dtype=np.float32) distortion = np.array([0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float32) config = { 'video source': 'data/multipattern.avi', 'camera projection': calib_mtx, 'camera distortion': distortion, 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'rigid bodies': [ { 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, ] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, _timestamps, _framenumbers, tracking, quality) = tracker.get_frame() assert 'reference' in port_handles reference_index = port_handles.index('reference') assert np.isclose(quality[reference_index], 0.91666666) assert np.allclose(tracking[reference_index], ref_regression) tracker.stop_tracking() tracker.close() port_handles = None tracking = None quality = None #again, but this time set calibration and distortion as float64 calib_mtx = np.array( [[560.0, 0.0, 320.0], [0.0, 560.0, 240.0], [0.0, 0.0, 1.0]], dtype=np.float64) distortion = np.array([0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float64) config = { 'video source': 'data/multipattern.avi', 'camera projection': calib_mtx, 'camera distortion': distortion, 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'rigid bodies': [ { 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, ] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, _timestamps, _framenumbers, tracking, quality) = tracker.get_frame() assert 'reference' in port_handles reference_index = port_handles.index('reference') assert np.isclose(quality[reference_index], 0.91666666) assert np.allclose(tracking[reference_index], ref_regression) tracker.stop_tracking() tracker.close() port_handles = None tracking = None quality = None #again, but this time set calibration and distortion as float calib_mtx = np.array( [[560.0, 0.0, 320.0], [0.0, 560.0, 240.0], [0.0, 0.0, 1.0]], dtype=float) distortion = np.array([0.1, 0.0, 0.0, 0.0, 0.0], dtype=float) config = { 'video source': 'data/multipattern.avi', 'camera projection': calib_mtx, 'camera distortion': distortion, 'aruco dictionary': 'DICT_ARUCO_ORIGINAL', 'rigid bodies': [ { 'name': 'reference', 'filename': 'data/reference.txt', 'aruco dictionary': 'DICT_ARUCO_ORIGINAL' }, ] } tracker = ArUcoTracker(config) tracker.start_tracking() (port_handles, _timestamps, _framenumbers, tracking, quality) = tracker.get_frame() assert 'reference' in port_handles reference_index = port_handles.index('reference') assert np.isclose(quality[reference_index], 0.91666666) assert np.allclose(tracking[reference_index], ref_regression) tracker.stop_tracking() tracker.close()