0
votes

I've been working on detecting fiducial markers in scenes. An example of my fiducial marker is here: http://tinypic.com/view.php?pic=4r6k3q&s=8#.VNgsgzVVK1F

I have been able to detect a single fiducial marker in a scene very well. What is the methodology for detecting multiple fiducial markers in a scene? Doing feature detection, extraction, and then matching is great for finding a single match, but it seems to be the wrong method for detecting multiple matches since it would be difficult to determine which features belong to which marker?

The fiducial markers would be the same, and would not be in a known location in the scene.

Update:

Below is some sample code. I was trying to match the first fiducial marker with x number of keypoints, and then use the remaining keypoints to match the second marker. However, this is not robust at all. Does anybody have any suggestions?

OrbFeatureDetector detector;
vector<KeyPoint> keypoints1, keypoints2; 

detector.detect(im1, keypoints1);
detector.detect(im2, keypoints2);

Mat display_im1, display_im2;
drawKeypoints(im1, keypoints1, display_im1, Scalar(0,0,255));
drawKeypoints(im2, keypoints2, display_im2, Scalar(0,0,255));

SiftDescriptorExtractor extractor;

Mat descriptors1, descriptors2;

extractor.compute( im1, keypoints1, descriptors1 );
extractor.compute( im2, keypoints2, descriptors2 );

BFMatcher matcher;
vector< DMatch > matches1, matches2;
matcher.match( descriptors1, descriptors2, matches1 );
sort (matches1.begin(), matches1.end());
matches2 = matches;
int numElementsToSave = 50;

matches1.erase(matches1.begin()+numElementsToSave,matches1.end());
matches2.erase(matches2.begin(),matches2.begin()+numElementsToSave);

Mat match_im1, match_im2;
drawMatches( im1, keypoints1, im2, keypoints2,
    matches1, match_im1, Scalar::all(-1), Scalar::all(-1),
    vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

drawMatches( im1, keypoints1, im2, keypoints2,
    matches2, match_im2, Scalar::all(-1), Scalar::all(-1),
    vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
2
See my answer here: stackoverflow.com/questions/28407828/… it might be good solution for you.cyriel
Thanks for the input. On the surface, I don't see how to apply your answer to my problem, but I will explore it a bit more.P3d0r

2 Answers

0
votes

I have never tried it before, but here you have a good explanation about the detection of multiple occurrences:

This tutorial shows how enabling multiple detection of the same object. To enable multiple detection, the parameter General->multiDetection should be checked. The approach is as following:

  • As usual, we match all features between the objects and the scene.
  • For an object which is in the scene two times (or more), it should have twice of matched features. We apply a RANSAC algorithm to find a homography. The inliers should belong to only one occurrence of the object, all others considered as outliers. We redo the homography process on the outliers, then find another homography… we do this process until no homography can be computed.
  • It may happens that a homography can be found superposed on a previous one using the outliers. You could set Homography->ransacReprojThr (in pixels) higher to accept more inliers in the homographies computed, which would decrease the chance of superposed detections. Another way is to ignore superposed homographies on a specified radius with the parameter General->multiDetectionRadius (in pixels).

For more information see the page below:
https://code.google.com/p/find-object/wiki/MultiDetection

0
votes

I developed a semi-automatic algorithm to detect multiple markers (interest points) from image using findContours method on a binary image (my markers are white on a green surface then I limit my search to area constraint as I know how big is each marker in each frame. of course this got some false positives but it was good enough. I couldn't see the picture in your post as tinypic is blocked here for some reason. But you can use the matchShape opencv function to eliminate the bad contours. here is the part of code I made for this.

Mat tempFrame;
cvtColor(BallFrame, tempFrame, COLOR_BGR2GRAY);
GaussianBlur(tempFrame, tempFrame, Size(15, 15), 2, 2); // remove noise
Mat imBw;
threshold(tempFrame, imBw, 220, 255, THRESH_BINARY); // High threshold to get better results
std::vector<std::vector<Point> > contours;
std::vector<Vec4i> hierarchy;
findContours(imBw, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
Point2f center;
float radius = 0.0;
for (int i = 0; i < contours.size(); i++)
{
    double area = contourArea(contours[i]);
if (area > 1 && area < 4000) {
        minEnclosingCircle(contours[i], center, radius);
        if (radius < 50) // eliminate wide narrow contours
        {
            // You can use `matchShape` here to match your marker shape
        }
    }

}

I hope this will help