我遇到cv :: findEssentialMat()问题,有时返回不正确的基本矩阵。我发现,对于从图像对生成的一组特定的点对应关系,这些对应关系的某些子集(包括整个子集)与OpenCV的五点算法收敛到与正确解决方案截然不同的解决方案。之所以奇怪,是因为每个点的对应都非常相似。换句话说,没有异常值。
查看附件图像,该图像可视化要素如何从先前图像移动到当前图像。蓝色圆圈表示该特征在当前图像中的位置,绿色圆圈表示该特征在前一图像中的位置,红线表示对应关系。所有功能对应关系在相机如何在图像之间移动方面都是一致的。
这是我已经尝试过但没有成功的东西:
我也尝试过运行带有点对应关系子集的cv :: findEssentialMat()。这很有趣,因为某些子集的确会生成正确的基本矩阵,该矩阵是对以下正确转换进行编码的基本矩阵: t〜= [-1 0 0],
但是当使用整套的点对应关系时,我得到这个错误的翻译 t〜= [0 0 -1]
下面是一个最小的工作示例(cpp文件,cmake文件和yaml文件),演示了此问题。只需将程序运行为
./test <numFeaturesToUse>
例如,运行
./test 11
查看cv :: findEssentialMat何时正常运行并运行
的示例./test 12
以查看未收敛到正确解决方案的示例。 如果有人能指出我做错了什么(如果有的话),将不胜感激!
test.cc
#include <opencv2/calib3d.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include <iostream>
typedef std::vector<cv::Point2f> points;
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 2)
{
cout << "Usage: test.cc numFeaturesToUse" << endl;
return 0;
}
int numFeaturesToUse = std::atoi(argv[1]);
// load features as cv::Mats
cv::FileStorage inFile("../features.yaml", cv::FileStorage::READ);
cv::Mat featuresRight_, featuresLeft_;
inFile["featuresRight"] >> featuresRight_;
bool loadFeaturesLeft = true;
if (loadFeaturesLeft)
inFile["featuresLeft"] >> featuresLeft_;
else
{
// each feature in left image should be right feature shifted
// to the right by 100 pixels. This always gets the correct
// answer
featuresLeft_ = featuresRight_.clone();
cv::MatIterator_<cv::Vec2f> featRightIt = featuresRight_.begin<cv::Vec2f>();
cv::MatIterator_<cv::Vec2f> featLeftIt = featuresLeft_.begin<cv::Vec2f>();
while (featRightIt != featuresRight_.end<cv::Vec2f>())
{
(*featLeftIt)[0] += 100;
(*featLeftIt)[1] += -1;
featRightIt++;
featLeftIt++;
}
}
bool useSubset = true;
if (useSubset)
{
int startRow = 20;
cv::Rect roi(0,startRow,1,numFeaturesToUse); // only use N rows of points starting at
featuresRight_ = featuresRight_(roi);
featuresLeft_ = featuresLeft_(roi);
}
// perturb the feature (# 12) that is causing the problem
// manually assign this feature to be shifted version of right feature
// featuresLeft_.at<cv::Vec2f>(11)[0] += 1;
// featuresLeft_.at<cv::Vec2f>(11)[1] += 1;
// featuresRight_.at<cv::Vec2f>(11)[0] += -100;
// featuresRight_.at<cv::Vec2f>(11)[1] += -400;
// featuresRight_.at<cv::Vec2f>(11)[0] = 400.0;
// featuresRight_.at<cv::Vec2f>(11)[1] = 400.0;
// featuresLeft_.at<cv::Vec2f>(11)[0] = featuresRight_.at<cv::Vec2f>(11)[0] + 120;
// featuresLeft_.at<cv::Vec2f>(11)[1] = featuresRight_.at<cv::Vec2f>(11)[1] - 5;
double dsFactor = 0.7;
cout << "Features right \n" << featuresRight_*dsFactor << "\n";
cout << "Features left \n" << featuresLeft_*dsFactor << "\n";
// draw the locations of left and right features on a mat
// left - blue
// right - gold
cv::Mat image = cv::imread("../DJI_0396.JPG");
cv::rotate(image, image, cv::ROTATE_90_COUNTERCLOCKWISE);
cv::Scalar blue(255,0,0);
cv::Scalar green(0,255,0);
cv::Scalar red(0,0,255);
cv::MatIterator_<cv::Vec2f> featRightIt = featuresRight_.begin<cv::Vec2f>();
cv::MatIterator_<cv::Vec2f> featLeftIt = featuresLeft_.begin<cv::Vec2f>();
while(featLeftIt != featuresLeft_.end<cv::Vec2f>())
{
cv::Point2f featureLeft(*featLeftIt);
cv::Point2f featureRight(*featRightIt);
cv::circle(image, featureLeft, 4, blue, -1);
cv::circle(image, featureRight, 4, green, -1); // green
cv::line(
image, // Draw onto this image
featureLeft, // Starting here
featureRight, // Ending here
red, // This color
1, // This many pixels wide
cv::LINE_AA // Draw line in this style
);
featLeftIt++;
featRightIt++;
}
cv::resize(image, image, cv::Size(), dsFactor, dsFactor);
cv::imshow("features", image);
// assign camera matrix
cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) << 1082.77717353143, 0, 690.835449448,
0, 1082.77717353143, 457.750756458,
0, 0, 1 );
bool rotate = true;
if (rotate)
{
double fx,fy,cx,cy;
fx = cameraMatrix.at<double>(0,0);
fy = cameraMatrix.at<double>(1,1);
cx = cameraMatrix.at<double>(0,2);
cy = cameraMatrix.at<double>(1,2);
cameraMatrix.at<double>(0,0) = fy;
cameraMatrix.at<double>(1,1) = fx;
cameraMatrix.at<double>(0,2) = cy;
cameraMatrix.at<double>(1,2) = cx;
}
cout << "camera matrix = " << cameraMatrix << "\n";
assert(featuresLeft_.size() == featuresRight_.size());
// findEssentialMat() settings
double prob = 0.999;
//int method = cv::RANSAC;
int method = cv::LMEDS;
//double threshold = 0.1;
cv::Mat E = cv::findEssentialMat(featuresLeft_, featuresRight_, cameraMatrix,
method, prob);
int totalFeatures = featuresLeft_.rows;
cout << "StereoRig::EstimatePose: Essential matrix = \n" << E << endl;
cv::Mat R_, translation_;
int numInliers = cv::recoverPose(E, featuresLeft_, featuresRight_, cameraMatrix,
R_, translation_); // outputs
cout << "StereoRig::EstimatePose: Number of inliers = " << numInliers << " out of " << totalFeatures << " total features" << endl;
double percentageInliers = (double) numInliers / totalFeatures;
double thresh = 0.6;
if (percentageInliers < thresh)
{
cout << "StereoRig::EstimatePose When estimating pose from feature correspondences, percentage of inliers ("
<< percentageInliers <<") was under the threshold ("<< thresh<<")." << endl;
}
cout << "Estimated translation = " << "\n";
cout << translation_ << "\n";
cv::waitKey(0);
return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
set (CMAKE_CXX_STANDARD 14)
project(test)
# link to opencv build (only look for OpenCV3 not OpenCV2)
find_package( OpenCV 3 REQUIRED)
add_executable (test test.cc)
target_link_libraries (test ${OpenCV_LIBS})
features.yaml
%YAML:1.0
---
featuresLeft: !!opencv-matrix
rows: 92
cols: 1
dt: "2f"
data: [ 1.28847961e+02, 6.49093262e+02, 1.42563141e+02,
6.48662964e+02, 8.19481445e+02, 1.19142212e+03, 7.20055664e+02,
4.70487366e+02, 6.43603821e+02, 3.42356812e+02, 5.35456360e+02,
5.23236694e+02, 1.42560211e+02, 6.48661682e+02, 4.50164185e+02,
9.40511475e+02, 2.87309570e+02, 6.84542358e+02, 8.62315247e+02,
1.20464592e+02, 6.15708496e+02, 2.43555664e+02, 1.30746323e+02,
5.13080139e+02, 8.99102722e+02, 4.01146759e+02, 8.82642578e+02,
4.15881439e+02, 5.71643616e+02, 2.78483398e+02, 6.49876892e+02,
2.69117401e+02, 7.08090027e+02, 6.62893860e+02, 5.65718994e+02,
4.85427002e+02, 6.91666748e+02, 7.81757141e+02, 4.73872772e+02,
5.82393555e+02, 5.19562012e+02, 6.72122650e+01, 4.00382660e+02,
2.22377808e+02, 5.84533264e+02, 5.59183533e+02, 8.66378845e+02,
1.05224136e+02, 5.85873657e+02, 5.71247131e+02, 7.27359497e+02,
5.70056396e+02, 4.35397614e+02, 5.80546875e+02, 6.60823730e+02,
4.31280060e+02, 5.46277710e+02, 3.12825623e+02, 2.92994354e+02,
6.69804443e+02, 3.80915070e+02, 8.45184326e+02, 5.54122681e+02,
1.02158447e+03, 6.66822388e+02, 7.47606018e+02, 7.38320923e+02,
8.25927917e+02, 4.38703217e+02, 1.87555298e+02, 5.21265625e+02,
5.94745789e+02, 6.46222351e+02, 4.89565552e+02, 1.63613831e+02,
4.85208130e+02, 6.58010864e+02, 9.67679749e+02, 6.48694763e+02,
2.37516983e+02, 6.74387329e+02, 4.45746124e+02, 5.88605774e+02,
5.35999390e+02, 6.20808105e+02, 2.63286713e+02, 3.44368896e+02,
6.16288696e+02, 8.03049561e+02, 4.34126892e+02, 2.15325211e+02,
6.25899841e+02, 3.06916382e+02, 4.56520416e+02, 4.95614868e+02,
2.08671097e+02, 5.04676971e+02, 2.67499878e+02, 8.04450867e+02,
2.89448669e+02, 4.97309570e+02, 9.19511292e+02, 5.60559875e+02,
2.56943237e+02, 7.97375488e+02, 6.35597107e+02, 6.99451233e+02,
5.04297241e+02, 5.86292419e+02, 3.40532043e+02, 2.91096863e+02,
4.45543365e+02, 5.34794312e+02, 2.45132690e+02, 5.37259827e+02,
1.69906967e+02, 4.61131104e+02, 9.09794434e+02, 5.24697693e+02,
6.23089355e+02, 6.93494690e+02, 4.19500031e+02, 7.04664429e+02,
2.68480499e+02, 5.59323608e+02, 8.14105797e+00, 7.20533752e+02,
3.91805969e+02, 5.85539246e+02, 5.59671936e+02, 1.54184204e+02,
5.36592224e+02, 5.88363586e+02, 5.00129486e+02, 8.33527039e+02,
2.55457306e+01, 8.96319885e+02, 2.84405151e+02, 8.60649292e+02,
4.74958618e+02, 5.79110352e+02, 5.90250793e+02, 7.92708252e+02,
1.42511322e+02, 8.60564697e+02, 4.74950104e+02, 6.75626709e+02,
3.95321686e+02, 6.55555237e+02, 9.86767151e+02, 4.55710693e+02,
2.07409485e+02, 3.31513824e+02, 5.55117981e+02, 7.90092773e+02,
4.63523285e+02, 1.76062378e+02, 6.18713623e+02, 6.79687073e+02,
4.40630096e+02, 2.76415710e+02, 7.01047546e+02, 6.20903625e+02,
8.57159729e+02, 5.22285217e+02, 5.58501221e+02, 3.54970581e+02,
5.74421875e+02, 4.79196747e+02, 6.09657288e+02, 8.84093750e+02,
1.07693872e+03, 6.33823853e+02, 8.33315430e+02, 2.37912460e+02,
4.43286407e+02, 6.88389404e+02, 4.36370270e+02, 8.40665222e+02,
3.36497498e+02, 1.77658432e+02, 5.66718872e+02, 7.55319702e+02,
7.37769318e+00 ]
featuresRight: !!opencv-matrix
rows: 92
cols: 1
dt: "2f"
data: [ 3.48587513e+00, 6.54300903e+02, 2.16347313e+01,
6.53776978e+02, 6.97840149e+02, 1.19988525e+03, 5.98826782e+02,
4.76740784e+02, 5.22565491e+02, 3.47719086e+02, 4.13773651e+02,
5.28816528e+02, 2.16297665e+01, 6.53775146e+02, 3.28051147e+02,
9.46521362e+02, 1.65979507e+02, 6.89732117e+02, 7.42543884e+02,
1.25529305e+02, 4.94935944e+02, 2.49277206e+02, 1.01769810e+01,
5.18613708e+02, 7.78789978e+02, 4.06911591e+02, 7.62147339e+02,
4.21893127e+02, 4.50675201e+02, 2.84116882e+02, 5.28738892e+02,
2.74634521e+02, 5.86458496e+02, 6.69662903e+02, 4.44102234e+02,
4.91375946e+02, 5.69598328e+02, 7.88479553e+02, 3.52315247e+02,
5.88038025e+02, 3.99272858e+02, 7.24335175e+01, 2.79831665e+02,
2.27995819e+02, 4.62965271e+02, 5.65336975e+02, 747., 110., 464.,
577., 6.05831604e+02, 5.76349426e+02, 3.13826538e+02,
5.86211914e+02, 5.39379211e+02, 4.37007294e+02, 4.25307678e+02,
3.18409332e+02, 1.71548569e+02, 6.75439392e+02, 2.59090179e+02,
8.50806824e+02, 4.32000031e+02, 1.02846155e+03, 5.44752502e+02,
7.53849792e+02, 6.16563049e+02, 8.33063477e+02, 3.18476013e+02,
1.92946686e+02, 3.99383270e+02, 6.00583191e+02, 5.24528076e+02,
4.95570587e+02, 4.31030235e+01, 4.90446259e+02, 5.36113647e+02,
9.74736084e+02, 5.28095642e+02, 2.43140930e+02, 5.53183777e+02,
4.52007416e+02, 4.66995789e+02, 5.41647949e+02, 4.99978821e+02,
2.68422241e+02, 223., 622., 6.82151550e+02, 4.39999298e+02,
9.44022217e+01, 6.31038269e+02, 186., 462., 3.75099762e+02,
2.14107742e+02, 3.83958862e+02, 2.73195770e+02, 6.83860474e+02,
2.95132202e+02, 3.75323700e+02, 9.25819702e+02, 4.40014893e+02,
2.62267639e+02, 6.75859680e+02, 6.42131897e+02, 5.78106018e+02,
5.10620270e+02, 4.65280518e+02, 3.46075043e+02, 1.70320724e+02,
4.50776031e+02, 4.13994263e+02, 2.50434418e+02, 417., 175.,
3.39066467e+02, 9.16131042e+02, 4.02902557e+02, 6.29403015e+02,
5.72313904e+02, 4.25308411e+02, 5.84261230e+02, 2.73812378e+02,
4.39524597e+02, 1.32251701e+01, 5.99402161e+02, 3.97848175e+02,
4.63748627e+02, 5.65522583e+02, 3.37356911e+01, 5.41680481e+02,
4.66630371e+02, 5.05906525e+02, 714., 30., 7.76105896e+02,
2.89903259e+02, 7.40108154e+02, 4.80904846e+02, 4.57319580e+02,
5.96026062e+02, 673., 148., 7.40087891e+02, 4.81301239e+02,
5.54387695e+02, 4.01024597e+02, 5.33782959e+02, 9.94106750e+02,
3.35050629e+02, 2.12548187e+02, 2.10056046e+02, 5.60611633e+02,
6.69055542e+02, 4.69386414e+02, 5.54003754e+01, 6.23763367e+02,
5.58282837e+02, 4.46638702e+02, 1.54980133e+02, 7.06359802e+02,
4.98765839e+02, 8.63861084e+02, 4.00624634e+02, 5.64329407e+02,
2.33481201e+02, 5.79876953e+02, 3.57501984e+02, 6.15616211e+02,
7.62703003e+02, 1.08548193e+03, 5.11708618e+02, 8.40311646e+02,
1.17268921e+02, 4.48423584e+02, 5.66531982e+02, 4.42379242e+02,
7.20351318e+02, 3.42316284e+02, 57., 572., 6.35811890e+02,
1.21897068e+01 ]