solvePnP函数崩溃

时间:2014-07-22 10:25:51

标签: opencv image-processing runtime-error kinect

我已经在网上搜索了所有答案,但是我无法找到问题的答案,所以我在这里发帖。

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

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 ++异常:cv ::内存位置0x0015b800的异常。

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

UPDATE:我发现内在函数和失真矩阵没有正确加载。我一直在查看对象和场景矩阵。我使用断点检查了矩阵值,两者都是它们显示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();
  

任何人都可以帮助我。我所知道的一切似乎都是正确的,在这里,在这段代码中。我应该在代码中包含其他内容以使其有效吗?

1 个答案:

答案 0 :(得分:2)

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

所以代码片段是:

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 [&#34;内在&#34;] 中的内在相同的名称你校准和保存矩阵的地方。例如,在校准后,请将其保存为:

    FS&LT;&LT;&#34;的&#34;&LT;

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