Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full res example #149

Merged
merged 5 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ubi8-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ jobs:
with:
path: OpenCSP

- name: pytest-cov
- name: pytest-cov (OpenCSP/example)
working-directory: OpenCSP/example
run: |
python3 -m pip install -r ../requirements.txt
export PYTHONPATH=$PWD/../
pytest --color=yes -rs -vv --cov=. --cov-report term --cov-config=.coveragerc

- name: Pip Upgrade pytest-cov
- name: Pip Upgrade pytest-cov (OpenCSP/example)
working-directory: OpenCSP/example
run: |
python3 -m pip install -U -r ../requirements.txt
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/ubi8-weekly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: github-UBI8-WEEKLY

# Runs every Sunday at midnight
on:
workflow_dispatch:
schedule:
- cron: '00 00 * * 0'

permissions:
contents: none

# Cancels any in progress 'workflow' associated with this PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
ubi8-weekly:
runs-on: [opencsp-latest-ubi8]
permissions:
packages: read
contents: read

steps:
- name: checkout
uses: actions/checkout@v4
with:
path: OpenCSP

- name: pytest-cov (OpenCSP/example - scene_reconstruction)
working-directory: OpenCSP/example
run: |
python3 -m pip install -r ../requirements.txt
export PYTHONPATH=$PWD/../
pytest \
--color=yes \
-rs \
-vv \
--cov=. --cov-report term \
--cov-config=.coveragerc \
--dir-input=/box_data/scene_reconstruction/data_measurement/ \
e10harvey marked this conversation as resolved.
Show resolved Hide resolved
--dir-output=/box_data/scene_reconstruction/data_calculation/ \
scene_reconstruction/example_scene_reconstruction.py
2 changes: 1 addition & 1 deletion .github/workflows/ubi8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
with:
path: OpenCSP

- name: pytest-cov
- name: pytest-cov (OpenCSP/opencsp)
working-directory: OpenCSP/opencsp
run: |
python3 -m pip install -r ../requirements.txt
Expand Down
19 changes: 19 additions & 0 deletions example/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import pytest


#
# Ensure pytest adds root directory to the system path.
#
def pytest_addoption(parser):
parser.addoption('--dir-input', action='store', default='', help='Base directory with data input')
parser.addoption('--dir-output', action='store', default='', help='Base directory where output will be written')


@pytest.fixture
def dir_input_fixture(request):
return request.config.getoption('--dir-input')


@pytest.fixture
def dir_output_fixture(request):
return request.config.getoption('--dir-output')
59 changes: 48 additions & 11 deletions example/scene_reconstruction/example_scene_reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,40 @@
import opencsp.common.lib.tool.log_tools as lt


def scene_reconstruction(save_dir):
"""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')
def scene_reconstruction(dir_output, dir_input):
"""
Reconstructs the XYZ locations of Aruco markers in a scene.

Parameters
----------
dir_output : str
The directory where the output files, including point locations and calibration figures, will be saved.
dir_input : str
The directory containing the input files needed for scene reconstruction. This includes:
- 'camera.h5': HDF5 file containing camera parameters.
- 'known_point_locations.csv': CSV file with known point locations.
- 'aruco_marker_images/NAME.JPG': Directory containing images of Aruco markers.
- 'point_pair_distances.csv': CSV file with distances between point pairs.
- 'alignment_points.csv': CSV file with alignment points.

Notes
-----
This function performs the following steps:
1. Loads the camera parameters from an HDF5 file.
2. Loads known point locations, point pair distances, and alignment points from CSV files.
3. Initializes the SceneReconstruction object with the camera parameters and known point locations.
4. Runs the calibration process to determine the marker positions.
5. Scales the points based on the provided point pair distances.
6. Aligns the points using the provided alignment points.
7. Saves the reconstructed point locations to a CSV file.
8. Saves calibration figures as PNG files in the output directory.

Examples
--------
>>> scene_reconstruction('/path/to/output', '/path/to/input')

"""
# "ChatGPT 4o" assisted with generating this docstring.

# Load components
camera = Camera.load_from_hdf(join(dir_input, 'camera.h5'))
Expand All @@ -38,22 +68,29 @@ def scene_reconstruction(save_dir):
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'))
cal_scene_recon.save_data_as_csv(join(dir_output, 'point_locations.csv'))

# Save calibrtion figures
for fig in cal_scene_recon.figures:
fig.savefig(join(save_dir, fig.get_label() + '.png'))
fig.savefig(join(dir_output, fig.get_label() + '.png'))


def example_driver(dir_output_fixture, dir_input_fixture):

dir_input = join(opencsp_code_dir(), 'app/scene_reconstruction/test/data/data_measurement')
dir_output = join(dirname(__file__), 'data/output/scene_reconstruction')
if dir_input_fixture:
dir_input = dir_input_fixture
if dir_output_fixture:
dir_output = dir_input_fixture

def example_driver():
# Define output directory
save_path = join(dirname(__file__), 'data/output/scene_reconstruction')
ft.create_directories_if_necessary(save_path)
ft.create_directories_if_necessary(dir_input)

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

scene_reconstruction(save_path)
scene_reconstruction(dir_output, dir_input)


if __name__ == '__main__':
Expand Down
59 changes: 59 additions & 0 deletions opencsp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

import configparser
import os
import copy
import sys
import argparse


def _opencsp_settings_dirs() -> list[str]:
Expand Down Expand Up @@ -50,6 +53,57 @@ def _opencsp_settings_dirs() -> list[str]:
return ret


def apply_command_line_arguments(settings_from_ini: configparser.ConfigParser) -> configparser.ConfigParser:
settings_mixed = copy.copy(settings_from_ini)

# parse the command line
parser = argparse.ArgumentParser(
prog="OpenCSP/__init__.py", description='OpenCSP settings parser', add_help=False, exit_on_error=False
)
parser.add_argument(
'--dir-input',
dest="dir_input",
default="",
type=str,
help="Use the given directory value as the input directory instead of [opencsp_root_path]/[large_data_example_dir].",
)
parser.add_argument(
'--dir-output',
dest="dir_output",
default="",
type=str,
help="Use the given directory value as the output directory instead of [opencsp_root_path]/[scratch_dir]/[scratch_name].",
)
args, remaining = parser.parse_known_args(sys.argv[1:])
dir_input: str = args.dir_input
dir_output: str = args.dir_output
sys.argv = [sys.argv[0]] + remaining
overridden_values: list[tuple[str, str]] = []

# apply the command line arguments to the settings
if dir_input != "":
settings_mixed["opencsp_root_path"]["large_data_example_dir"] = dir_input
overridden_values.append(("opencsp_root_path/large_data_example_dir", dir_input))
if dir_output != "":
dir_output_path, dir_output_name = os.path.dirname(dir_output), os.path.basename(dir_output)
try:
os.makedirs(dir_output)
except FileExistsError:
pass
settings_mixed["opencsp_root_path"]["scratch_dir"] = dir_output_path
settings_mixed["opencsp_root_path"]["scratch_name"] = dir_output_name
overridden_values.append(("opencsp_root_path/scratch_dir", dir_output_path))
overridden_values.append(("opencsp_root_path/scratch_name", dir_output_name))

# let the user know if values have been overridden
if len(overridden_values) > 0:
print("Some settings have been overridden from the command line:")
for setting_name, command_line_value in overridden_values:
print(f"\t{setting_name}: {command_line_value}")

return settings_mixed


_settings_files: list[str] = []

# default settings file
Expand All @@ -66,4 +120,9 @@ def _opencsp_settings_dirs() -> list[str]:
opencsp_settings = configparser.ConfigParser(allow_no_value=True)
opencsp_settings.read(_settings_files)

for section in opencsp_settings.sections():
for key in opencsp_settings[section]:
print(f"opencsp_settings[{section}][{key}]={opencsp_settings[section][key]}")

opencsp_settings = apply_command_line_arguments(opencsp_settings)
__all__ = ['opencsp_settings']