【问题标题】:Unable to detect ArUco markers with OpenCV 3.1.0无法使用 OpenCV 3.1.0 检测 ArUco 标记
【发布时间】:2018-01-01 18:22:30
【问题描述】:

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

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

}

【问题讨论】:

    标签: c++ opencv visual-c++ opencv3.1 aruco


    【解决方案1】:

    你的代码有几个问题:

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

    一个建议:在#include 语句中使用正斜杠,而不是反斜杠。正斜杠适用于任何地方,反斜杠仅适用于 Windows。

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

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

    【讨论】:

    • 成功了,史蒂夫!我还记录了您关于使用正斜杠的建议。我刚刚开始使用 C++ 进行编码,并且正在努力检测给定图像中的多个 ArUco 标记。如果我有其他疑问,会回复你们。 TC。
    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多