【发布时间】:2016-05-09 14:09:21
【问题描述】:
我正在开展一个使用光流技术估计无人机(四轴飞行器)位置的项目。我目前有一个使用 OpenCV 的 farneback 算法的代码。当相机始终指向地面时,当前代码工作正常。
现在,我想在相机未指向正下方的情况下添加支持 - 这意味着四轴飞行器现在具有俯仰/滚动/偏航(欧拉角)。四轴飞行器欧拉角是已知的,我正在寻找一种方法来计算和应用基于已知的当前欧拉角所需的变换。这样结果图像就好像是从上面拍摄的一样(见下图)。
我通过来自 OpenCV 的 findHomography 或 getPerspectiveTransform 函数找到了在具有 4 个角的 2 组(源和目标)时计算转换的方法。但是我找不到任何方法可以只知道欧拉角(因为我不知道目标图像核心)。
所以我的问题是我可以使用什么方法以及如何将帧转换为好像它是从上面拍摄的,如果需要的话,只使用欧拉角和相机距地面的高度?
为了展示我的需要:
我当前代码的相关部分如下:
for(;;)
{
Mat m, disp, warp;
vector<Point2f> corners;
// take out frame- still distorted
cap >> origFrame;
// undistort the frame using the calibration parameters
cv::undistort(origFrame, undistortFrame, cameraMatrix, distCoeffs, noArray());
// lower the process effort by transforming the picture to gray
cvtColor(undistortFrame, gray, COLOR_BGR2GRAY);
if( !prevgray.empty() )
{
// calculate flow
calcOpticalFlowFarneback(prevgray, gray, uflow, 0.5, 3/*def 3 */, 10/* def 15*/, 3, 3, 1.2 /* def 1.2*/, 0);
uflow.copyTo(flow);
// get average
calcAvgOpticalFlow(flow, 16, corners);
// calculate range of view - 2*tan(fov/2)*distance
rovX = 2*0.44523*distanceSonar*100; // 2 * tan(48/2) * dist(cm)
rovY = 2*0.32492*distanceSonar*100; // 2 * tan(36/2) * dist(cm)
// calculate final x, y location
location[0] += (currLocation.x/WIDTH_RES)*rovX;
location[1] += (currLocation.y/HEIGHT_RES)*rovY;
}
//break conditions
if(waitKey(1)>=0)
break;
if(end_run)
break;
std::swap(prevgray, gray);
}
更新:
成功添加旋转后,我仍然需要将图像居中(并且不要超出框架窗口,如下所示)。我想我需要某种翻译。 我希望源图像的中心位于目标图像的中心。我该如何添加它?
有效的旋转功能:
void rotateFrame(const Mat &input, Mat &output, Mat &A , double roll, double pitch, double yaw){
Mat Rx = (Mat_<double>(3, 3) <<
1, 0, 0,
0, cos(roll), -sin(roll),
0, sin(roll), cos(roll));
Mat Ry = (Mat_<double>(3, 3) <<
cos(pitch), 0, sin(pitch),
0, 1, 0,
-sin(pitch), 0, cos(pitch));
Mat Rz = (Mat_<double>(3, 3) <<
cos(yaw), -sin(yaw), 0,
sin(yaw), cos(yaw), 0,
0, 0, 1);
Mat R = Rx*Ry*Rz;
Mat trans = A*R*A.inv();
warpPerspective(input, output, trans, input.size());
}
当我使用rotateFrame(origFrame, processedFrame, cameraMatrix, 0, 0, 0); 运行它时,我得到了预期的图像:
但是当我以 10 度滚动运行它时 rotateFrame(origFrame, processedFrame, cameraMatrix, 20*(M_PI/180), 0, 0);。图像超出框架窗口:
【问题讨论】:
-
"OpenCV 中的 FindHomography 或 getPerspectiveTransform 函数。但是没有一个在不知道角位置但已知角度的情况下这样做" 你确定它们不适用于角位置吗?因为我使用四个角进行转换
-
不够清楚,我已经编辑了我的帖子。我的意思是我不知道目标角,但我确实知道欧拉角。
标签: c++ opencv image-processing computer-vision image-rotation