RealOrangeOne / zoloto

A fiducial marker system powered by OpenCV - Supports ArUco and April
https://zoloto.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
13 stars 7 forks source link

Fix detection of generated marker PDFs #313

Closed RealOrangeOne closed 1 year ago

RealOrangeOne commented 1 year ago

This is a fairly simple fix, but there's some backstory. Stay a while and listen:

Marker PDFs add a border to the resulting PDFs. The aim of this was to help lining up, and ensure a high-contrast border for the marker (on top of the black border it already has). Additionally, a few small notches are added showing the center of the marker, which is useful for alignment.

After some testing, it turns out this border is actually quite a hindrance, and can drastically affect the chances of detecting a marker.

As part of the marker detection, OpenCV performs "contour detection and refinement", where it searches for squares with well defined edges to attempt to decode into markers. If 2 contours are too close together, and fully contained within eachother, the larger contour is kept. When marker detection failed, it was because the border was superseding the actual marker edge as a contour candidate, which was then rejected later when it came to decoding.

This could be considered a limitation of OpenCV, whereby a smaller valid contour is rejected for a larger potentially-invalid one. However, OpenCV has a tunable for this: minMarkerDistanceRate:

Minimum distance between any pair of corners from two different markers. It is expressed relative to the minimum marker perimeter of the two markers. If two candidates are too close, the smaller one is ignored.

Its default value isn't quite enough to separate the marker and its border as different contours. In testing, tweaking this value (as little as 10-20%) improved reliability to the point of working as expected. If adjusted too low, it results in markers appearing multiple times, but this required drastic changes (around 1000%) to occur.

This also explains why we saw better detection of markers at a larger distance, or when moving. Because at distance, the border is imperceptible and excluded during adaptive thresholding. Similar is true when moving, where the hard edge of the border is disrupted enough to not be considered a contour. We also saw this be unreliable, likely due to whether the border was covered by any mounting tape or not.

The solution proposed here is two-fold:

Additionally, it may be useful to weak the value of minMarkerDistanceRate downstream. I don't want to change the value by default, because it's important Zoloto remain unopinionated and uses the defaults. Setting this to even 0.035 drastically improves detection. Changing this theoretically reduces the need to recolour the border, as even if the border is seen, it doesn't affect the contour refinement.

Does that mean this PR is a 6-character change at its core? Yes. But the usability and testing improvements are worthwhile.

PeterJCLaw commented 1 year ago

Additionally, it may be useful to weak the value of minMarkerDistanceRate downstream. I don't want to change the value by default, because it's important Zoloto remain unopinionated and uses the defaults.

Since Zoloto is involved in producing the markers and those markers are already not the default markers I don't think the argument that Zoloto use the defaults is moot. It is demonstrably already not doing so, so trying to get back to that here feels too late.

IMO it's sufficiently important that Zoloto offer good performance with its own markers for this to be something that it overrides.

Alternatively, if changing this demonstrably has negative effects on the detection behaviour then the presence of a marker outline probably needs deeper reconsideration.

RealOrangeOne commented 1 year ago

the presence of a marker outline probably needs deeper reconsideration

This is the reason I also made the border lighter, so that even with it there, it's less likely to cause an impact. I've also done testing with the border even lighter, such that in even unreasonable lighting, it thresholds to white. This way it's even less likely to cause issues, and even more obviously just for human consumption.

I'd also considered removing the border entirely in favour of just the center notches, but using just those points to line up a side makes mounting more annoying.

PeterJCLaw commented 1 year ago

Just a thought -- would it help the thresholding if we made the outline only present at the corners:

┌    ┐

└    ┘

That should still be plenty for humans.

8BitJosh commented 1 year ago

Just a thought -- would it help the thresholding if we made the outline only present at the corners:

┌    ┐

└    ┘

That should still be plenty for humans.

I dont think we should spend all of our effort designing the boarder of the token. This will help a bit with the wall markers but once they get put onto a token we will have a hard physical boarder anyway, which these changes would do nothing about.

RealOrangeOne commented 1 year ago

IMO it's sufficiently important that Zoloto offer good performance with its own markers for this to be something that it overrides.

On reflection, I agree. Especially given if it does cause people any issues, it's trivially simple to un-override the value if needed. I've pushed up https://github.com/RealOrangeOne/zoloto/pull/313/commits/c86b25a941db00cb794aa58827d5840876957d6f to address.