如何在opencv的Aruco标记上绘制矩形?

问题描述 投票:0回答:1

我有一个程序来绘制和检测aruco标记,并在其上写下标记ID。我需要一个矩形而不是标记id出现在每个标记上,我可以绘制一个矩形,但不在标记上的固定位置,这是代码:

#include <opencv2\highgui.hpp>
#include <opencv2\aruco.hpp>
#include <opencv2\core.hpp>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\imgproc.hpp>
#include <opencv2\calib3d.hpp>
#include <sstream>
#include <fstream>
#include <iostream>
using namespace cv;
using namespace std;


int main(int argc, char *argv[]) {
    cv::VideoCapture inputVideo;
    inputVideo.open(0);
    Mat outputMarker;
    auto  markerDict = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);
    for (int i = 0; i < 50; i++) {
        aruco::drawMarker(markerDict, i, 500, outputMarker, 1);
        ostringstream convert;
        String imageName = "4x4marker_";
        convert << imageName << i << ".jpg";
        imwrite(convert.str(), outputMarker);

        while (inputVideo.grab()) {
            cv::Mat image, imageCopy;
            inputVideo.retrieve(image);
            image.copyTo(imageCopy);

            std::vector<int> ids;
            std::vector<std::vector<cv::Point2f> > corners;
            cv::aruco::detectMarkers(image, markerDict, corners, ids);

            // if at least one marker detected
            if (ids.size() > 0)
                cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);
            int x = 0;
            int y = 3;


            rectangle(imageCopy, Point(imageCopy.cols/2, imageCopy.rows/2),
                Point(x,y),Scalar::all(255), -1, 8, 0);



            cv::imshow("out", imageCopy);
            char key = (char)cv::waitKey(5);
            if (key == 27)
                break;
        }
    }
}

用于简化代码测试的示例标记。

Here

c++ opencv draw aruco
1个回答
0
投票

使用detectMarkers功能时,它会返回每个检测的角点。在您的情况下,您要将其放入detectMarkers。要绘制矩形,您可以执行以下操作:

std::vector<std::vector<cv::Point2f> > corners

但是,您可能希望绘制一个更适合标记的多边形,因为如果标记不完全垂直于相机光轴并且没有扭曲,则图像上的标记投影将不是矩形。为此,您可以使用for (size_t i = 0; i< corners.size(); +i) { cv::Point2f p0(image.cols,image.rows); cv::Ponit2f p1(0,0); for (auto p: corners[i]) { if (p.x < p0.x) p0.x = p.x; if (p.y < p0.y) p0.y = p.y; if (p.x > p1.x) p1.x = p.x; if (p.y > p1.y) p1.y = p.y; } rectangle(imageCopy, p0, p1,Scalar::all(255), -1, 8, 0); } ,或者如果您不希望它填充fillPoly

您可以使用填充多边形,如:

fillPoly

我还没有编译这段代码,仅仅是概念。

© www.soinside.com 2019 - 2024. All rights reserved.