本文介绍了如何在emgu CV中进行相机校准后访问旋转和平移向量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 相机校准的目标是找到内在和外在参数: 内在的是那些描述相机本身(焦点长度,失真等)我得到的值,没有问题。 外部参数基本上是相机的位置。当我尝试访问那些我获得 c 我放置了一个断点,发现内部 Data 属性 null 。查看VS调试程序的屏幕截图: 这解释为什么我不能访问它。 解决方案 div> 这是因为EmguCV中的错误。您正在呼叫 public static double CalibrateCamera( MCvPoint3D32f [] [] objectPoints, PointF [] [] imagePoints, SizeSize, IInputOutputArray cameraMatrix, IInputOutputArray distortionCoeffs, CvEnum.CalibType calibrationType, MCvTermCriteria termCriteria, out Mat [] rotationVectors , out Mat [] translationVectors) p> public static double CalibrateCamera( IInputArray objectPoints, IInputArray imagePoints, Size imageSize, IInputOutputArray cameraMatrix, IInputOutputArray distortionCoeffs, IOutputArray rotationVectors, IOutputArray translationVectors, CvEnum.CalibType flags, MCvTermCriteria termCriteria) IOutputArray rotationVectors 应复制到 Mat [] rotationVectors 。翻译中的同样的事情。问题出在此循环。 有 for(int i = 0; i< ; imageCount; i ++) { rotationVectors [i] = new Mat(); 使用(Mat matR = rotationVectors [i])// matR.CopyTo(rotationVectors [i]); translationVectors [i] = new Mat(); using(Mat matT = translationVectors [i])//< - bug matT.CopyTo(translationVectors [i]); } ,应该有 for(int i = 0; i { rotationVectors [i] = new Mat using(Mat matR = rVecs [i]) matR.CopyTo(rotationVectors [i]); translationVectors [i] = new Mat(); using(Mat matT = tVecs [i]) matT.CopyTo(translationVectors [i]); } 最后,要获取旋转和翻译值,您可以使用 DataPointer var rotation = new Matrix< float>(rotationVectors [0] rotationVectors [0] .Cols,rotationVectors [0] .DataPointer); The goal of a camera calibration is to find the intrinsic and extrinsic parameters:The intrinsic ones are those that describe the camera itself (focallength, distortion, etc.) I get values for those, no problem.The extrinsic parameters are basically the position of the camera. When I try to access those I get an AccessViolationException.One way to perform such calibration is totake an image of a calibration target with known cornersfind those corners in the imagefrom the correspondence between 3D and 2D points, find the matrix that transforms one into the otherthat matrix consists of the intrinsic and extrinsic parameters.The call to the calibration function looks like this:Mat[] rotationVectors = new Mat[1];Mat[] translationVectors = new Mat[1];double error = CvInvoke.CalibrateCamera(realCorners, detectedCorners, calibrationImages[0].Image.Size, cameraMatrix, distortionCoefficients, 0, new MCvTermCriteria(30, 0.1), out rotationVectors, out translationVectors);Console.WriteLine(rotationVectors[0].Size); // AccessViolationExceptionI only use one image here, but I have the same problem when using more images (30) Different calibration images would yield different results for translation-/rotationVector anyway, which makes me doubt that using only 1 image is a problem.The detection of points works and drawing them into the original image gives reasonabel results.Both cameraMatrix and distortionCoefficients can be accessed and contain values. (I tried to only post the relevant parts of the code)I use emgu version 3.0.0.2157Why do I get an AccessViolationException on the rotationVectors and translationVectors?I placed a breakpoint and found that the internal Data property is null. See screenshot of VS debugger:That explains why I cannot access it. But why is it null in the first place? 解决方案 It is because of bug in EmguCV. You are calling public static double CalibrateCamera( MCvPoint3D32f[][] objectPoints, PointF[][] imagePoints, Size imageSize, IInputOutputArray cameraMatrix, IInputOutputArray distortionCoeffs, CvEnum.CalibType calibrationType, MCvTermCriteria termCriteria, out Mat[] rotationVectors, out Mat[] translationVectors)inside this method there is a call topublic static double CalibrateCamera( IInputArray objectPoints, IInputArray imagePoints, Size imageSize, IInputOutputArray cameraMatrix, IInputOutputArray distortionCoeffs, IOutputArray rotationVectors, IOutputArray translationVectors, CvEnum.CalibType flags, MCvTermCriteria termCriteria)IOutputArray rotationVectors should be copied to Mat[] rotationVectors. The same thing in case of translationVectors. The problem is in this loop.There isfor (int i = 0; i < imageCount; i++){ rotationVectors[i] = new Mat(); using (Mat matR = rotationVectors[i]) // <- bug matR.CopyTo(rotationVectors[i]); translationVectors[i] = new Mat(); using (Mat matT = translationVectors[i]) // <- bug matT.CopyTo(translationVectors[i]);}and there should befor (int i = 0; i < imageCount; i++){ rotationVectors[i] = new Mat(); using (Mat matR = rVecs[i]) matR.CopyTo(rotationVectors[i]); translationVectors[i] = new Mat(); using (Mat matT = tVecs[i]) matT.CopyTo(translationVectors[i]);}Finally to get rotation and translation values you can copy data using DataPointervar rotation = new Matrix<float>(rotationVectors[0].Rows, rotationVectors[0].Cols, rotationVectors[0].DataPointer); 这篇关于如何在emgu CV中进行相机校准后访问旋转和平移向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
05-27 09:05