2015-10-14 6 views
0

Цель калибровки камеры, чтобы найти внутренние и внешние параметры:Как получить доступ к векторам вращения и перевода после калибровки камеры в emgu CV?

  1. Присущих из них являются те, которые описывают сам (фокусное длины, искажение и т.д.) камеры я получаю значение для тех, нет проблема.
  2. Внешние параметры - это в основном положение камеры. Когда я пытаюсь получить доступ к этим, я получаю AccessViolationException.

Один из способов выполнить такую ​​калибровку, чтобы

  1. принять изображение цели калибровки с известными углами
  2. найти эти углы в образе
  3. от соответствия между 3D и 2D точек , найдите матрицу, которая преобразует ее в другую
  4. , что матрица состоит из внутренних и внешних параметров.

Звонок в calibration function выглядит следующим образом:

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); // AccessViolationException 
  • Я использую только одно изображение здесь, но у меня такая же проблема при использовании нескольких изображений (30) Различные калибровки изображения будут давать разные результаты для translation -/rotationVector в любом случае, что заставляет меня сомневаться, что использование только одного изображения является проблемой.
  • Обнаружение точек работает и рисует их в исходное изображение, дает результаты разумной оценки.
  • И cameraMatrix, и distortionCoefficients могут быть доступны и содержать значения. (Я пытался только опубликовать соответствующие части кода)
  • я использую emgu версии 3.0.0.2157

Почему я получаю AccessViolationException на rotationVectors и translationVectors?

Я установил точку останова и обнаружил, что внутренняя собственность Data равна null. Смотрите скриншот VS отладчик:

enter image description here

Это объясняет, почему я не могу получить доступ к нему. Но почему это null в первую очередь?

ответ

1

Это из-за ошибки в EmguCV. Вы звоните

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) 

внутри этого метода есть вызов

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. То же самое в случае трансляции векторов. Проблема в цикле this.

Существует

for (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]);     
} 

и должно быть

for (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]);     
} 

Наконец, чтобы получить вращение и перевод значения можно копировать данные с помощью DataPointer

var rotation = new Matrix<float>(rotationVectors[0].Rows, rotationVectors[0].Cols, rotationVectors[0].DataPointer); 
+0

я написал свою собственную функцию, которая изменяет эти линии. Я действительно могу получить доступ к значениям. Они сильно отличаются от того, что я получаю от SolvePnP, но, по крайней мере, я могу получить к ним доступ. Благодаря! – null

+0

@Bartosz Rachwal и null, извините за вопрос, но мой cvInoke.SolvePnP не хочу принимать Mat [] rotationVector, работает только с Emgu.CV.MatrixвращенияVector. Что я могу сделать, чтобы прочитать ротацию? Я надеюсь, что вы можете помочь мне –