0

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

}
4

1 回答 1

4

你的代码有几个问题:

  1. imshow在调用之前显示图像,drawDetectedMarkers因此您永远不会看到检测到的标记。
  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);

}
于 2017-07-26T17:16:48.430 回答