asi_core.calibration.self_calibration ===================================== .. py:module:: asi_core.calibration.self_calibration .. autoapi-nested-parse:: Tools for the geometric self calibration of all-sky imagers The internal camera model assumed by the calibration is described by: Scaramuzza, D., et al. (2006). A Toolbox for Easily Calibrating Omnidirectional Cameras. RSJ International Conference on Intelligent Robots and Systems Beijing, China. The external camera orientation is defined according to: Luhmann, T. (2000). Nahbereichsphotogrammetrie: Grundlagen, Methoden und Anwendungen. Heidelberg, Germany, Wichmann Verlag. The self-calibration functionality itself was introduced and described by Niklas Blum, Paul Matteschk, Yann Fabel, Bijan Nouri, Roberto Roman, Luis F. Zarzalejo, Juan Carlos Antuna-Sanchez, Stefan Wilbert "Geometric Calibration of All-Sky Cameras Using Sun and Moon Positions: A Comprehensive Analysis", Solar Energy (in review). When using this self-calibration in any publication or other work, make sure to reference the latter publication. Attributes ---------- .. autoapisummary:: asi_core.calibration.self_calibration.q25_ss_means asi_core.calibration.self_calibration.q25_ss_std Classes ------- .. autoapisummary:: asi_core.calibration.self_calibration.Calibration asi_core.calibration.self_calibration.CenterDetector Functions --------- .. autoapisummary:: asi_core.calibration.self_calibration.plot_orb_positions asi_core.calibration.self_calibration.get_background_img_and_plot asi_core.calibration.self_calibration.find_center_via_cam_model Module Contents --------------- .. py:data:: q25_ss_means .. py:data:: q25_ss_std :value: (5.4, 2.89e-05, 3.066e-08) statistics taken from Rafal Broda's evaluation of PyranoCam Q25 cameras start values and search range should be tested if a new camera type needs to be calibrated. For the same camera type, calibration parameters do not vary a lot. The second polynomial coefficient (a_1 of a_0 + a_1*x + a_2*x^2 + a_3*x^3) is assumed to be zero which holds for hyperbolic and parabolic mirrors or fisheye cameras according to Scaramuzza (2006). .. py:class:: Calibration(processed_timestamps, ss_expected={'mean': q25_ss_means, 'std': q25_ss_std}, eor_expected={'mean': (0, np.pi, np.pi / 2), 'min': (-np.pi / 4, np.pi * 3 / 4, -2 * np.pi), 'max': (np.pi / 4, np.pi * 5 / 4, 4 * np.pi - 1e-05)}, ignore_outliers_above_percentile=99, min_rel_dist_mask_orb=1.5, save_orb_quality_indicators=True) Provides the ASI self-calibration functionality. The functionality is: - Detecting celestial bodies i.e. orbs - Transforming spherical coordinates of orbs into pixel coordinates - Calculating residuals between expected and found orb positions in ASI image - Optimizing external and internal calibration - Looping over timestamps - Visualizing results :param processed_timestamps: One (datetime, timezone-aware) or preferably all processed timestamps as pd.Series or similar (subclass of pandas.core.base.IndexOpsMixin) :param ss_expected: Specifies the mean values and the ranges within which coefficients of ss are optimized. :param eor_expected: Specifies the mean values and the ranges within which Euler angles are optimized. :param ignore_outliers_above_percentile: Percentile of the deviation used in the calibration. Observations with deviations beyond this will be sorted out. :param min_rel_dist_mask_orb: Threshold for minimum required distance between orb center and mask relative to orb diameter :param save_orb_quality_indicators: If True, save geometric parameters with each orb observation which indicate the observation's quality .. py:attribute:: camera .. py:attribute:: ocam .. py:attribute:: orb_observations .. py:attribute:: ss_expected .. py:attribute:: eor_expected .. py:attribute:: ignore_outliers_above_percentile :value: 99 .. py:attribute:: min_rel_dist_mask_orb :value: 1.5 .. py:attribute:: save_orb_quality_indicators :value: True .. py:attribute:: bounds_eor .. py:attribute:: bounds_eor_ior .. py:attribute:: bounds_eor_ior_center .. py:attribute:: x_center_expected .. py:attribute:: y_center_expected .. py:method:: optimize_eor(orb_observations, orientation_init) Calls optimizer to minimize calc_residual_eor setting only the EOR's angles as free parameters :param orb_observations: dataframe of detected orbs with identified pixel coordinates and spherical coordinates from astronomy :param orientation_init: Initial guess of the Euler angles determining the ASI's external orientation :return: Results of the optimization see scio.minimize .. py:method:: optimize_eor_ior(orb_observations, orientation_init=None, ocam_init=None, test_various_azimuths=True) Calls optimizer to minimize calc_residual_eor_ior setting the EOR's angles and the coefficients of ss of the internal calibration as free parameters. :param orb_observations: dataframe of detected orbs with identified pixel coordinates and spherical coordinates from astronomy :param orientation_init: Initial guess of the Euler angles determining the ASI's external orientation :param ocam_init: Initial guess of camera's internal calibration in particular of the coefficients of ss :param test_various_azimuths: If True, loop over azimuth angles which represent 360° rotation of ASI around vertical axis :return: Results of the optimization see scio.minimize .. py:method:: optimize_eor_ior_center(orb_observations, orientation_init=None, ocam_init=None) WARNING THIS FUNCTION WAS NOT TESTED PROPERLY YET. DON'T USE IT. Calls optimizer to minimize calc_residual_eor_ior setting the EOR's angles and the coefficients of ss of the internal calibration and image center as free parameters. :param orb_observations: dataframe of detected orbs with identified pixel coordinates and spherical coordinates from astronomy :param orientation_init: Initial guess of the Euler angles determining the ASI's external orientation :param ocam_init: Initial guess of camera's internal calibration in particular of the coefficients of ss :return: Results of the optimization see scio.minimize .. py:method:: calc_residual_eor_ior_center(orientation_ior_center) Calculates deviation metric of the difference between expected and found coordinates of celestial bodies. :param orientation_ior_center: Array of the three Euler angles and coefficients no. 0, 2, 3 of ss and x_center, y_center :return: Deviation used as target for the optimization .. py:method:: calc_residual_eor_ior(orientation_ior) Calculates deviation metric of the difference between expected and found coordinates of celestial bodies. :param orientation_ior: Array of the three Euler angles and coefficients no. 0, 2, 3 of ss :return: Deviation used as target for the optimization .. py:method:: calc_residual_eor(orientation) Calculates deviation metric of the difference between expected and found coordinates of celestial bodies. :param orientation: Array of the three Euler angles :return: Deviation used as target for the optimization .. py:method:: angles_to_pixels(orb_observations, ocam, eor) :staticmethod: Transforms angle coordinates of a celestial body seen by a camera into pixel coordinates on the chip :param orb_observations: dataframe with columns azimuth and elevation indicating the positions of one or more celestial bodies observed at one or more timestamps :param ocam: Ocam object describing the ASI's camera model and internal calibration :param eor: (array) External orientation of the ASI indicated by the 3 Euler angles :return: Pixel coordinates of the celestial body in the camera image .. py:method:: angles_pixels_to_vector_deviation(orb_observations, ocam, eor, ignore_outliers_above_percentile=None, compute_found_angles=False) :staticmethod: Calculates root mean squared deviation between detected and expected orb coordinates in cartesian coordinates. Transforms angle coordinates of a celestial body seen by a camera and pixel coordinates of detected body to cartesian coordinates, calculates area spun up by both vectors and calculates root mean square of all areas (i.e. deviations). :param orb_observations: dataframe with columns azimuth and elevation indicating the positions of one or more celestial bodies observed at one or more timestamps :param ocam: Ocam object describing the ASI's camera model and internal calibration :param eor: (array) External orientation of the ASI indicated by the 3 Euler angles :param ignore_outliers_above_percentile: If number between 0 and 100 is provided observations with deviation above corresponding percentile are excluded from calculation of deviation/ optimization :param compute_found_angles: If True, return azimuth and elevation angles of found orb positions :return: Root mean square deviation from all orb observations .. py:method:: get_deviation(orb_observations, ignore_outliers_above_percentile=99) :staticmethod: Calculates deviation metric between found and astronomically expected orb positions. :param orb_observations: Dataframe with expected 'expected_x, *_y' and found orb positions 'found_x, *_y' as columns :param ignore_outliers_above_percentile: (in percent) If not None and between 0 and 100, datapoints with a deviation above this percentile (e.g. above 99%) are ignored. :return: Deviation metric .. py:method:: find_orb_positions(detector) Detects orb positions for multiple timestamps. :param detector: CelestialBodyDetector instance :return: dataframe of orb observations with columns timestamp, found pixel position of the orb and expected elevation and azimuth angle of the orb in degree. .. py:method:: get_all_orb_positions(orb_detectors, output_file=f'orb_observations.csv', reset_temp=True) Loads or detects orb positions of multiple types, especially sun and moon. :param orb_detectors: list of CelestialBodyDetector instances :param output_file: path to save dataframe of orb observations to :param reset_temp: reprocess orb positions and do not load previously saved dataframes :return: dataframe of orb observations with columns timestamp, found pixel position of the orb and expected elevation and azimuth angle of the orb in degree. .. py:method:: compute_and_save_azimuth_elevation(ocam_model, min_ele_evaluated, external_orientation, save_npy=False) Computes the azimuth and elevation matrices, and optionally saves them as .npy files. :param ocam_model: Updated ocam model. :param min_ele_evaluated: Updated minimum elevation evaluated. :param external_orientation: Updated external orientation. :param save_npy: Boolean flag to save the matrices as .npy files. .. py:function:: plot_orb_positions(orb_observations_path, background_image_path, output_path_figure='found_and_expected_orb_positions_after_calibration.png', exp_area_diameter=None, center_x=None, center_y=None, outliers_above_percentile_ignored_in_calib=99) Creates and saves a plot which compares expected and found orb pixel positions. :param orb_observations_path: Path to load dataframe of expected and found orb positions from :param background_image_path: Path to background image laid under plot :param output_path_figure: Path to save the figure to :param exp_area_diameter: Diameter of the exposed area in the fisheye image :param center_x: x-coordinate of the center of the ASI image :param center_y: y-coordinate of the center of the ASI image :param outliers_above_percentile_ignored_in_calib: Percentile of outliers to be filtered to recalculate deviation metric received in calibration .. py:function:: get_background_img_and_plot(camera, orb_obs_file, exp_time, image_file_name, outliers_above_percentile_ignored_in_calib) Find background image and plot all found and expected orb positions over this image. :param camera: AllSkyImager instance :param orb_obs_file: csv file containing dataframe of found and expected orb positions :param exp_time: [microseconds], exposure time of the background image :param image_file_name: Identifier to be used as first part of the saved figure's name :param outliers_above_percentile_ignored_in_calib: Percentile of outliers to be filtered to recalculate deviation metric received in calibration .. py:class:: CenterDetector Provides functionality to detect and visualize the center of the exposed area of an ASI image. .. py:attribute:: max_intensity :value: 255 .. py:attribute:: max_threshold_value :value: 250 .. py:attribute:: gaussian_blur_kernel :value: (5, 5) .. py:method:: find_best_threshold(img, min_contour_area_ratio=0.1) Finds the boundary of a fisheye image's exposed area by maximizing the circularity of the detected contours. :param img: Image based on which center is detected. :param min_contour_area_ratio: (float) Minimum contour area ratio to consider for circle detection. :return: tuple of the best threshold value (int), and a list of pixel coordinates indicating the best contour found. .. py:method:: find_fisheye_circle_center(img, min_contour_area_ratio=0.1, save_visualization=True) Finds the center and radius of a fisheye image's exposed area. :param img: image used to detect center :param min_contour_area_ratio: (float) Minimum contour area ratio to consider for circle detection. :param save_visualization: If true, a visualization of the found image center is created and saved. :return: Center coordinates of the fisheye circle (tuple), exposed radius and diameter. .. py:method:: visualize_center(img, best_contour, center_x, center_y, output_image_path='fisheye_rim.jpg') Visualizes the position of the fisheye objective's center in the image. :param img: Background image :param best_contour: Contour indicating the most reasonable boundary of the fisheye's exposed area :param center_x: x-coordinate of the ASI image's center :param center_y: y-coordinate of the ASI image's center :param output_image_path: Path to save the figure to .. py:method:: find_center_timerange(camera, start, end, sampling_time=timedelta(hours=2), exp_time=160) Loops over range of timestamps, detecting the average image center in all respective images :param camera: Camera object to load images with :param start: First timestamp processed :param end: Last timestamp processed :param sampling_time: Time difference between evaluated images :param exp_time: Required exposure time of considered images :return: Mean values of the image center's x and y coordinates and radius of the exposed area .. py:function:: find_center_via_cam_model(calibrator, orb_data, x_samples=6, y_samples=None, max_rel_center_dev=0.25, number_iterations=11, slow_but_roubst=False) Determines all parameters of the camera model iteratively refining the lens center image coordinates Reuses the optimization algorithm of the lens center of Scaramuzza 2006 however calling our calibration procedure :param calibrator: calibrator instance :param orb_data: Dataframe of image- and astronomy-based orb positions :param x_samples: Number of sample points in each iterations mesh grid of test points in x-direction :param y_samples: Number of sample points in each iterations mesh grid of test points in x-direction :param max_rel_center_dev: Maximum expected deviation of the lens center's image coordinates from the image center as fraction of the image side height and width :param number_iterations: Number of refinement iterations for center detection :param slow_but_roubst: If True, don't use options to speed up process. Make sure that process converges. :return: calibrator instance with refined lens center position (x_center, y_center)