Skip to content

Commit

Permalink
Add Python3 wrapper thanks to Dima Kogan (AprilRobotics#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrogius authored Jul 2, 2019
1 parent 43ca2c4 commit d13014b
Show file tree
Hide file tree
Showing 5 changed files with 575 additions and 4 deletions.
42 changes: 38 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ find_package(OpenCV QUIET)

include_directories(.)
aux_source_directory(common COMMON_SRC)
aux_source_directory(. APRILTAG_SRCS)
set(APRILTAG_SRCS apriltag.c apriltag_pose.c apriltag_quad_thresh.c)

set(CMAKE_BUILD_TYPE Release)

# Library
add_library(${PROJECT_NAME} SHARED ${APRILTAG_SRCS} ${COMMON_SRC})
file(GLOB TAG_FILES ${CMAKE_SOURCE_DIR}/tag*.c)
set_source_files_properties(SOURCE ${TAG_FILES} PROPERTIES COMPILE_FLAGS -O0)
add_library(${PROJECT_NAME} SHARED ${APRILTAG_SRCS} ${COMMON_SRC} ${TAG_FILES})
if (MSVC)
# FindThreads will not find pthread.h with MSVC
# winmm is necessary for __imp_timeGetTime
Expand All @@ -34,8 +36,6 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}
)

file(GLOB TAG_FILES ${CMAKE_SOURCE_DIR}/tag*.c)
set_source_files_properties(SOURCE ${TAG_FILES} PROPERTIES COMPILE_FLAGS -O0)

# install library
install(TARGETS ${PROJECT_NAME} EXPORT apriltag
Expand All @@ -61,6 +61,40 @@ STRING(REGEX REPLACE "^prefix=" "prefix=${CMAKE_INSTALL_PREFIX}" PKGC_CONF "${PK
FILE(WRITE ${PROJECT_BINARY_DIR}/apriltag.pc ${PKGC_CONF})
install(FILES "${PROJECT_BINARY_DIR}/apriltag.pc" DESTINATION "lib/pkgconfig/")


# Python wrapper
execute_process(COMMAND which python3 OUTPUT_QUIET RESULT_VARIABLE Python3_NOT_FOUND)
if (NOT Python3_NOT_FOUND)
# TODO deal with both python2/3
execute_process(COMMAND python3 ${CMAKE_SOURCE_DIR}/python_build_flags.py OUTPUT_VARIABLE PY_OUT)
set(PY_VARS CFLAGS LDFLAGS LINKER EXT_SUFFIX)
cmake_parse_arguments(PY "" "${PY_VARS}" "" ${PY_OUT})
separate_arguments(PY_CFLAGS)
separate_arguments(PY_LDFLAGS)
set(LIB_APRILTAG_PATH ${PROJECT_BINARY_DIR}/lib)

foreach(X detect py_type)
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/apriltag_${X}.docstring.h
COMMAND < ${CMAKE_SOURCE_DIR}/apriltag_${X}.docstring sed 's/\"/\\\\\"/g\; s/^/\"/\; s/$$/\\\\n\"/\;' > apriltag_${X}.docstring.h
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endforeach()

add_custom_command(OUTPUT apriltag_pywrap.o
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} ${PY_CFLAGS} -I${PROJECT_BINARY_DIR} -c -o apriltag_pywrap.o ${CMAKE_SOURCE_DIR}/apriltag_pywrap.c
DEPENDS ${CMAKE_SOURCE_DIR}/apriltag_pywrap.c ${PROJECT_BINARY_DIR}/apriltag_detect.docstring.h ${PROJECT_BINARY_DIR}/apriltag_py_type.docstring.h)
add_custom_command(OUTPUT apriltag${PY_EXT_SUFFIX}
COMMAND ${PY_LINKER} ${PY_LDFLAGS} -Wl,-rpath=lib apriltag_pywrap.o ${LIB_APRILTAG_PATH}/libapriltag.so -o apriltag${PY_EXT_SUFFIX}
DEPENDS ${PROJECT_NAME} apriltag_pywrap.o)
add_custom_target(apriltag_python ALL
DEPENDS apriltag${PY_EXT_SUFFIX})

execute_process(COMMAND python3 -m site --user-site OUTPUT_VARIABLE PY_DEST)
string(STRIP ${PY_DEST} PY_DEST)
install(CODE "execute_process(COMMAND cp ${PROJECT_BINARY_DIR}/apriltag${PY_EXT_SUFFIX} ${PY_DEST})")

endif (NOT Python3_NOT_FOUND)


# Examples
# apriltag_demo
add_executable(apriltag_demo example/apriltag_demo.c)
Expand Down
60 changes: 60 additions & 0 deletions apriltag_detect.docstring
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
AprilTag detector

SYNOPSIS

import cv2
import numpy as np
from apriltag import apriltag

imagepath = '/tmp/tst.jpg'
image = cv2.imread(imagepath, cv2.IMREAD_GRAYSCALE)
detector = apriltag("tag36h11")

detections = detector.detect(image)

print("Saw tags {} at\n{}". \
format([d['id'] for d in detections],
np.array([d['center'] for d in detections])))

----> Saw tags [3, 5, 7, 8, 10, 10, 14] at
[[582.42911184 172.90587335]
[703.32149701 271.50587376]
[288.1462089 227.01502779]
[463.63679264 227.91185418]
[ 93.88534443 241.61109765]
[121.94062798 237.97010936]
[356.46940849 260.20169159]]

DESCRIPTION

The AprilTags visual fiducial system project page is here:
https://april.eecs.umich.edu/software/apriltag

This is a Python class to provide AprilTags functionality in Python programs. To
run the detector you

1. Construct an object of type apriltag.apriltag()

2. Invoke the detect() method on this object

The detect() method takes a single argument: an image array. The return value is
a tuple containing the detections. Each detection is a dict with keys:

- id: integer identifying each detected tag

- center: pixel coordinates of the center of each detection

- lb-rb-rt-lt: pixel coordinates of the 4 corners of each detection. The order
is left-bottom, right-bottom, right-top, left-top

- hamming: How many error bits were corrected? Note: accepting large numbers of
corrected errors leads to greatly increased false positive rates. NOTE: As of
this implementation, the detector cannot detect tags with a hamming distance
greater than 2.

- margin: A measure of the quality of the binary decoding process: the average
difference between the intensity of a data bit versus the decision threshold.
Higher numbers roughly indicate better decodes. This is a reasonable measure
of detection accuracy only for very small tags-- not effective for larger tags
(where we could have sampled anywhere within a bit cell and still gotten a
good detection.)
80 changes: 80 additions & 0 deletions apriltag_py_type.docstring
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
AprilTag detector

SYNOPSIS

import cv2
import numpy as np
from apriltag import apriltag

imagepath = '/tmp/tst.jpg'
image = cv2.imread(imagepath, cv2.IMREAD_GRAYSCALE)
detector = apriltag("tag36h11")

detections = detector.detect(image)

print("Saw tags {} at\n{}". \
format([d['id'] for d in detections],
np.array([d['center'] for d in detections])))

----> Saw tags [3, 5, 7, 8, 10, 10, 14] at
[[582.42911184 172.90587335]
[703.32149701 271.50587376]
[288.1462089 227.01502779]
[463.63679264 227.91185418]
[ 93.88534443 241.61109765]
[121.94062798 237.97010936]
[356.46940849 260.20169159]]

DESCRIPTION

The AprilTags visual fiducial system project page is here:
https://april.eecs.umich.edu/software/apriltag

This is a Python class to provide AprilTags functionality in Python programs. To
run the detector you

1. Construct an object of type apriltag.apriltag()

2. Invoke the detect() method on this object

The constructor takes a number of arguments:

- family: a string for the tag type we're detecting. This argument is required.
If an invalid string is given, the known list of tag families will be
reported. At the time of this writing the known families are:

- "tag36h11"
- "tag25h9"
- "tag16h5"
- "tagCircle21h7"
- "tagCircle49h12"
- "tagStandard41h12"
- "tagStandard52h13"
- "tagCustom48h12"

All the other arguments are optional:

- Nthreads: how many threads the detector should use. Default is 1

- maxhamming: max number of corrected bits. Larger values guzzle RAM. Default is
1

- decimate: detection of quads can be done on a lower-resolution image,
improving speed at a cost of pose accuracy and a slight decrease in detection
rate. Decoding the binary payload is still done at full resolution. Default is 1.0

- blur: What Gaussian blur should be applied to the segmented image (used for
quad detection?) Parameter is the standard deviation in pixels. Very noisy
images benefit from non-zero values (e.g. 0.8). Default is 0.0

- refine_edges: When non-zero, the edges of the each quad are adjusted to "snap
to" strong gradients nearby. This is useful when decimation is employed, as it
can increase the quality of the initial quad estimate substantially. Generally
recommended to be on. Very computationally inexpensive. Option is ignored if
decimate == 1. Default is True

- debug: When non-zero, write a variety of debugging images to the current
working directory at various stages through the detection process. (Somewhat
slow). Default is False

The detect() method takes a single argument: an image array
Loading

0 comments on commit d13014b

Please sign in to comment.