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

Tidy up packaging #33

Merged
merged 18 commits into from
Jun 30, 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
13 changes: 0 additions & 13 deletions .flake8

This file was deleted.

47 changes: 0 additions & 47 deletions .github/workflows/check.yml

This file was deleted.

76 changes: 76 additions & 0 deletions .github/workflows/test_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Lint & build

on:
push:
workflow_dispatch:

jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
py_version: ["3.8", "3.9", "3.10", "3.11"]
include:
- os: windows-latest
py_version: "3.8"
- os: windows-latest
py_version: "3.11"
- os: macos-latest
py_version: "3.8"
- os: macos-latest
py_version: "3.11"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.py_version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[dev,cli]
python -m pip install 'opencv-python-headless>=4.8,<4.9'
- name: Lint
run: |
poe lint
- name: Typecheck
run: |
poe type
- name: Run tests
run: |
poe test
build:
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v5
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip build poethepoet
# Install package to generate version info
python -m pip install --no-deps .
- name: Build package
run: |
poe build
- name: Save built package
uses: actions/upload-artifact@v4
with:
name: package
path: |
dist
- name: Publish to PyPi
if: ${{ github.ref_type == 'tag' }}
uses: pypa/gh-action-pypi-publish@release/v1
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ venv.bak/
# mypy
.mypy_cache/

# ruff
.ruff_cache/

# PyCharm stuff
.idea
core
Expand Down
30 changes: 0 additions & 30 deletions Makefile

This file was deleted.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# april_vision

[![Lint & build](https://github.com/WillB97/april_vision/actions/workflows/test_build.yml/badge.svg)](https://github.com/WillB97/april_vision/actions/workflows/test_build.yml)
[![PyPI version](https://badge.fury.io/py/april-vision.svg)](https://badge.fury.io/py/april-vision)
[![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://opensource.org/licenses/MIT)

A fiducial marker system used by Student Robotics.
Uses [april tag](https://april.eecs.umich.edu/software/apriltag) markers to provide detection, pose and distance estimation for these markers.

Expand Down
12 changes: 9 additions & 3 deletions april_vision/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""An AprilTags wrapper with camera discovery and axis conversion."""
# ruff: noqa: E402
import os

os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0"
Expand All @@ -8,13 +9,17 @@
from .detect_cameras import CalibratedCamera, find_cameras
from .frame_sources import FrameSource, USBCamera
from .helpers import generate_marker_size_mapping
from .marker import (CartesianCoordinates, Marker, Orientation,
PixelCoordinates, SphericalCoordinate)
from .marker import (
CartesianCoordinates,
Marker,
Orientation,
PixelCoordinates,
SphericalCoordinate,
)
from .utils import Frame
from .vision import Processor

__all__ = [
'__version__',
'CalibratedCamera',
'CartesianCoordinates',
'Frame',
Expand All @@ -25,6 +30,7 @@
'Processor',
'SphericalCoordinate',
'USBCamera',
'__version__',
'calibrations',
'find_cameras',
'generate_marker_size_mapping',
Expand Down
22 changes: 15 additions & 7 deletions april_vision/cli/calibrate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Camera calibration script.
"""
"""Camera calibration script."""
import argparse
import logging
from datetime import datetime
Expand All @@ -19,7 +17,8 @@


class CalBoard:
"""Class used to represent a calibration board"""
"""Class used to represent a calibration board."""

def __init__(
self,
rows: int,
Expand All @@ -38,10 +37,11 @@ def __init__(
def corners_from_id(self, marker_id: int) -> List[Tuple[float, float, float]]:
"""
Takes an input of a marker ID and returns the coordinates of the corners of the marker.
The coordinates are 3D real world positions, top left of the board is 0,0,0.
The Z coordinate of the board is always zero.
The list of co-ords are in the order:
[bottom_left, bottom_right, top_right, top_left]
bottom_left, bottom_right, top_right, top_left
"""
marker_pixel_size = self.marker_size / self.marker_details.width_at_border

Expand All @@ -68,7 +68,7 @@ def frame_capture(
LOGGER.info("Press space to capture frame.")

while True:
ret, frame = cap.read()
_ret, frame = cap.read()

cv2.imshow("Frame", frame)

Expand All @@ -90,6 +90,7 @@ def parse_detections(
) -> Tuple[List[Tuple[float, float, float]], List[Tuple[float, float]]]:
"""
Pairs up 2D pixel corners with 3D real world co-ords.
Takes the input of marker detections and the board design and outputs two lists
where board_obj_points[i] pairs with board_img_points[i].
"""
Expand All @@ -108,6 +109,7 @@ def parse_detections(


def main(args: argparse.Namespace) -> None:
"""Main function for calibrate command."""
# Setup the camera
video_dev = cv2.VideoCapture(args.index)

Expand Down Expand Up @@ -152,7 +154,7 @@ def main(args: argparse.Namespace) -> None:
width, height = frames[0].grey_frame.shape[::-1]

# Calculate the camera calibration
reproj_error, camera_matrix, dist_coeff, rvec, tvec = cv2.calibrateCamera(
reproj_error, camera_matrix, dist_coeff, _rvec, _tvec = cv2.calibrateCamera(
objectPoints,
imagePoints,
(width, height),
Expand Down Expand Up @@ -188,6 +190,12 @@ def write_cal_file(
avg_reprojection_error: float,
vidpid: Optional[str] = None,
) -> None:
"""
Write the calibration data to an XML file.
This file can be loaded by the detect_cameras module.
The file is also compatible with the OpenCV calibration module.
"""
LOGGER.info("Generating calibration XML file")
output_filename = cal_filename
if not output_filename.lower().endswith(".xml"):
Expand Down
1 change: 1 addition & 0 deletions april_vision/cli/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@


def parse_properties(args: argparse.Namespace) -> List[Tuple[int, int]]:
"""Parse the camera properties supplied on the command line."""
props = []

if args.set_fps is not None:
Expand Down
2 changes: 1 addition & 1 deletion april_vision/cli/marker_generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
def create_subparser(subparsers: argparse._SubParsersAction) -> None:
"""
Marker_generator command parser.
Add multiple subparsers to deal with different modes of page generation.
"""

parser = subparsers.add_parser(
"marker_generator",
description="Generate markers",
Expand Down
3 changes: 2 additions & 1 deletion april_vision/cli/marker_generator/marker_modes/mode_cal.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Marker_generator subparser CAL_BOARD used to generate a calibration board."""
import argparse
import logging

Expand All @@ -14,7 +15,7 @@


def main(args: argparse.Namespace) -> None:
"""Generate a calibration board"""
"""Generate a calibration board."""
tag_data = get_tag_family(args.marker_family)
LOGGER.info(tag_data)

Expand Down
3 changes: 2 additions & 1 deletion april_vision/cli/marker_generator/marker_modes/mode_image.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Marker_generator subparser IMAGE used to generate an image of a marker."""
import argparse
import logging

Expand All @@ -14,7 +15,7 @@


def main(args: argparse.Namespace) -> None:
"""Generate a marker image"""
"""Generate a marker image."""
tag_data = get_tag_family(args.marker_family)
LOGGER.info(tag_data)

Expand Down
16 changes: 12 additions & 4 deletions april_vision/cli/marker_generator/marker_modes/mode_single.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Marker_generator subparser SINGLE used to generate a PDF of a marker."""
import argparse
import logging
from typing import Union
Expand All @@ -8,15 +9,22 @@
from april_vision.marker import MarkerType

from ..marker_tile import MarkerTile
from ..utils import (DEFAULT_COLOUR, DEFAULT_FONT, DEFAULT_FONT_SIZE, DPI,
CustomPageSize, PageSize, mm_to_pixels,
parse_marker_ranges)
from ..utils import (
DEFAULT_COLOUR,
DEFAULT_FONT,
DEFAULT_FONT_SIZE,
DPI,
CustomPageSize,
PageSize,
mm_to_pixels,
parse_marker_ranges,
)

LOGGER = logging.getLogger(__name__)


def main(args: argparse.Namespace) -> None:
"""Generate a single marker on a page with the provided arguments"""
"""Generate a single marker on a page with the provided arguments."""
tag_data = get_tag_family(args.marker_family)
LOGGER.info(tag_data)

Expand Down
Loading