AprilRobotics / apriltag

AprilTag is a visual fiducial system popular for robotics research.
https://april.eecs.umich.edu/software/apriltag
Other
1.56k stars 535 forks source link

What's the meaning of 'apriltag.c:448: homography_compute2: Assertion `max_val_idx >= 0' failed.'? #321

Closed WZG3661 closed 4 months ago

WZG3661 commented 6 months ago

an error ccurred accidentally: apriltag.c:448: homography_compute2: Assertion `max_val_idx >= 0' failed. what's the meaning of this error? did I do something wrong?

christian-rauch commented 6 months ago

This check was added in #317 to avoid indexing with a negative index. I hope that the proposed fix in #213, which was ported into #317 via 359a98403e64237d6ec7b800dc8b61ddaa7ee570, fixes the issue, but apparently, it does not.

Do you have a reproducible script and data for this?

WZG3661 commented 6 months ago

this is my code:

#include "apriltag.h"
#include "tagStandard41h12.h"

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

int main() {

  std::string img_path = "path_to_img";
  cv::Mat img = cv::imread(img_path, CV_8UC1);

  apriltag_family_t *tf;
  apriltag_detector_t *td;

  tf = tagStandard41h12_create();
  td = apriltag_detector_create();
  apriltag_detector_add_family(td, tf);

  image_u8_t im = {img.cols, img.rows, img.cols, img.data};
  zarray_t *detections = apriltag_detector_detect(td, &im);

  apriltag_detector_destroy(td);
  tagStandard41h12_destroy(tf);
  return 0;
}

this is the picture: 1710383687 256000 and the commit is e6cd3c7afdc

christian-rauch commented 6 months ago

Thanks. I can reproduce this with the apriltag_demo:

apriltag_demo -f tagStandard41h12 319063435-0f7a44f8-58e7-452c-99bc-142160e24a93.jpg
christian-rauch commented 6 months ago

With the debug information

debug_clusters

debug_quads_raw

I can see that there are two odd perfect axis-aligned rectangular quads and with the debugger I can see that those coordinates are horizontally and vertically aligned (identical x and y coordinates).

While it is very unlikely that we will get detections that are perfectly axis-aligned like this on a sub-pixel level, I don't see why homography_compute2 should be able to compute a homography from this.

mkrogius commented 4 months ago

At e6cd3c7afdc23814f38a6b537904a41c393fc305 I am able to repro with:

rm -r build
cmake -B build
cmake --build build
uild/apriltag_demo -f tagStandard41h12 ~/Downloads/319063435-0f7a44f8-58e7-452c-99bc-142160e24a93.jpg

(I wasn't able to repro with -DCMAKE_BUILD_TYPE=Release since it removes asserts)

Printing out the correspondences matrix that is input to homography_compute2 in this case gives:

-1.0000 -1.0000 191.9706 454.0736 
1.0000 -1.0000 191.9706 454.0736 
1.0000 1.0000 191.9706 472.9767 
-1.0000 1.0000 191.9706 472.9767 

Which is a degenerate case for which a valid homography does not exist. We should return null rather than asserting from homography_compute2.

But how did we end up with a degenerate case not getting filtered out earlier? This is the quad in question: debug_quads_raw

The reason is that we only end up with a degenerate quad after the refine_edges step and there are not checks on the result of the refine edges step that the quad is valid. This is fine IMO since the fastest way to know if a quad is valid at this point is just to do the decode step, which is what happens next