aprilrobotics / apriltag Goto Github PK
View Code? Open in Web Editor NEWAprilTag is a visual fiducial system popular for robotics research.
Home Page: https://april.eecs.umich.edu/software/apriltag
License: Other
AprilTag is a visual fiducial system popular for robotics research.
Home Page: https://april.eecs.umich.edu/software/apriltag
License: Other
I want to use the 36h11 tags with 2 black borders, apriltag1 and apriltag2 can set this value. But I found that black_border is removed from apriltag3.
so, MY QUESTION IS: How can I use apriltag3 to detect 36h11 with 2 black_border.
thanks in advance.
Hello,
Firstly, thank you for this great project, I really appreciate your effort to push forward the research field !
I'm writing here because I'm curious to try the version 3 of AprilTag. I'm used with the previous version.
So I have printed the Tag36h11 with the ID 0, from the git "Apriltag-imgs"
After printing it on a white piece of paper, I have downloaded this repository and compile it on my Ubuntu 16.04 machine.
I have followed all the steps described by the README.md file, and when I run the OpenCV example, all works ok (with the command : ./opencv_demo ) and the video is displayed.
But when I show the AprilTag on the camera, nothing happen. No AprilTag detected.
I don't know if I have missed something, because it is supposed to be the basic example. I'm using the OpenCV 3.4.0.
Do you have any clue of what could happened ? Is it working in your side ?
Thanks in advance for your time !
I got a memory leak using estimate_tag_pose() and i am wondering if i forgot to free something.
What I tried after receiving the pose:
matd_destroy(pose.R);
matd_destroy(pose.t);
The valgrind output was:
7,992 bytes in 999 blocks are definitely lost in loss record 13,538 of 13,605
at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x92B3731: matd_svd_tall (in /usr/local/lib/libapriltag.so.3.1.0)
by 0x92B4781: matd_svd_flags (in /usr/local/lib/libapriltag.so.3.1.0)
by 0x92B47AE: matd_svd (in /usr/local/lib/libapriltag.so.3.1.0)
by 0x929DF6A: orthogonal_iteration (in /usr/local/lib/libapriltag.so.3.1.0)
by 0x92A0030: estimate_tag_pose_orthogonal_iteration (in /usr/local/lib/libapriltag.so.3.1.0)
by 0x92A0134: estimate_tag_pose (in /usr/local/lib/libapriltag.so.3.1.0)
Is it my bad or could there be a memory leak in the library?
How should the pose be freed correctly? There is no destroy function like there is for a detection_t object.
Hi All,
I suggest to wait until all threads completed startup before returning in workerpool_create function, adding
pthread_mutex_lock(&wp->mutex);
while (wp->end_count < wp->nthreads) {
pthread_cond_wait(&wp->endcond, &wp->mutex);
}
pthread_mutex_unlock(&wp->mutex);
and in workerpool_run function, wp->end_count editing should be protected (ok... this problem should not happen), inserting it after mutex lock:
pthread_mutex_lock(&wp->mutex);
wp->end_count = 0;
pthread_cond_broadcast(&wp->startcond);
Best
Paolo
while compiling the project using the quick start guide here, I encounter the following errors:
.../src/apriltag/apriltag_pywrap.c:6:31: fatal error: numpy/arrayobject.h: No such file or directory
compilation terminated.
I'm using ubuntu 16.04 and ros kinetic
Hey there,
I was just about to use the apriltag library in a cmake project and encountered the following error message:
CMake Error at CMakeLists.txt:10 (add_library):
Target "apriltag-test" links to target "Threads::Threads" but the target
was not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
Shouldn't the apriltagConfig.cmake
handle finding the Threads library if it's a public dependency? A minimal example can be found here.
Cheers,
Stefan
Hello, i am trying to detect a tag36h11 printed on a piece of paper using an Asus Xtion pro live camera.
Although i can easily detect the printed tag when i capture frames from my webcam, i cannot detect it when using the Xtion.
I specifically start the colour stream from the Xtion using openni2, capture a rgb frame, convert to grayscale and then run the apriltag_detector, but to no avail.
If i redirect the feed from my webcam to the programm instead, the detection works as expected.
Anyone ever had any issues similar to this one ?
I will attach code and a sample image, in which i cannot detect anything
Thanks
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <OpenNI.h>
extern "C" {
#include "apriltag.h"
#include "tag36h11.h"
}
// Helper functions
void detectAprilTag(const cv::Mat &);
int main(int argc, char** argv){
const openni::SensorType sensorType = openni::SENSOR_COLOR;
const char windowName[] = "AprilTagDetection";
int srcMatType;
if(sensorType == openni::SENSOR_COLOR){
srcMatType = CV_8UC3;
} else {
srcMatType = CV_16U;
}
// Initialize camera, load drivers
openni::Status status;
status = openni::OpenNI::initialize();
if(status != openni::STATUS_OK){
printf("Failed to initialize OpenNI:\n%s\n",openni::OpenNI::getExtendedError());
return EXIT_FAILURE;
}
// Connect to any available OpenNI-compliant camera
openni::Device device;
status = device.open(openni::ANY_DEVICE);
if (status != openni::STATUS_OK){
printf("Failed to open device: \n%s\n", openni::OpenNI::getExtendedError());
openni::OpenNI::shutdown();
return EXIT_FAILURE;
}
// Ensure that device has the appropriate type of sensor
const openni::SensorInfo *sensorInfo = device.getSensorInfo(sensorType);
if(sensorInfo == NULL){
printf("Failed to find sensor of appropriate type\n");
device.close();
openni::OpenNI::shutdown();
return EXIT_FAILURE;
}
// Create stream, don't start it yet
openni::VideoStream stream;
status = stream.create(device, sensorType);
if(status != openni::STATUS_OK){
printf("Failed to create stream: \n%s\n",
openni::OpenNI::getExtendedError());
device.close();
openni::OpenNI::shutdown();
return EXIT_FAILURE;
}
{
// Select video mode with highest resolution
const openni::Array<openni::VideoMode> *videoModes = &sensorInfo->getSupportedVideoModes();
int maxResolutionX = -1;
int maxResolutionIndex = 0;
for(int i = 0; i < videoModes->getSize(); i++){
int resolutionX = (*videoModes)[i].getResolutionX();
if(resolutionX > maxResolutionX){
maxResolutionX = resolutionX;
maxResolutionIndex = i;
}
}
stream.setVideoMode((*videoModes)[maxResolutionIndex]);
}
openni::VideoMode vm = stream.getVideoMode();
int cols, rows;
cols = vm.getResolutionX();
rows = vm.getResolutionY();
// Start stream
status = stream.start();
if (status != openni::STATUS_OK){
printf("Failed to start stream: \n%s\n",
openni::OpenNI::getExtendedError());
stream.destroy();
device.close();
openni::OpenNI::shutdown();
return EXIT_FAILURE;
}
// OpenNI-frame, OpenCV-matrix and an openCV window
openni::VideoFrameRef frame;
cv::Mat dstMat;
cv::namedWindow(windowName);
// TODO (charis): Delete this as soon we debug this
// Initialize camera
/*
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cerr << "Couldn't open video capture device" << '\n';
return -1;
}
*/
// Capture and display frames until any key is pressed
while(cv::waitKey(1) == -1){
status = stream.readFrame(&frame);
if(frame.isValid()){
cv::Mat srcMat (
frame.getHeight(), frame.getWidth(), srcMatType,
(void *)frame.getData(), frame.getStrideInBytes());
if(sensorType == openni::SENSOR_COLOR){
cv::cvtColor(srcMat, dstMat, cv::COLOR_RGB2BGR);
} else {
srcMat.convertTo(dstMat, CV_8UC1);
}
// openni::RGB888Pixel* cData = (openni::RGB888Pixel *)frame.getData();
// cv::Mat colorImage(rows, cols, CV_8UC3, cData);
// dstMat = cv::imread("/home/xbaremenos/programms/apriltag/example/gray_frame.jpeg");
cv::imshow(windowName, dstMat);
// Detect april Tag in dstMat
// cap >> dstMat;
// std::cerr << "dstMat_type = " << dstMat.type() << '\n';
detectAprilTag(dstMat);
}
}
cv::destroyWindow(windowName);
stream.stop();
stream.destroy();
device.close();
openni::OpenNI::shutdown();
return 0;
}
void detectAprilTag(const cv::Mat &frame){
apriltag_detector_t *td = apriltag_detector_create();
apriltag_family_t *tf = tag36h11_create();
apriltag_detector_add_family(td, tf);
td->quad_decimate = 2.0;
td->quad_sigma = 0.5;
td->refine_edges = 1;
td->decode_sharpening = 0.25;
td->nthreads = 4;
// td->debug = 1;
// Detection
// Make sure we have a grayscale img
cv::Mat gray;
if(frame.type() == CV_8UC1) gray = frame;
else cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
// cv::cvtColor(frame, gray, cv::COLOR_RGB2GRAY);
// gray = cv::imread("/home/xbaremenos/programms/apriltag/example/gray_frame.jpeg", 0);
// cv::GaussianBlur(gray, gray, cv::Size(15, 15), 0);
// std::cerr << "gray_type = " << gray.type() << '\n';
cv::imshow("gray", gray);
image_u8_t im = {
.width = gray.cols,
.height = gray.rows,
.stride = gray.cols,
.buf = gray.data
};
zarray_t *detections = apriltag_detector_detect(td, &im);
std::cout << zarray_size(detections) << " tags detected" << '\n';
// std::cout << "td->quad_sigma = " << td->quad_sigma << '\n';
/*
std::cout << "td->quad_decimate = " << td->quad_decimate << '\n';
std::cout << "td->quad_sigma = " << td->quad_sigma << '\n';
std::cout << "td->refine_edges = " << td->refine_edges << '\n';
std::cout << "td->decode_sharpening = " << td->decode_sharpening << '\n';
std::cout << "td->nthreads = " << td->nthreads << '\n';
std::cout << "td->debug = " << td->debug << '\n';
*/
// Cleanup
apriltag_detections_destroy(detections);
apriltag_detector_destroy(td);
tag36h11_destroy(tf);
}
I'm getting the following compilation errors in my project when including apriltag.h:
external/apriltag/common/matd.h:274:39: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
return (a->ncols == 1 && a->nrows == len) || (a->ncols == len && a->nrows == 1);
^
external/apriltag/common/matd.h:274:60: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
return (a->ncols == 1 && a->nrows == len) || (a->ncols == len && a->nrows == 1);
Casting len to unsigned int
fixes the problem, but I'd like to avoid making local changes/forking.
hi,
i want to consult that whether the rotate90 in this version has the same function as rotate90 in version2? because i test it on Tag36h11, and i find that the version3 do not work well when the Apriltag rotate 90 degree. thanks
static uint64_t rotate90(uint64_t w, uint32_t d)
{
uint64_t wr = 0;
for (int32_t r = d-1; r >=0; r--) {
for (int32_t c = 0; c < d; c++) {
int32_t b = r + d*c;
wr = wr << 1;
if ((w & (((uint64_t) 1) << b))!=0)
wr |= 1;
}
}
return wr;
}
static uint64_t rotate90(uint64_t w, int numBits)
{
int p = numBits;
uint64_t l = 0;
if (numBits % 4 == 1) {
p = numBits - 1;
l = 1;
}
w = ((w >> l) << (p/4 + l)) | (w >> (3 * p/ 4 + l) << l) | (w & l);
w &= ((1L << numBits) - 1);
return w;
}
After I run the detetection code, I printed the results as follows:
[
Detection(tag_family=b'tag36h11',
tag_id=10,
hamming=0,
goodness=0.0,
decision_margin=84.80438232421875,
homography=array([[-7.38342440e-01, -2.70827385e-02, -4.84738851e+00],
[-7.20858833e-02, -7.50317415e-01, -2.15003013e+00],
[-9.95938328e-05, -1.93046851e-04, -1.13314994e-02]]),
center=array([427.77997126, 189.7392432 ]),
corners=array([[369.78128052, 120.26848602],
[494.62762451, 130.96569824],
[482.85839844, 255.71211243],
[362.02590942, 247.55128479]]))
]
I was confused by some parameters in the Detection(...), can anyone know about this tell something about it? Especially the parameter 'homography', 'hamming', 'decision_margin' and 'goodness'.
I have had some trouble building Apriltag on an Anaconda environment in Ubuntu 18.04
Here is my solution and I hope it helps others: use the following commands to build instead
export CONDA_HOME=/opt/conda
export CONDA_ENV=opencv
cmake -D PYTHON_LIBRARY=$CONDA_HOME/envs/$CONDA_ENV/lib/libpython3.6m.so -D PYTHON_INCLUDE_DIR=$CONDA_HOME/envs/$CONDA_ENV/include/python3.6m .
mkdir -p ~/.local/lib/python3.6/site-packages # the Makefile installs the wrapper to the user-site so make this directory if not exists
sudo make install
I got this working after consulting https://cmake.org/cmake/help/v3.0/module/FindPythonLibs.html which mentions the parameters PYTHON_LIBRARY
and PYTHON_INCLUDE_DIR
. Incidentally, these are the same parameters used when one builds OpenCV (probably because both use the same Cmake module).
If you think this is useful, I could open a pull request incorporating this instruction (see my fork https://github.com/lixiii/apriltag).
If you are curious, this is the error that you will get if you try installing using cmake . && make install
and anaconda:
(base) root@47b067de4de5:~/apriltag2# cmake .
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
...
...
-- Could NOT find PythonLibs (missing: PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS)
-- Configuring done
-- Generating done
-- Build files have been written to: /root/apriltag
Hi,
I am glad to find this version shows the in-process pictures, it helps me a lot for learning this algorithm.
In the article โAprilTag 2: Efficient and robust fiducial detectionโ fig.3 (b), the adaptive threshold result seemed normal. When I test the opencv demo, results are as follows. The right is the source picture, the left used another algorithm to threshold, and put into detector.
It looks so many noises and candidate quads when using threshold algorithm on the demo , so is this to save time or for precision?
Thanks!
Hi!
Firstly, thank you for your great work!
I'm writing here because I had a problem. I ran the project, but it only printed three lines and quit. The three lines are shown below:
'Summary
hamm 0 0 0 0 0 0 0 0 0 0 0.000
0'
It seems the parameter 'maxiters' equals one, but I don't know how to fix this. Would you help me with this one? Thank you in advance.
Best,
Ivy
I've been able to build apriltag in a Linux VM and can run the apriltag_demo. But, when I run the program I don't have any options to select or any way to point to an image of an apriltag. All I get is an output that reads "Summary Hamm" with a bunch of zeros. Would appreciate any direction.
Following the integration of CMake and the package.xml
metadata in #11, this issue is for tracking the release of the library to the official ROS1 and ROS2 repo.
I released to ROS2 crystal a while ago from my now obsolet repo. A future PR to rosdistro
would need to replace this section.
Hi,
I would like to know the coordinate system of pose resulting from estimate_tag_pose
. (x-right, y-down, z- goes inside the tag )?.
Also what is the correct sequence(XYZ
or ZYX
or ...) to determine roll, pitch, yaw from rotation matrix of pose?.
Thank you.
Hi there,
first of all thank you for providing the library. We use it a lot in our research. ๐
A few days ago you merged in a python wrapper as far as I can see and the patch detects python in the most obscure way I have seen so far in my life as a distribution maintainer.
Please consider streamlining the detection process by simply using find_package(Python)
et. al..
The current process does not even mention NumPy, which you include in your sources though.
This accidentally works in Debian-based systems because they added a handy symlink
/usr/include/numpy -> /usr/lib/python3.6/site-packages/numpy/core/include/numpy
, but this link is not defined through the numpy project and other Linux distributions do not have it.
So you really should explicitly request NumPy support.
On my system, I also see this other error, which is related to lib
being called lib64
on my system:
Errors << apriltag:make ws/logs/apriltag/build.make.000.log
gcc: error: ws/build/apriltag/lib/libapriltag.so: No such file or directory
make[2]: *** [CMakeFiles/apriltag_python.dir/build.make:62: apriltag.cpython-36m-x86_64-linux-gnu.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/apriltag_python.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
I'm surprised this apparently does not appear on Debian-based systems, as they enforced this 64bit suffix quite strongly.
Apriltag 2 had a concept of goodness
defined as a measure of the quality of tag localization - average contrast of the pixels around the border of the tag. Does this concept still exist anywhere?
Visual Studio in Debug is telling me that the stack is getting corrupted in apriltag.c in homography_compute2(). See lines 435, 436.
double max_val = 0;
int max_val_idx = -1;
I confirm in the debugger that the invalid index (-1) for max_val_idx survives to be used as an index later in the function. So I simply changed the initial value of max_val to be -1.0 and the problem went away because the first iteration of the loop then assigns both values and max_val_idx is no longer -1.
see #54 (comment)
I'm not sure if you get notifications on closed bugs but I couldn't re-open #54, so filing this. Please close if that is preferred.
Thanks a lot.
Hi,
When the tag is placed parallel to the image plane, the quaternions dance around zero. Though the variance is not high, the angular pose when visualized in rviz flickers a lot.
How can we fix this?
I have run the opencv_demo and all the apritags can be detected. my current probem is how to output the pose information(RT) of apriltags? is there code released?
Trying to compile on Red Hat RHEL 7. I've installed cmake3 which creates a makefile. This error on make install. Any ideas?
make_errors.txt
With @surirohit we have been working on these Python bindings for your Apriltags3 library. We are building these for both x86 and arm architectures. We experience no issues with x86. However under arm (on a RPi), we get the following error when we try to access the homography of a detected April Tag:
Traceback (most recent call last):
File "apriltags3.py", line 465, in <module>
tags = at_detector.detect(img, True, camera_params, parameters['sample_test']['tag_size'])
File "apriltags3.py", line 360, in detect
homography =_matd_get_array(tag.H).copy()
File "apriltags3.py", line 124, in _matd_get_array
mat_ptr.contents.data,
ValueError: NULL pointer access
Segmentation fault
The exact same code runs with no issue under Ubuntu on a standard Laptop PC with a 64bit Intel x86 processor.
Given that the issue is architecture-depended (x86 vs arm, 64bit vs 32bit) we suspect that this could potentially be an issue on your end that you might be interested in looking into.
My compiler points out:
third_party/apriltags/apriltag-2019-06-24/common/pjpeg.c: In function 'pjpeg_decode_buffer':
third_party/apriltags/apriltag-2019-06-24/common/pjpeg.c:561:53: warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer
-memaccess]
memset(dcpred, 0, sizeof(dcpred));
I'm trying apriltag-2018-11-29.tgz with with Python using ctypes to access the .so.
I assumed that the order of the corners matches the marker, but that appears not to the the case.
The comments in the code say:
# p[4][2]: double The corners of the tag in image pixel coordinates. These always
# wrap counter-clock wise around the tag.
If I have the tag vertical
p[0] blue dot bottom left, p[1] green bottom right, p[2] red top right, p[3] white top left
If I turn more than 45 degrees
Now p[0] blue top right of marker, p[1] green top left, p[2] bottom left and p[3] bottom right
Is this a bug (maybe fixed in later code) or I've failed to understand how the orientation of the marker on the square can be found?
Yours
Ian
Regarding the fprintf
in apriltag_pose.c:435 that prints:
Error, more than one new minima found
How is a user of your library supposed to react to this message? Is this a bug or is it debugging output that can be safely ignored? In the latter case, perhaps this debugging output can be toggled on and off using a member of the apriltag_detection_info_t
?
This is not an issue. There was a simple mistake in my code.
Thanks for your excellent works, whereas I have some questions waiting your generous answers.
for (int i = 0; i < zarray_size(detections); i++)
{
apriltag_detection_t *det;
zarray_get(detections, i, &det);
line(frame, Point(det->p[0][0], det->p[0][1]),
Point(det->p[1][0], det->p[1][1]),
Scalar(0, 0xff, 0), 2);
line(frame, Point(det->p[0][0], det->p[0][1]),
Point(det->p[3][0], det->p[3][1]),
Scalar(0, 0, 0xff), 2);
line(frame, Point(det->p[1][0], det->p[1][1]),
Point(det->p[2][0], det->p[2][1]),
Scalar(0xff, 0, 0), 2);
line(frame, Point(det->p[2][0], det->p[2][1]),
Point(det->p[3][0], det->p[3][1]),
Scalar(0xff, 0, 0), 2);
stringstream ss;
ss << det->id;
String text = ss.str();
int fontface = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontscale = 1.0;
int baseline;
Size textsize = getTextSize(text, fontface, fontscale, 2,
&baseline);
putText(frame, text, Point(det->c[0]-textsize.width/2,
det->c[1]+textsize.height/2),
fontface, fontscale, Scalar(0xff, 0x99, 0), 2);
//pose_estimation
apriltag_detection_info_t info;
info.det = det;
info.tagsize = 178;
info.fx = astra.fx;
info.fy = astra.fy;
info.cx = astra.u0;
info.cy = astra.v0;
apriltag_pose_t pose;
double err = estimate_tag_pose(&info, &pose);
cout<<err<<endl;
}
zarray_destroy(detections);
As the Error says, I suppose the functionmatd_destroy
in estimate_tag_pose
frees a invalid pointer.
*** Error in `/home/xzy/Nursing_robot/camera/cmake-build-debug/Nursing_robot': free(): invalid pointer: 0x0000000000405b22 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f003f1d27e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f003f1db37a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f003f1df53c]
/usr/local/lib/libapriltag.so.3(matd_destroy+0x45)[0x7f00451e2cac]
/usr/local/lib/libapriltag.so.3(estimate_tag_pose+0x83)[0x7f0044dbeee8]
/home/xzy/Nursing_robot/camera/cmake-build-debug/Nursing_robot[0x404c4d]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f003f17b830]
/home/xzy/Nursing_robot/camera/cmake-build-debug/Nursing_robot[0x403fd9]
I think there is an issue with apriltag_to_image()
for the old tag families (16h5
, 25h9
, 36h11
).
This is what I get (id=0
):
16h5
25h9
36h11
Circle21h7
Circle49h12
Custom48h12
Standard41h12
Standard52h13
Looks like an issue with the border?
My code:
{
//16h5
apriltag_family_t *tf = tag16h5_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "16h5_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tag16h5_destroy(tf);
}
{
//25h9
apriltag_family_t *tf = tag25h9_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "25h9_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tag25h9_destroy(tf);
}
{
//36h11
apriltag_family_t *tf = tag36h11_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "36h11_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tag36h11_destroy(tf);
}
{
//Circle21h7
apriltag_family_t *tf = tagCircle21h7_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "Circle21h7_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tagCircle21h7_destroy(tf);
}
{
//Circle49h12
apriltag_family_t *tf = tagCircle49h12_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "Circle49h12_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tagCircle49h12_destroy(tf);
}
{
//Custom48h12
apriltag_family_t *tf = tagCustom48h12_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "Custom48h12_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tagCustom48h12_destroy(tf);
}
{
//Standard41h12
apriltag_family_t *tf = tagStandard41h12_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "Standard41h12_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tagStandard41h12_destroy(tf);
}
{
//Standard52h13
apriltag_family_t *tf = tagStandard52h13_create();
apriltag_detector_t *td = apriltag_detector_create();
apriltag_detector_add_family(td, tf);
image_u8_t *im = apriltag_to_image(tf, 0);
image_u8_write_pnm(im, "Standard52h13_id0.pnm");
image_u8_destroy(im);
apriltag_detector_destroy(td);
tagStandard52h13_destroy(tf);
}
Some issues.
I tried to import the python warpper from Ubentu 18.04 terminal command line.
It turns out that the only directory can do the
python3
import apriltag
is the root folder
apriltag.c
apriltag.cpython-36m-x86_64-linux-gnu.so
apriltag_demo
apriltag_detect.docstring
apriltag_detect.docstring.h
apriltag.h
apriltag_math.h
apriltag.pc
apriltag.pc.in
apriltag_pose.c
apriltag_pose.h
apriltag_py_type.docstring
apriltag_py_type.docstring.h
apriltag_pywrap.c
apriltag_pywrap.o
apriltag_quad_thresh.c
CMakeCache.txt
CMakeFiles
cmake_install.cmake
CMakeLists.txt
common
example
install_manifest.txt
install.sh
lib
LICENSE.md
Makefile
package.xml
python_build_flags.py
README.md
tag16h5.c
tag16h5.h
tag25h9.c
tag25h9.h
tag36h11.c
tag36h11.h
tagCircle21h7.c
tagCircle21h7.h
tagCircle49h12.c
tagCircle49h12.h
tagCustom48h12.c
tagCustom48h12.h
tagStandard41h12.c
tagStandard41h12.h
tagStandard52h13.c
tagStandard52h13.h
The only way to successfully import apriltag is to make sure that the ./lib is in the same directory.
Is there any way to add the
libapriltag.so.3.1.0
into system lib path? I do not want to copy the lib folder and paste it everywhere.
Simply copying the libapriltag.so.3.1.0 to /lib and making a soft link libapriltag.so.3 made the import work, but it does not look like the suitable solution.
I can't get apriltags3 (HEAD) to detect a newly created custom java -cp april.jar april.tag.TagFamilyGenerator standard_5 5
border-less tags. That is despite the otherwise excellent improvements in performance that apriltags3 has over the previous version with small tags.
I put a complete test case and example data here https://gist.github.com/nzjrs/e951294289ac22320d7188572e804fb8
It would be useful to adopt a version scheme and tag the code accordingly. This is try for other AprilRobotics repositories. In particular, this would enable some level of traceability for corporate users.
Trying to measure the yaw,pitch and roll angle using Apriltag. I have tag size constraint and can't be used more than 6cm.
Now measure the yaw angle and observed some fluctuations and noises.
Which type of tag and approach deliver better accuracy in rotation measurement?
When i want to detect tagCircle49h12 in opencv_demo,there has error:
apriltag.c: failed to allocate hamming decode table. Reduce max hamming size.
I only use "getopt_add_string(getopt, 'f', "family", "tagCircle49h12", "Tag family to use");" replace "getopt_add_string(getopt, 'f', "family", "tag36h11", "Tag family to use");" in thre opencv_demo.
How do you detect tagCircle49h12?
I have no issue with fewer number of tag id's like Tag36h10, Tag36h11 but when I tried with TagStandard52h13 with help of JNI function but my application got crashed. Please help, This is the first time I am using Apriltag. I have followed all the steps as guided in the wiki. There is something wrong in my process while using TagStandard52h13.
I have followed the steps like below.
image_u8_t* im = image_u8_create_from_pnm("test.png");
apriltag_detector_t *td = apriltag_detector_create();
apriltag_family_t *tf = tagStandard52h13_create();
apriltag_detector_add_family(td, tf);
zarray_t *detections = apriltag_detector_detect(td, im);
for (int i = 0; i < zarray_size(detections); i++) {
apriltag_detection_t *det;
zarray_get(detections, i, &det);
// Do stuff with detections here.
}
// Cleanup.
tagStandard52h13_destroy(tf);
apriltag_detector_destroy(td);
But no tags are being detected.
We are new to AprilTags and struggling with detection and pose estimation of apriltags from images.
We have installed the code for AprilTags from https://github.com/AprilRobotics/apriltag on a Google Colab Notebook, then on Google Colab Notebook we utilize the AprilTag python wrapper and execute AprilTag detection from images. Our image inputs are photos of AprilTags printed on standard paper taken from smartphones and computer webcameras. We are not able to detect the AprilTags in our images accurately, it seems like the output position information we get using the detector.detect() function is inaccurate. However, when we run the AprilTags IOS app on our images, the IOS app accurately detects the tag and estimates pose. We are not sure what is the problem.
We have shared our python code below, attached our inputs and outputs. Could you help us out about how to use AprilTags functions properly and solve our problem with detection and pose estimation?
Python Code:
import cv2
import numpy as np
from apriltag import apriltag
from matplotlib import pyplot as plt
imagepath = 'april_cam.jpg'
ii = np.zeros((25,25))
image = plt.imread(imagepath, cv2.IMREAD_GRAYSCALE)
image = image[:,:,0].copy()
plt.imshow(image)
detector = apriltag("tagStandard41h12")
print(detector)
detections = detector.detect(image)
ii = image.copy()
width = 25
for i in range(len(detections)):
center = detections[i]['center']
bound = detections[i]['lb-rb-rt-lt']
print(bound)
for bb in bound:
ii[int(bb[0])-width:int(bb[0])+width,int(bb[1])-width:int(bb[1])+width] = 1
ii[int(center[0])-width:int(center[0])+width,int(center[1])-width:int(center[1])+width] = 1
plt.imshow(ii)
Hi apriltag devs. I'm working on the Rust bindings for this library,
and here is my humble suggestion to better glue the library with Rust bindings.
The image_u8_create()
function assumes the default alignment DEFAULT_ALIGNMENT_U8
,
which is a compile-time macro and is not exported in compiled library.
The Rust side has no way take the value, and can only be done by copy-and-paste manner in code.
It would be prone to error if these constants change in future releases. It's better to be an extern
variable.
Dear AprilRobotics teams,
I have tried your library and I could compile the codes and run on my images on first try with no efforts in almost no time. Many thanks for that. Then I focused on pose estimation. Reading at the code, it looks like estimate_tag_pose calls estimate_tag_pose_orthogonal_iteration, which only uses the 4 corners of the tag (orthogonal_iteration function is called on v and p with n_points == 4). Am I correct ? Why only on the 4 corners ? Don't you have all the pixel values of each corners of the landmark ? And the equivalent coordinate in the real world (scaled using the given tagsize) ? If so you could provide all px / real word correspondances to your PnP solver (or equivalent) to get a more robust pose estimation.
What's your opinion ?
Best Regards
Boris Bocquet
Hi,
I git clone this repository and to build it. I can import the apriltag in python3 but can't import in python2. I check the CMakeList.txt file, and found that # TODO deal with both python2/3
.
So I want to know how can I build it for python2?
Thanks,
Mikoy Chinese
Hi,
seems there are multiple repos trying to wrap apritags for ROS, but most of them seem outdated. Are you planning on releasing a ROS node and keeping it up to date? Would be awesome...
I am building apriltag
from source code for ROS2 on Windows and I just realized it depends on pthreads
libraries (most likely it means the one built from vcpkg
after searching the git log). Without it, it will be failing at the following error messages:
Starting >>> apriltag
--- stderr: apriltag
--- output: apriltag
-- The C compiler identification is MSVC 19.16.27030.1
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
-- The CXX compiler identification is MSVC 19.16.27030.1
Please set them or make sure they are set and tested correctly in the CMake files:
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
PTHREAD_LIBRARIES
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works
linked by target "apriltag" in directory C:/colcon_ws/src/apriltag
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
---
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
Failed <<< apriltag [ Exited with code 1 ]
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
PTHREAD_LIBRARIES
linked by target "apriltag" in directory C:/colcon_ws/src/apriltag
-- Configuring incomplete, errors occurred!
See also "C:/colcon_ws/build/apriltag/CMakeFiles/CMakeOutput.log".
---
And here are some ideas to make life little bit easier for Windows developers:
rosdep
key for this external thing.pthreads
as a local vendor library for this project, which can be found in https://github.com/ros2/rviz/tree/ros2/rviz_assimp_vendor.What do you think?
Hi all,
Currently, I'm able to detect tags at 15fps on Pi 4 on 480x480 frames. Though image_raw
publishes up to 50fps, the /tag_detection
rate doesn't change even though a lot of RAM is available. Tried overclocking but the detection rate fell down on contrary. And can't really reduce tag sizes anymore.
Other things I tweaked:
tag_decimate
has no effect.Any advice from your past experiences?
Thanks!
should I create multiple detectors?
Oh I think it's through the method apriltag_detector_add_family
Hi, and thank you for making this code available.
I am using it in a live camera, and am seeing very heavy ambiguity pose flipping, so much so that it is unusable.
I am looking at implementing Temporal smoothing to fix this, but before I go down that route, is this normal? Or am I possibly doing something wrong?
Aruco markers with the same camera and calibration data are solid, Apriltags flip axes almost every frame.
Any tips greatly appreciated!
Thanks.
After building apriltag the usual way, then following with "make install" I am trying to compile code from outside the apriltag build area, and am relying on "pkg-config --cflags --libs apriltag
" in my makefile.
The use of "make install" from the apriltag cmake+make means that the include files from /usr/local/include/apriltag are in play, not the ones from the original apriltag build area.
As a result I ran into issues with two include files that needed modifications.
The following ones were problematic (likely there are more):
/usr/local/include/apriltag/common/getopt.h
/usr/local/include/apriltag/common/string_util.h
Both files reference nearby include files only with "filename.h" instead of <apriltag/common/filename.h" ...
I had to modify the above two files, and there are likely others that suffer from this same problem.
Here are the diffs:
$ diff /usr/local/include/apriltag/common/getopt.h
/usr/local/include/apriltag/common/getopt.h_broken
30,31c30,31
< #include <apriltag/common/zarray.h>
< #include <apriltag/common/string_util.h>
---
> #include "zarray.h"
> #include "string_util.h"
$ diff /usr/local/include/apriltag/common/string_util.h
/usr/local/include/apriltag/common/string_util.h_broken
35c35
< #include <apriltag/common/zarray.h>
---
> #include "common/zarray.h"
Someone way smarter than me can probably figure out how to fix these (and others) properly so that the #include references will work during the initial build and later on in other sources that reference the "make install" versions under /usr/local/include/apriltag.
Hello,
I edited the opencv_demo by adding the following because I am interested in pose:
//POSE DETECTION:
apriltag_detection_info_t info;
info.det = det;
info.tagsize = 100;
info.fx = 630;
info.fy = 630;
info.cx = 640;
info.cy = 360;
apriltag_pose_t pose;
double err = estimate_tag_pose(&info, &pose);
cout << "Err: " << err <<endl;
When I execute opencv_demo, it works for about 5 seconds, then crashes with this error:
Error, more than one new minima found.
*** Error in `./opencv_demo': free(): invalid pointer: 0x00007f01cd5ad81f ***
======= Backtrace: =========
Then it lists a bunch of locations.
How can I fix this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.