Loading openflexure_microscope/api/default_extensions/camera_stage_mapping/camera_stage_calibration_2d.py +30 −21 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ from camera_stage_tracker import Tracker, move_until_motion_detected from functools import partial def backlash_corrected_move(get_position, move, backlash_amount, pos): """Make two moves, arriving at `pos` from a consistent direction""" displacement = pos - get_position() Loading @@ -22,10 +23,12 @@ def backlash_corrected_move(get_position, move, backlash_amount, pos): move(pos - backlash_vector) move(pos) def bake_backlash_corrected_move(get_position, move, backlash_amount): """Return a function that performs backlash-corrected moves""" return partial(backlash_corrected_move, get_position, move, backlash_amount) def calibrate_xy_grid(tracker, move, step=100, n_steps=4, backlash_compensation=0): """Make a series of moves in X and Y to determine the XY components of the pixel-to-sample matrix. Loading Loading @@ -63,19 +66,25 @@ def calibrate_xy_grid(tracker, move, step = 100, n_steps=4, backlash_compensatio image_positions -= np.mean(image_positions, axis=0) # image_positions *= -1 # To get the matrix right, we want the position of each # image relative to the template, rather than the other way around A, res, rank, s = np.linalg.lstsq(image_positions, stage_positions) # we solve pixel_shifts*A = location_shifts A, res, rank, s = np.linalg.lstsq( image_positions, stage_positions ) # we solve pixel_shifts*A = location_shifts transformed_image_positions = np.dot(image_positions, A) residuals = transformed_image_positions - stage_positions fractional_error = norm(residuals) / stage_positions.shape[0] step fractional_error = norm(residuals) / stage_positions.shape[0] print(f"Ratio of residuals to displacement is {fractional_error})") if fractional_error > 0.05: # Check it was a reasonably good fit print("Warning: the error fitting measured displacements was %.1f%%" % (fractional_error*100)) print(f"Calibrated the pixel-location matrix.\nResiduals were {fractional_error*100:.1f}% of the shift.") print( "Warning: the error fitting measured displacements was %.1f%%" % (fractional_error * 100) ) print( f"Calibrated the pixel-location matrix.\nResiduals were {fractional_error*100:.1f}% of the shift." ) return { "image_to_stage_displacement": A, "moves": (stage_positions, image_positions), "fractional_error": fractional_error "fractional_error": fractional_error, } Loading
openflexure_microscope/api/default_extensions/camera_stage_mapping/camera_stage_calibration_2d.py +30 −21 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ from camera_stage_tracker import Tracker, move_until_motion_detected from functools import partial def backlash_corrected_move(get_position, move, backlash_amount, pos): """Make two moves, arriving at `pos` from a consistent direction""" displacement = pos - get_position() Loading @@ -22,10 +23,12 @@ def backlash_corrected_move(get_position, move, backlash_amount, pos): move(pos - backlash_vector) move(pos) def bake_backlash_corrected_move(get_position, move, backlash_amount): """Return a function that performs backlash-corrected moves""" return partial(backlash_corrected_move, get_position, move, backlash_amount) def calibrate_xy_grid(tracker, move, step=100, n_steps=4, backlash_compensation=0): """Make a series of moves in X and Y to determine the XY components of the pixel-to-sample matrix. Loading Loading @@ -63,19 +66,25 @@ def calibrate_xy_grid(tracker, move, step = 100, n_steps=4, backlash_compensatio image_positions -= np.mean(image_positions, axis=0) # image_positions *= -1 # To get the matrix right, we want the position of each # image relative to the template, rather than the other way around A, res, rank, s = np.linalg.lstsq(image_positions, stage_positions) # we solve pixel_shifts*A = location_shifts A, res, rank, s = np.linalg.lstsq( image_positions, stage_positions ) # we solve pixel_shifts*A = location_shifts transformed_image_positions = np.dot(image_positions, A) residuals = transformed_image_positions - stage_positions fractional_error = norm(residuals) / stage_positions.shape[0] step fractional_error = norm(residuals) / stage_positions.shape[0] print(f"Ratio of residuals to displacement is {fractional_error})") if fractional_error > 0.05: # Check it was a reasonably good fit print("Warning: the error fitting measured displacements was %.1f%%" % (fractional_error*100)) print(f"Calibrated the pixel-location matrix.\nResiduals were {fractional_error*100:.1f}% of the shift.") print( "Warning: the error fitting measured displacements was %.1f%%" % (fractional_error * 100) ) print( f"Calibrated the pixel-location matrix.\nResiduals were {fractional_error*100:.1f}% of the shift." ) return { "image_to_stage_displacement": A, "moves": (stage_positions, image_positions), "fractional_error": fractional_error "fractional_error": fractional_error, }