Ask Your Question

detect fiducial of dots

asked 2015-03-31 04:23:03 -0500

antithing gravatar image

Hi, I have an augmented reality application that is working, using the awesome ArUco library.

BUT, I want to replace the fiducial markers with my own, made of dots.

SO, for example, four dots for the corners, one on the top edge for orientation and one or two in the centre for identification.

Findcorners will not work, obviously, because there are no corners. Can anyone point me at a method to detect a pattern of dots and give orientation?

c++, visual studio.


edit retag flag offensive close merge delete


Can you post also an image with the explanation? It seems not very explicit what you are saying

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-03-31 04:36:04 -0500 )edit

Sorry, something like this:

The four corners are the points i will need for solvePnp, the mid top dot is to find the orientation, the middle dot will be to identify which marker-pattern it is.


antithing gravatar imageantithing ( 2015-03-31 05:14:00 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2015-03-31 04:35:51 -0500

updated 2015-03-31 07:03:30 -0500

cv::threshold (maybe Otzu), cv::erode/dilate, findContours, cv::moments to check which contours are your circles, solvePNP to get the pose. But as always, an image of your marker could help.

Something to begin with: (I just have to practive my python)

#!/usr/bin/env python 
import cv2

im_col = cv2.imread('in.jpg',cv2.IMREAD_COLOR)

im = cv2.cvtColor(im_col,cv2.COLOR_BGR2GRAY)

(threshold,bw) = cv2.threshold(im,150,255,cv2.THRESH_BINARY)
#(threshold,bw) = cv2.threshold(im,150,255,cv2.THRESH_OTSU)

conts, hier = cv2.findContours(bw,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

cleaned = []
for c in conts:
  a = cv2.contourArea(c)
  print a
  if a < 50 and a > 5:

cv2.drawContours(im_col,cleaned,-1,(0,255,0), 3)



Otsu will generate many false positives so that you will have to clean up with Ransac or something similar, THRES_BINARY depends stronger on the threshold so that it's not really robust.

edit flag offensive delete link more


added image above, thanks for your reply!

antithing gravatar imageantithing ( 2015-03-31 05:14:19 -0500 )edit

I can find each dot individually, but what is the best way to search for the whole pattern at once? if that makes sense...

antithing gravatar imageantithing ( 2015-03-31 05:15:07 -0500 )edit

I think the best way is to search the individual points and then merge the detections. Do you have real world images of your marker?

FooBar gravatar imageFooBar ( 2015-03-31 05:39:01 -0500 )edit

I am yet to make them, but they will be ir-leds, viewed with an infrared camera. So pretty much just white dots on a black background, as above.

antithing gravatar imageantithing ( 2015-03-31 05:41:33 -0500 )edit

like this:

only brighter...

antithing gravatar imageantithing ( 2015-03-31 05:56:55 -0500 )edit

thanks! will port your code to c++ and try it out.

antithing gravatar imageantithing ( 2015-03-31 07:10:16 -0500 )edit

ok so i have this:

std::vector< int > cleaned;
double sum = 0;

for (int i = 0; i < contours.size(); i++)
    double a = contourArea(contours[i]);

    if (a < 50 && a > 5)

     sum =(sum + cleaned[i]);   


which gives the sum of the contours, as your code does. But i can't get it to draw the rectangle. I ideally need a bounding box that rotates based on the angle of the marker, eg, constrained by the corner points of the square.

apologies for idiocy...

antithing gravatar imageantithing ( 2015-03-31 08:09:51 -0500 )edit

you should have again a look at the code. The area is nowhere summed. I just select some of contours. (and please don't forget to upvote/accept)

FooBar gravatar imageFooBar ( 2015-03-31 08:49:59 -0500 )edit

ah right. sorry! Still, I can't draw the contour... Any time i use 'cleaned', it crashes..

drawContours(drawing, cleaned, -1, color, CV_FILLED, 8, hierarchy);

Possibly i need to go read some opencv docs. gaargh.


antithing gravatar imageantithing ( 2015-03-31 09:12:02 -0500 )edit

std::vector< int > cleaned;

    for (int i = 0; i < contours.size(); i++){
        double a = contourArea(contours[i]);
        if (a < 50 && a > 5)

    for (int i = 0; i < cleaned.size(); i++){
      drawContours(drawing, contours, cleaned[i], color, CV_FILLED, 8); 
FooBar gravatar imageFooBar ( 2015-03-31 09:58:58 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2015-03-31 04:23:03 -0500

Seen: 864 times

Last updated: Mar 31 '15