【问题标题】:solvePnP function crashes解决即插即用功能崩溃
【发布时间】:2014-07-22 22:17:52
【问题描述】:

我在网上和 SO 上到处搜索这个答案,但我找不到我的问题的答案,所以我把它贴在这里。

我正在尝试使用 solvePnP 函数通过获取 rvecstvecs 来查找两个图像之间的相对相机位姿。我这里是这两个图像的链接. refernce image ,query image. 我已经检测并匹配了关键点,并将它们存储在矢量 Point3f(参考图像的二维坐标+深度)和矢量 Point2f(环境中查询图像的二维坐标)中。我已经有了相机的相机内在函数和失真矩阵。这是我使用的代码sn-ps。

drawMatches(fin,keypoints_1,fin1,keypoints_2,good_matches,Img_matches,Scalar::all(-1),vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
imshow("mm",img_matches);
vector<Point2f> obj;
vector<Point2f> scene;
vector<Point3f> obj1;
 for( int i = 0; i <good_matches.size(); i++ )
{
obj.push_back( keypoints_1[ good_matches[i].queryIdx ].pt);
 scene.push_back( keypoints_2[ good_matches[i].trainIdx ].pt );}

for( int i = 0; i < obj.size(); i++ )  
{raw=depth.at<unsigned char>(int(obj[i].x),int(obj[i].y));
distan=(raw*1798)/255;//this is just to get the actual distance of a point in a depth image
obj1.push_back(Point3f(int(obj[i].x),int(obj[i].y),distan));}//transfering to a Point3f vector.

Mat H = findHomography( obj, scene, CV_RANSAC );
solvePnP(obj1,scene,intrinsics,distortion,rvec,tvec);

注意:向量 obj1 中的点比通常的 4 对多。这会产生问题吗?

我遇到的问题是运行时错误:

test.exe 中 0x75dc812f (KernelBase.dll) 处未处理的异常:Microsoft C++ 异常:内存位置 0x0015b800 处的 cv::Exception。

我从之前校准的 xml 配置文件中获得了相机矩阵

更新:我发现内在函数和失真矩阵没有正确加载。我一直在浪费时间查看对象和场景矩阵。我使用断点检查了矩阵值它们显示 0 列和行。我认为矩阵在校准期间没有正确存储,我检查了 xml 文件;但它们有数据。这是我用来将矩阵传输到程序中的一段代码。

Mat intrinsics;
Mat distortion;
FileStorage fsIntrinsic("intrinsics.xml", FileStorage::READ); 
fsIntrinsic["intrinsics"] >> intrinsics;
FileStorage fsDistortion("distortion.xml", FileStorage::READ);
fsDistortion["distortion"] >> distortion;
if(!fsInrinsic.isOpened())
return -1;
if(!fsDistortion.isOpened())
return -1;
fsIntrinsic.release();
fsDistortion.release();

谁能帮帮我。我所知道的一切似乎都是正确的,在这里,在这段代码中。我应该在代码中包含其他内容以使其工作吗?

【问题讨论】:

    标签: opencv image-processing runtime-error kinect


    【解决方案1】:

    我终于设法消除了对这个问题的疑虑。通过断点分析,我发现内在矩阵已正确加载,但失真系数矩阵显示零列和行。一个基本错误是我初始化了 2 个文件存储变量,一次只能使用一个(即在使用 .release() 函数释放一个之后。

    所以代码 sn-p 将是:

    fsIntrinsic.release();//releasing the first filestorage variable.
    FileStorage fsDistortion("distortion.xml", FileStorage::READ);
    .
    .
    .
    fsDistortion.release();
    

    但这是一项乏味的任务,因此我将内在函数和失真系数矩阵存储到同一个文件中,并使用相同的文件存储变量访问它们,如下所示:

    FileStorage fs("intrinsicsdist.xml", FileStorage::READ);
    fs["intrinsic"]>>intrinsics;
    fs["dist"]>>distortion;
    fs.release();
    

    注意:

    1. 请经常检查文件是否打开以及矩阵是否正确加载。可以使用.isOpened()函数检查文件打开情况。
    2. 请始终记住在您校准和保存矩阵的代码中的 fs["intrinsic"] 中的方括号内放入相同的名称。例如说校准后将其另存为:

      fs内在"

    当您将矩阵读入程序时,粗体字应该相同。 我浪费了很多时间来忽略这条信息。干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      相关资源
      最近更新 更多