首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法用ArUco 3.1.0检测OpenCV标记

无法用ArUco 3.1.0检测OpenCV标记
EN

Stack Overflow用户
提问于 2017-07-26 12:17:33
回答 1查看 3.2K关注 0票数 0

我试图编写一个简单的C++例程,首先将ArUco标记的预定义字典(例如4x4_100)写到文件夹中,然后使用OpenCV 3.1和VisualStudio2017在从文件夹中选择的特定图像中检测ArUco标记。我已经编译了所有使用ArUco标记所需的OpenCV--控制库。我的例程构建没有任何错误,但即使在提供了所有正确的参数(如图像、字典等)之后,我也很难检测到标记。内置的“aruco::检测标记”函数。你能帮我理解一下我的方法有什么问题吗?下面是一个最小的工作示例,测试映像附在40.jpg“之后

代码语言:javascript
复制
#include "opencv2\core.hpp"
#include "opencv2\imgproc.hpp"
#include "opencv2\imgcodecs.hpp"
#include "opencv2\aruco.hpp"
#include "opencv2\highgui.hpp"
#include <sstream>
#include <fstream>
#include <iostream>

using namespace cv;
using namespace std;

// Function to write ArUco markers
void createArucoMarkers()
{

// Define variable to store the output markers
    Mat outputMarker;
// Choose a predefined Dictionary of markers
    Ptr< aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);
// Write each of the markers to a '.jpg' image file
    for (int i = 0; i < 50; i++)
    {
        aruco::drawMarker(markerDictionary, i, 500, outputMarker, 1);
        ostringstream convert;
        string imageName = "4x4Marker_";
        convert << imageName << i << ".jpg";
        imwrite(convert.str(), outputMarker);

    }
}


// Main body of the routine
int main(int argv, char** argc)
{
    createArucoMarkers();

// Read a specific image
    Mat frame = imread("4x4Marker_40.jpg", CV_LOAD_IMAGE_UNCHANGED);
// Define variables to store the output of marker detection
    vector<int> markerIds;
    vector<vector<Point2f>> markerCorners, rejectedCandidates;
// Define a Dictionary type variable for marker detection  
    Ptr<aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);

// Detect markers
    aruco::detectMarkers(frame, markerDictionary, markerCorners, markerIds);

// Display the image
    namedWindow("Webcam", CV_WINDOW_AUTOSIZE);
    imshow("Webcam", frame);
// Draw detected markers on the displayed image
    aruco::drawDetectedMarkers(frame, markerCorners, markerIds);
    cout << "\nmarker ID is:\t"<<markerIds.size();
    waitKey();

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-26 17:16:48

在您的代码中有一些问题:

  1. 在调用imshow之前,您将使用drawDetectedMarkers显示图像,因此您将永远看不到检测到的标记。
  2. 您显示的是markerIds向量的大小,而不是其中包含的值。
  3. (这是主要的问题)您的标记周围没有空白,因此不可能检测到。

一个建议是:在#include语句中使用正斜杠,而不是反斜杠。正斜杠在任何地方都能工作,反斜杠只在Windows上工作。

这在我的机器上有效。请注意,我将图像作为彩色图像加载,以便更容易地查看drawDetectedMarkers的结果。

代码语言:javascript
复制
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/highgui.hpp>
#include <sstream>
#include <fstream>
#include <iostream>

using namespace cv;
using namespace std;

// Function to write ArUco markers
void createArucoMarkers()
{

    // Create image to hold the marker plus surrounding white space
    Mat outputImage(700, 700, CV_8UC1);
    // Fill the image with white
    outputImage = Scalar(255);
    // Define an ROI to write the marker into
    Rect markerRect(100, 100, 500, 500);
    Mat outputMarker(outputImage, markerRect);

    // Choose a predefined Dictionary of markers
    Ptr< aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);
    // Write each of the markers to a '.jpg' image file
    for (int i = 0; i < 50; i++)
    {
        //Draw the marker into the ROI
        aruco::drawMarker(markerDictionary, i, 500, outputMarker, 1);
        ostringstream convert;
        string imageName = "4x4Marker_";
        convert << imageName << i << ".jpg";
        // Note we are writing outputImage, not outputMarker
        imwrite(convert.str(), outputImage);

    }
}


// Main body of the routine
int main(int argv, char** argc)
{
    createArucoMarkers();

    // Read a specific image
    Mat frame = imread("4x4Marker_40.jpg", CV_LOAD_IMAGE_COLOR);
    // Define variables to store the output of marker detection
    vector<int> markerIds;
    vector<vector<Point2f>> markerCorners, rejectedCandidates;
    // Define a Dictionary type variable for marker detection
    Ptr<aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);

    // Detect markers
    aruco::detectMarkers(frame, markerDictionary, markerCorners, markerIds);

    // Display the image
    namedWindow("Webcam", CV_WINDOW_AUTOSIZE);
    // Draw detected markers on the displayed image
    aruco::drawDetectedMarkers(frame, markerCorners, markerIds);
    // Show the image with the detected marker
    imshow("Webcam", frame);

    // If a marker was identified, show its ID
    if (markerIds.size() > 0) {
        cout << "\nmarker ID is:\t" << markerIds[0] << endl;
    }
    waitKey(0);

}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45326773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档