我有一个程序来绘制和检测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;
}
}
}
用于简化代码测试的示例标记。
使用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
我还没有编译这段代码,仅仅是概念。