Как измерить угол прямоугольного маркера на вращающейся плоскости с помощью угловой камеры?

Я разрабатываю приложение. В этом приложении есть прямоугольный красный объект на вращающейся плоской поверхности. Я могу точно обнаружить этот красный объект. Я поворачиваю его на 10 градусов и измеряю, сколько градусов камера делает снова и снова. Но я видел широкий разброс значений углов, которые я измерил, когда камера смотрела под углом к ​​поверхности.

Я использовал openHv методы findHomography () и warpPerspective (), чтобы исправить это, но я не получил точного результата, который хотел. Потому что эти два метода после того, как взять 4 очка и вставить эти точки всегда в ту же точку, которую я определил.

Интересно, если бы мы могли сделать что-то подобное в соответствии с углом, под которым смотрит камера, вы можете исправить форму прямоугольника со всем изображением, например, края прямоугольника могут быть заданы в «A» градусах от x, «B» градусов от y и «C» градусов от z, но будет ли он также поддерживать угол обзора камеры? Тогда я буду измерять угол в выпрямленном прямоугольнике. Короче говоря, мне нужно исправить прямоугольник в соответствии с углом наклона камеры и измерить угол наклона прямоугольника относительно камеры. Но я не знаю, как далеко стоит камера. Я должен сделать это на всей картине, а не на одном объекте ..

Спасибо за помощь…

Я поделюсь некоторым кодом и изображениями

`for (int getKey = 0; getKey < 36; getKey++)
{
ret = turnMotor("btnSetActPosZero", "true");
Sleep(1000);

ret = turnMotor("btnAbsMove", "true");
Sleep(3000);for (int imageCnt = 0; key != 'q', imageCnt < dongu; imageCnt++)
{
// Get the image
Image rawImage;
t_error = t_camera.RetrieveBuffer(&rawImage);
if (t_error != PGRERROR_OK) { t_error.PrintErrorTrace(); return -1; }

Image rgbImage;
rawImage.Convert(FlyCapture2::PIXEL_FORMAT_BGR, &rgbImage);

cv::Mat imageUndistorted;
unsigned int rowBytes = (double)rgbImage.GetReceivedDataSize() / (double)rgbImage.GetRows();
cv::Mat image = cv::Mat(rgbImage.GetRows(), rgbImage.GetCols(), CV_8UC3, rgbImage.GetData(), rowBytes);
cv::Mat res = image.clone();

cv::initUndistortRectifyMap(intrinsic, distCoeffs, cv::Mat(), intrinsic, cv::Size(image.cols, image.rows), CV_32FC1, map1, map2);
cv::remap(image, imageUndistorted, map1, map2, cv::INTER_CUBIC);
cv::Mat imageI = cv::Mat(imageUndistorted, bbox);

// Split eye image into 3 channels.
vector<Mat>bgr(3);
split(imageI, bgr);

float angleRefAngleKirmizi = 0.0;

{
cv::Mat mask = (bgr[0] > 160) & (bgr[1] > 175);
vector<vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;

cv::Mat maskRedBefore = (bgr[2] > 175);

Mat maskRed = maskRedBefore - mask;
int index = 0;
for (int i = 0; i < 4; i++)
{
index = 0;
findContours(maskRed, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
if (contours.size() == 0) { return -1; };

double maxArea = contourArea(contours[0]);
int index = 0;
for (int i = 0; i < contours.size(); i++)
{
if (contourArea(contours[i]) > maxArea) {
maxArea = contourArea(contours[i]);
index = i;
}
}
floodFill(maskRed, Point(0, 0), Scalar(255, 255, 255));
drawContours(maskRed, contours, index, cv::Scalar(0, 255, 0), 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
floodFill(maskRed, contours[index][int(contours[index].size() / 2)], Scalar(0, 0, 0));
floodFill(maskRed, Point(0, 0), Scalar(0, 0, 0));

}

Mat mask2;
cv::Vec4f myLine;
vector<cv::Point> nonZeroCoordinates;
cv::findNonZero(maskRed, nonZeroCoordinates);

if (nonZeroCoordinates.size() != 0)
{
cv::fitLine(nonZeroCoordinates, myLine, CV_DIST_L2, 0, 0.01, 0.01);
angleRefAngleKirmizi = atan2(myLine[1], myLine[0]) < 0 ? atan2(myLine[1], myLine[0]) + CV_PI : atan2(myLine[1], myLine[0]);

cv::putText(imageI, to_string(angleRefAngleKirmizi * 180 / CV_PI), cv::Point(myLine[2], myLine[3]), cv::FONT_HERSHEY_SCRIPT_SIMPLEX, 0.3, cvScalar(0, 255, 255), 1, CV_AA);
line(imageI, cv::Point(myLine[2], myLine[3]), cv::Point(myLine[2] + myLine[0] * 100, myLine[3] + myLine[1] * 100), cv::Scalar(255, 0, 0), 1, 8);

out_transform << to_string(angleRefAngleKirmizi * 180 / CV_PI) << endl;
}

}

imshow("image", imageI);
key = cv::waitKey(1);
}
`

и составные изображения прямоугольника моделируются в некоторых отношениях n.показано, что изображение сочетания прямоугольника под некоторыми углами и вращающееся шоу плоской поверхностивращающаяся плоская поверхность

а также добавить код, который делает два метода opencv.

            vector<cv::Point2d> approx;
approxPolyDP(cv::Mat(contours[index]), approx, 3, true);

if (approx.size() == 0) return -14;
for (int j = 0; j < approx.size(); j++)
{
cv::putText(imageI, to_string(j), approx[j], cv::FONT_HERSHEY_SCRIPT_SIMPLEX, 0.6, cvScalar(0, 0, 0), 1, CV_AA);
line(imageI, approx[j], approx[(j+1)% approx.size()], cv::Scalar(0, 0, 0), 1, 8);

}vector<Point2f> pts_src;
pts_src.push_back(Point2f(0, 0));
pts_src.push_back(Point2f(80, 0));
pts_src.push_back(Point2f(80, 30));
pts_src.push_back(Point2f(0, 30));// Calculate Homography between source and destination points
Mat h = findHomography(approx, pts_src);

// Warp source image
warpPerspective(imageI, HomogImage, h, HomogImage.size(), CV_INTER_LINEAR);

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]