Я пытаюсь написать простую подпрограмму на C ++, чтобы сначала записать предопределенный словарь маркеров ArUco (например, 4x4_100) в папку, а затем обнаружить маркеры ArUco на определенном изображении, выбранном из папки, используя OpenCV 3.1 и Visual Studio 2017. Я скомпилировал все библиотеки OpenCV-contrib, необходимые для использования маркеров ArUco. Моя процедура собирается без каких-либо ошибок, но у меня возникают проблемы с обнаружением маркеров даже после предоставления всех правильных аргументов (например, изображения, словаря и т. Д.) Встроенной функции «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();
}
В вашем коде есть несколько проблем:
imshow
перед звонком drawDetectedMarkers
так что вы никогда не увидите обнаруженный маркер.markerIds
вектор вместо значения, содержащегося в нем.Одно из предложений: используйте прямые, а не обратные сле #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);
}
Других решений пока нет …