• Hardware Platform (Jetson / GPU) Jetson Orin Nano
• JetPack Version (valid for Jetson only) 6.2.1
• VPI Version 3.2
• DeepStream Version 7.1
• Issue Type (questions, new requirements, bugs) Bugs
VPI AprilTags detector randomly yields unexpected false detections, no matter which family (the simpler the family the more chance a false will be detected) or maxBitsCorrected defined.
Here’s a minimal demo which detects a false tag in the attached objectless image:
input.zip (358.9 KB)
cmake_minimum_required(VERSION 3.15)
project(apriltags)
find_package(vpi REQUIRED)
add_executable(apriltags
apriltags.cpp
)
target_link_libraries(apriltags
PRIVATE
vpi
)
#include <string.h>
#include <sstream>
#include <vpi/VPI.h>
#include <vpi/algo/AprilTags.h>
#define CHECK_VPI_STATUS(STMT) \
do \
{ \
VPIStatus status = (STMT); \
if (status != VPI_SUCCESS) \
{ \
char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
std::ostringstream ss; \
ss << vpiStatusGetName(status) << ": " << buffer; \
throw std::runtime_error(ss.str()); \
} \
} while (0);
static unsigned char *loadPGM(const char *filename, int *w, int *h)
{
FILE *f = fopen(filename, "rb");
if (!f) return NULL;
char magic[3];
fscanf(f, "%2s", magic);
if (strcmp(magic, "P5") != 0)
return NULL;
int c;
c = fgetc(f);
while (c == '#') {
while (fgetc(f) != '\n');
c = fgetc(f);
}
ungetc(c, f);
int width, height, maxval;
fscanf(f, "%d %d %d", &width, &height, &maxval);
fgetc(f);
*w = width;
*h = height;
unsigned char *buffer = (unsigned char*)malloc(width * height);
fread(buffer, 1, width * height, f);
fclose(f);
return buffer;
}
VPIImage loadPGMtoVPI(const char *filename, int& w, int& h)
{
unsigned char *pgm = loadPGM(filename, &w, &h);
if (!pgm)
return NULL;
VPIImage img;
VPIImageData imgData;
vpiImageCreate(w, h, VPI_IMAGE_FORMAT_U8, 0, &img);
vpiImageLockData(img, VPI_LOCK_WRITE, VPI_IMAGE_BUFFER_HOST_PITCH_LINEAR, &imgData);
uint8_t *dst = (uint8_t*)imgData.buffer.pitch.planes[0].data;
int pitch = imgData.buffer.pitch.planes[0].pitchBytes;
for (int y = 0; y < h; y++)
memcpy(dst + y * pitch, pgm + y * w, w);
vpiImageUnlock(img);
free(pgm);
return img;
}
int main(int argc, char** argv)
{
VPIImage image;
VPIAprilTagDecodeParams params;
VPIStream stream;
VPIPayload detector;
VPIArray detections;
int w, h;
image = loadPGMtoVPI("input.pgm", w, h);
params = {NULL, 0, 0, VPI_APRILTAG_16H5}; // any maxBitsCorrected [0,2] yields false detections
CHECK_VPI_STATUS(vpiStreamCreate(VPI_BACKEND_CPU, &stream));
CHECK_VPI_STATUS(vpiCreateAprilTagDetector(VPI_BACKEND_CPU, w, h, ¶ms, &detector));
CHECK_VPI_STATUS(vpiArrayCreate(64, VPI_ARRAY_TYPE_APRILTAG_DETECTION, VPI_BACKEND_CPU, &detections));
CHECK_VPI_STATUS(vpiSubmitAprilTagDetector(stream, 0, detector, 64, image, detections));
CHECK_VPI_STATUS(vpiStreamSync(stream));
VPIArrayData detections_data;
CHECK_VPI_STATUS(vpiArrayLockData(detections, VPI_LOCK_READ, VPI_ARRAY_BUFFER_HOST_AOS, &detections_data));
VPIAprilTagDetection *detection = reinterpret_cast<VPIAprilTagDetection *>(detections_data.buffer.aos.data);
for (int32_t count = *detections_data.buffer.aos.sizePointer; count > 0; count--, detection++) {
printf("%f %f\n", detection->center.x, detection->center.y);
}
vpiArrayUnlock(detections);
vpiArrayDestroy(detections);
vpiPayloadDestroy(detector);
vpiStreamDestroy(stream);
vpiImageDestroy(image);
}
$ ./apriltags
952.112000 481.504059
This seems like a serious issue/bug, making VPI AprilTags practically useless.
Thank you in advance.