Я занимаюсь разработкой приложения.В этом приложении есть прямоугольный красный объект на вращающейся плоской поверхности.Я могу точно обнаружить этот красный объект.Я поворачиваю его на 10 градусов и измеряю, сколько градусов камера делает снова и снова. Но я видел широкий разброс значений углов, которые я измерил, когда камера смотрела под углом к поверхности.
Я использовал openCv методы 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);
}
`
и составные изображения прямоугольника смоделированы в некоторых отношениях. показано, что сочетание изображений прямоугольника под некоторыми углами и вращающейся плоской поверхности показывают вращающейся плоской поверхности
, а также добавить код, который выполняет два метода 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);