Skip to content

Commit

Permalink
Merge pull request #39 from braden6521/sofast_cal_logtools
Browse files Browse the repository at this point in the history
Merging Sofast Calibrations use Logtools into develop
  • Loading branch information
braden6521 authored Mar 21, 2024
2 parents bceb9cc + 4eba646 commit 53d965e
Show file tree
Hide file tree
Showing 25 changed files with 339 additions and 445 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import opencsp.common.lib.photogrammetry.photogrammetry as pg
from opencsp.common.lib.opencsp_path.opencsp_root_path import opencsp_code_dir
import opencsp.common.lib.tool.file_tools as ft
import opencsp.common.lib.tool.log_tools as lt


def annotate_aruco_markers(
Expand Down Expand Up @@ -40,7 +41,7 @@ def annotate_aruco_markers(
if num_ims == 0:
raise ValueError('No files match given pattern')
else:
print(f'{num_ims:d} images found.')
lt.debug(f'{num_ims:d} images containing Aruco markers to be annotated.')

# Check save dir
if not exists(save_dir):
Expand Down Expand Up @@ -81,7 +82,7 @@ def annotate_aruco_markers(

# Save image
save_name = basename(file)
print(save_name)
lt.debug(f'Currently saving annotated Aruco markers to: {save_name:s}')
imageio.imwrite(join(save_dir, save_name), img_rgb)


Expand All @@ -97,6 +98,7 @@ def example_annotate_aruco_markers():
save_dir = join(dirname(__file__), 'data/output/annotated_aruco_markers')

ft.create_directories_if_necessary(save_dir)
lt.logger(join(save_dir, 'log.txt'), lt.log.DEBUG)

# Annotate images
annotate_aruco_markers(source_pattern, save_dir)
Expand Down
42 changes: 19 additions & 23 deletions example/scene_reconstruction/example_scene_reconstruction.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,45 @@
import os
from os.path import join
from os.path import join, dirname

import numpy as np

from opencsp.app.scene_reconstruction.lib.SceneReconstruction import SceneReconstruction
from opencsp.common.lib.camera.Camera import Camera
from opencsp.common.lib.geometry.Vxyz import Vxyz
from opencsp.common.lib.opencsp_path.opencsp_root_path import opencsp_code_dir
import opencsp.common.lib.tool.file_tools as ft
import opencsp.common.lib.tool.log_tools as lt


def example_scene_reconstruction():
def example_scene_reconstruction(save_dir: str):
"""Example script that reconstructs the XYZ locations of Aruco markers in a scene."""
# Define input directory
dir_input = join(
opencsp_code_dir(), 'app/scene_reconstruction/test/data/data_measurement'
)

# Define output directory
save_dir = join(os.path.dirname(__file__), 'data/output')
if not os.path.exists(save_dir):
os.makedirs(save_dir)

VERBOSITY = 2 # 0=no output, 1=only print outputs, 2=print outputs and show plots, 3=plots only with no printing

# Load components
camera = Camera.load_from_hdf(join(dir_input, 'camera.h5'))
known_point_locations = np.loadtxt(
join(dir_input, 'known_point_locations.csv'), delimiter=',', skiprows=1
)
known_point_locations = np.loadtxt(join(dir_input, 'known_point_locations.csv'), delimiter=',', skiprows=1)
image_filter_path = join(dir_input, 'aruco_marker_images', '*.JPG')
point_pair_distances = np.loadtxt(
join(dir_input, 'point_pair_distances.csv'), delimiter=',', skiprows=1
)
alignment_points = np.loadtxt(
join(dir_input, 'alignment_points.csv'), delimiter=',', skiprows=1
)
point_pair_distances = np.loadtxt(join(dir_input, 'point_pair_distances.csv'), delimiter=',', skiprows=1)
alignment_points = np.loadtxt(join(dir_input, 'alignment_points.csv'), delimiter=',', skiprows=1)

# Perform marker position calibration
cal_scene_recon = SceneReconstruction(
camera, known_point_locations, image_filter_path
)
cal_scene_recon.run_calibration(VERBOSITY)
cal_scene_recon.make_figures = True
cal_scene_recon.run_calibration()

# Scale points
point_pairs = point_pair_distances[:, :2].astype(int)
distances = point_pair_distances[:, 2]
cal_scene_recon.scale_points(point_pairs, distances, verbose=VERBOSITY)
cal_scene_recon.scale_points(point_pairs, distances)

# Align points
marker_ids = alignment_points[:, 0].astype(int)
alignment_values = Vxyz(alignment_points[:, 1:4].T)
cal_scene_recon.align_points(marker_ids, alignment_values, verbose=VERBOSITY)
cal_scene_recon.align_points(marker_ids, alignment_values)

# Save points as CSV
cal_scene_recon.save_data_as_csv(join(save_dir, 'point_locations.csv'))
Expand All @@ -61,4 +50,11 @@ def example_scene_reconstruction():


if __name__ == '__main__':
example_scene_reconstruction()
# Define output directory
save_path = join(dirname(__file__), 'data/output/scene_reconstruction')
ft.create_directories_if_necessary(save_path)

# Set up logger
lt.logger(join(save_path, 'log.txt'), lt.log.INFO)

example_scene_reconstruction(save_path)
31 changes: 16 additions & 15 deletions example/sofast_fringe/example_calibration_camera_pose.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,22 @@

import numpy as np

from opencsp.common.lib.deflectometry.CalibrationCameraPosition import (
CalibrationCameraPosition,
)

from opencsp.common.lib.deflectometry.CalibrationCameraPosition import CalibrationCameraPosition
from opencsp.common.lib.camera.Camera import Camera
from opencsp.common.lib.geometry.Vxyz import Vxyz
from opencsp.common.lib.opencsp_path.opencsp_root_path import opencsp_code_dir
from opencsp.common.lib.photogrammetry.photogrammetry import load_image_grayscale
import opencsp.common.lib.tool.file_tools as ft
import opencsp.common.lib.tool.log_tools as lt


def example_run_camera_position_calibration():
def example_run_camera_position_calibration(save_dir: str):
"""Calibrates the position of the Sofast camera. Saves the rvec/tvec that
define the relative pose of the camera/screen to a CSV file located
at ./data/output/camera_rvec_tvec.csv
"""
# Define save dir
save_dir = join(dirname(__file__), 'data/output/camera_pose')
ft.create_directories_if_necessary(save_dir)

# Define directory where screen shape calibration data is saved
base_dir_sofast_cal = join(
opencsp_code_dir(), 'common/lib/deflectometry/test/data/data_measurement'
)
base_dir_sofast_cal = join(opencsp_code_dir(), 'common/lib/deflectometry/test/data/data_measurement')

# Define inputs
file_camera_sofast = join(base_dir_sofast_cal, 'camera_sofast.h5')
Expand All @@ -43,15 +35,24 @@ def example_run_camera_position_calibration():

# Perform camera position calibraiton
cal = CalibrationCameraPosition(camera, pts_xyz_marker, corner_ids, image)
cal.verbose = 2
cal.make_figures = True
cal.run_calibration()

for fig in cal.figures:
fig.savefig(join(save_dir, fig.get_label() + '.png'))
file = join(save_dir, fig.get_label() + '.png')
lt.info(f'Saving figure to: {file:s}')
fig.savefig(file)

# Save data
cal.save_data_as_csv(join(save_dir, 'camera_rvec_tvec.csv'))


if __name__ == '__main__':
example_run_camera_position_calibration()
# Define save dir
save_path = join(dirname(__file__), 'data/output/camera_pose')
ft.create_directories_if_necessary(save_path)

# Set up logger
lt.logger(join(save_path, 'log.txt'))

example_run_camera_position_calibration(save_path)
52 changes: 23 additions & 29 deletions example/sofast_fringe/example_calibration_screen_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@
import numpy as np

from opencsp.app.sofast.lib.MeasurementSofastFringe import MeasurementSofastFringe
from opencsp.app.sofast.lib.CalibrateDisplayShape import (
CalibrateDisplayShape,
DataInput,
)
from opencsp.app.sofast.lib.CalibrateDisplayShape import CalibrateDisplayShape, DataInput
from opencsp.common.lib.camera.Camera import Camera
from opencsp.common.lib.deflectometry.ImageProjection import ImageProjection
from opencsp.common.lib.geometry.Vxyz import Vxyz
from opencsp.common.lib.opencsp_path.opencsp_root_path import opencsp_code_dir
import opencsp.common.lib.tool.file_tools as ft
import opencsp.common.lib.tool.log_tools as lt


def example_run_screen_shape_calibration():
"""Runs screen shape calibration. Saves data to ./data/output/screen_shape"""
# Define save directory
save_dir = join(dirname(__file__), 'data/output/screen_shape')
ft.create_directories_if_necessary(save_dir)

def example_run_screen_shape_calibration(save_dir):
"""Runs screen shape calibration. Saves data to ./data/output/screen_shape
"""
# Load output data from Scene Reconstruction (Aruco marker xyz points)
file_pts_data = join(
opencsp_code_dir(),
Expand All @@ -35,26 +30,18 @@ def example_run_screen_shape_calibration():
resolution_xy = [100, 100]

# Define directory where screen shape calibration data is saved
base_dir_sofast_cal = join(
opencsp_code_dir(), 'app/sofast/test/data/data_measurement'
)
base_dir_sofast_cal = join(opencsp_code_dir(), 'app/sofast/test/data/data_measurement')

# Define input files
file_screen_cal_point_pairs = join(
base_dir_sofast_cal, 'screen_calibration_point_pairs.csv'
)
file_screen_cal_point_pairs = join(base_dir_sofast_cal, 'screen_calibration_point_pairs.csv')
file_camera_distortion = join(base_dir_sofast_cal, 'camera_screen_shape.h5')
file_image_projection = join(base_dir_sofast_cal, 'image_projection.h5')
files_screen_shape_measurement = glob(
join(base_dir_sofast_cal, 'screen_shape_sofast_measurements/pose_*.h5')
)
files_screen_shape_measurement = glob(join(base_dir_sofast_cal, 'screen_shape_sofast_measurements/pose_*.h5'))

# Load input data
camera = Camera.load_from_hdf(file_camera_distortion)
image_projection_data = ImageProjection.load_from_hdf(file_image_projection)
screen_cal_point_pairs = np.loadtxt(
file_screen_cal_point_pairs, delimiter=',', skiprows=1, dtype=int
)
screen_cal_point_pairs = np.loadtxt(file_screen_cal_point_pairs, delimiter=',', skiprows=1, dtype=int)

# Store input data in data class
data_input = DataInput(
Expand All @@ -64,23 +51,30 @@ def example_run_screen_shape_calibration():
pts_xyz_marker,
camera,
image_projection_data,
[
MeasurementSofastFringe.load_from_hdf(f)
for f in files_screen_shape_measurement
],
[MeasurementSofastFringe.load_from_hdf(f) for f in files_screen_shape_measurement],
)

# Perform screen shape calibration
cal = CalibrateDisplayShape(data_input)
cal.run_calibration(2)
cal.make_figures = True
cal.run_calibration()

# Save screen shape data as HDF5 file
cal.save_data_as_hdf(join(save_dir, 'screen_distortion_data.h5'))

# Save calibration figures
for fig in cal.figures:
fig.savefig(join(save_dir, fig.get_label() + '.png'))
file = join(save_dir, fig.get_label() + '.png')
lt.info(f'Saving figure to: {file:s}')
fig.savefig(file)


if __name__ == '__main__':
example_run_screen_shape_calibration()
# Define save directory
save_path = join(dirname(__file__), 'data/output/screen_shape')
ft.create_directories_if_necessary(save_path)

# Set up logger
lt.logger(join(save_path, 'log.txt'), lt.log.INFO)

example_run_screen_shape_calibration(save_path)
41 changes: 17 additions & 24 deletions example/sofast_fringe/example_process_facet_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
from opencsp.app.sofast.lib.DefinitionEnsemble import DefinitionEnsemble
from opencsp.app.sofast.lib.DefinitionFacet import DefinitionFacet
from opencsp.app.sofast.lib.ImageCalibrationScaling import ImageCalibrationScaling
from opencsp.app.sofast.lib.MeasurementSofastFringe import (
MeasurementSofastFringe as Measurement,
)
from opencsp.app.sofast.lib.MeasurementSofastFringe import MeasurementSofastFringe
from opencsp.app.sofast.lib.ProcessSofastFringe import ProcessSofastFringe as Sofast
from opencsp.app.sofast.lib.SpatialOrientation import SpatialOrientation
from opencsp.app.sofast.lib.visualize_setup import visualize_setup
Expand All @@ -20,20 +18,20 @@
import opencsp.common.lib.render_control.RenderControlAxis as rca
import opencsp.common.lib.render_control.RenderControlFigure as rcfg
import opencsp.common.lib.render_control.RenderControlMirror as rcm
import opencsp.common.lib.tool.log_tools as lt
import opencsp.common.lib.tool.file_tools as ft
import opencsp.common.lib.tool.log_tools as lt


def example_driver():
def example_driver(dir_save: str):
"""Example SOFAST script
Performs processing of previously collected Sofast data of multi facet mirror ensemble.
1. Loads saved "multi-facet" SOFAST collection data
2. Processes data with SOFAST (without using facet file)
3. Prints best-fit parabolic focal lengths
3. Logs best-fit parabolic focal lengths
4. Plots slope magnitude, physical setup
"""

# Define sample data directory
sample_data_dir = join(opencsp_code_dir(), 'test/data/measurements_sofast_fringe/')

Expand All @@ -45,17 +43,10 @@ def example_driver():
file_facet = join(sample_data_dir, 'Facet_lab_6x4.json')
file_ensemble = join(sample_data_dir, 'Ensemble_lab_6x4.json')

# Define save dir
dir_save = join(dirname(__file__), 'data/output/facet_ensemble')
ft.create_directories_if_necessary(dir_save)

# Set up logger
lt.logger(join(dir_save, 'log.txt'))

# Load data
camera = Camera.load_from_hdf(file_camera)
display = Display.load_from_hdf(file_display)
measurement = Measurement.load_from_hdf(file_measurement)
measurement = MeasurementSofastFringe.load_from_hdf(file_measurement)
calibration = ImageCalibrationScaling.load_from_hdf(file_calibration)
ensemble_data = DefinitionEnsemble.load_from_json(file_ensemble)

Expand Down Expand Up @@ -91,17 +82,14 @@ def example_driver():
for idx in range(sofast.num_facets):
surf_coefs = sofast.data_characterization_facet[idx].surf_coefs_facet
focal_lengths_xy = [1 / 4 / surf_coefs[2], 1 / 4 / surf_coefs[5]]
lt.info(f'Facet {idx:d} xy focal lengths (meters): '
f'{focal_lengths_xy[0]:.3f}, {focal_lengths_xy[1]:.3f}')
lt.info(f'Facet {idx:d} xy focal lengths (meters): {focal_lengths_xy[0]:.3f}, {focal_lengths_xy[1]:.3f}')

# Get optic representation
ensemble: FacetEnsemble = sofast.get_optic()

# Generate plots
figure_control = rcfg.RenderControlFigure(tile_array=(1, 1), tile_square=True)
mirror_control = rcm.RenderControlMirror(
centroid=True, surface_normals=True, norm_res=1
)
mirror_control = rcm.RenderControlMirror(centroid=True, surface_normals=True, norm_res=1)
axis_control_m = rca.meters()

# Visualize setup
Expand All @@ -117,9 +105,7 @@ def example_driver():
fig_record.save(dir_save, 'physical_setup_layout', 'png')

# Plot scenario
fig_record = fm.setup_figure_for_3d_data(
figure_control, axis_control_m, title='Facet Ensemble'
)
fig_record = fm.setup_figure_for_3d_data(figure_control, axis_control_m, title='Facet Ensemble')
ensemble.draw(fig_record.view, mirror_control)
fig_record.axis.axis('equal')
fig_record.save(dir_save, 'facet_ensemble', 'png')
Expand All @@ -134,4 +120,11 @@ def example_driver():


if __name__ == '__main__':
example_driver()
# Define save dir
save_path = join(dirname(__file__), 'data/output/facet_ensemble')
ft.create_directories_if_necessary(save_path)

# Set up logger
lt.logger(join(save_path, 'log.txt'), lt.log.INFO)

example_driver(save_path)
Loading

0 comments on commit 53d965e

Please sign in to comment.