【问题标题】:OpenCV Multiple marker detection?OpenCV多标记检测?
【发布时间】:2015-04-09 02:02:58
【问题描述】:

我一直致力于检测场景中的基准标记。我的基准标记的一个例子在这里: http://tinypic.com/view.php?pic=4r6k3q&s=8#.VNgsgzVVK1F

我已经能够很好地检测场景中的单个基准标记。在一个场景中检测多个基准标记的方法是什么?进行特征检测、提取和匹配非常适合找到单个匹配项,但它似乎是检测多个匹配项的错误方法,因为很难确定哪些特征属于哪个标记?

基准标记将是相同的,并且不会位于场景中的已知位置。

更新:

下面是一些示例代码。我试图将第一个基准标记与 x 个关键点进行匹配,然后使用剩余的关键点匹配第二个标记。但是,这根本不可靠。有人有什么建议吗?

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 );

【问题讨论】:

  • 在此处查看我的答案:stackoverflow.com/questions/28407828/… 这对您来说可能是个不错的解决方案。
  • 感谢您的意见。从表面上看,我不知道如何将您的答案应用于我的问题,但我会进一步探索。

标签: opencv computer-vision


【解决方案1】:

我开发了一种半自动算法,在二值图像上使用findContours 方法从图像中检测多个标记(兴趣点)(我的标记在绿色表面上是白色的,然后我将搜索限制在区域约束中,因为我知道如何big 是每一帧中的每个标记。当然,这有一些误报,但已经足够好了。我看不到你帖子中的图片,因为由于某种原因,tinypic 在这里被阻止了。但你可以使用matchShape opencv 函数消除不良轮廓。 这是我为此编写的部分代码。

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
        }
    }

}

我希望这会有所帮助

【讨论】:

    【解决方案2】:

    我以前从未尝试过,但这里你对检测多次出现有一个很好的解释:

    本教程展示了如何启用相同的多重检测 目的。要启用多重检测,参数 General-&gt;multiDetection 应该被检查。方法如下 以下:

    • 像往常一样,我们匹配对象和场景之间的所有特征。
    • 对于在场景中出现两次(或更多)的对象,它应该具有两次匹配的特征。我们应用 RANSAC 算法来找到一个 单应性。内点应该只属于 对象,所有其他都被视为异常值。我们重做单应性 处理异常值,然后找到另一个单应性……我们这样做 直到无法计算出单应性为止。
    • 使用异常值可能会发现单应性叠加在前一个单应性上。你可以设置 Homography-&gt;ransacReprojThr(以像素为单位)更高以接受更多 计算的单应性中的内点,这将减少机会 的叠加检测。另一种方法是忽略叠加 参数General-&gt;multiDetectionRadius(以像素为单位)在指定半径上的单应性。

    欲了解更多信息,请参阅以下页面:
    https://code.google.com/p/find-object/wiki/MultiDetection

    【讨论】:

    • 这很有趣。它看起来与我正在尝试做的非常相似。正在调整他们的代码。
    猜你喜欢
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 2021-06-09
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多