2012-04-05 7 views
5

Я пытаюсь использовать привязки python OpenCV 2.3 для калибровки камеры. Я использовал данные, приведенные ниже в Matlab, и калибровка работала, но я не могу заставить ее работать в OpenCV. Матрица камеры, которую я устанавливаю как начальное предположение, очень близка к ответу, вычисленному из набора инструментов matlab.Калибровка камеры OpenCV 2.3

import cv2 
import numpy as np 

obj_points = [[-9.7,3.0,4.5],[-11.1,0.5,3.1],[-8.5,0.9,2.4],[-5.8,4.4,2.7],[-4.8,1.5,0.2],[-6.7,-1.6,-0.4],[-8.7,-3.3,-0.6],[-4.3,-1.2,-2.4],[-12.4,-2.3,0.9], [-14.1,-3.8,-0.6],[-18.9,2.9,2.9],[-14.6,2.3,4.6],[-16.0,0.8,3.0],[-18.9,-0.1,0.3], [-16.3,-1.7,0.5],[-18.6,-2.7,-2.2]] 
img_points = [[993.0,623.0],[942.0,705.0],[1023.0,720.0],[1116.0,645.0],[1136.0,764.0],[1071.0,847.0],[1003.0,885.0],[1142.0,887.0],[886.0,816.0],[827.0,883.0],[710.0,636.0],[837.0,621.0],[789.0,688.0],[699.0,759.0],[768.0,800.0],[697.0,873.0]] 

obj_points = np.array(obj_points) 
img_points = np.array(img_points) 

w = 1680 
h = 1050 
size = (w,h) 

camera_matrix = np.zeros((3, 3)) 
camera_matrix[0,0]= 2200.0 
camera_matrix[1,1]= 2200.0 
camera_matrix[2,2]=1.0 
camera_matrix[2,0]=750.0 
camera_matrix[2,1]=750.0 

dist_coefs = np.zeros(4) 
results = cv2.calibrateCamera(obj_points, img_points,size, 
    camera_matrix, dist_coefs) 
+1

Что вы подразумеваете под «не может показаться, чтобы заставить его работать» - это дает некоторую ошибку? (в этом случае, какая ошибка?) Или это работает и просто не дает вам коэффициенты, которые вы ожидаете? –

ответ

20

Во-первых, ваша матрица камеры ошибочна. Если вы читали , он должен выглядеть следующим образом:

fx 0 cx 
0 fy cy 
0 0 1 

Если вы посмотрите на вашей, вы получили это неправильный путь вокруг:

fx 0 0 
0 fy 0 
cx cy 1 

Итак, сначала установите camera_matrix на camera_matrix.T (или измените, как вы строите camera_matrix. Помните, что camera_matrix[i,j] is строкаi, столбецj).

camera_matrix = camera_matrix.T 

Далее, я запустил свой код, и я вижу, что «не могу заставить его работать» означает следующее сообщение об ошибке (кстати - всегда говорят, что вы подразумеваете под «не могу показаться, чтобы получить это работать»в ваших вопросах - если это ошибка, отправьте сообщение об ошибке Если он работает, но дает вам извращенец номера, так сказать):

OpenCV Error: Assertion failed (ni >= 0) in collectCalibrationData, file /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp, line 3161 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
cv2.error: /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp:3161: error: (-215) ni >= 0 in function collectCalibrationData 

Я тогда прочитал (очень полезно, кстати) и. заметили, что obj_points и img_points должны быть векторами векторов, так как можно подавать в наборах объектов/точек изображения s для нескольких изображений одной шахматной доски (/ калибровочных точек).

Следовательно:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs) 

Что? Я все равно получаю такую ​​же ошибку ?!

Затем я взглянул на образцы OpenCV python2 (в папке OpenCV-2.x.x/samples/python2), и заметил calibration.py, показывая мне, как использовать калибровочные функции (никогда не недооценивают образцы, они часто лучше, чем в документации!) ,

Я попытался запустить calibration.py, но он не запускается, потому что он не содержит аргументы camera_matrix и distCoeffs, которые необходимы. Поэтому я модифицировал его для подачи в манекене camera_matrix и distCoeffs, и эй, он работает!

Единственная разница, которую я вижу между моими obj_points/img_points и их, заключается в том, что у них есть dtype=float32, а у меня нет.

Итак, я изменяю мой obj_points и img_points также иметь DTYPE float32 (интерфейс python2 к OpenCV смешно как то, часто не работают, когда матрицы не имеют dtype):

obj_points = obj_points.astype('float32') 
img_points = img_points.astype('float32') 

Затем я попробую еще раз:

>>> cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs) 
OpenCV Error: Bad argument 
(For non-planar calibration rigs the initial intrinsic matrix must be specified) 
in cvCalibrateCamera2, file .... 

Что ?! По крайней мере, другая ошибка.Но I сделал снабдить исходную внутреннюю матрицу!

Так я возвращаюсь к документации, и обратите внимание на flags параметр:

флаги - Различные флаги, которые могут быть нулем или комбинацией следующих значений:

CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix содержит действительный инициал значения Рх, Ру, сх, су, которые оптимизированы далее

...

Ага, так что я должен сказать функцию явно использовать исходные предположения я представил:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix.T, dist_coefs, 
        flags=cv2.CALIB_USE_INTRINSIC_GUESS) 

Ура! Оно работает!

(Мораль истории - читайте документацию OpenCV тщательно и использовать последнюю версию (т.е. на opencv.itseez.com), если вы используете интерфейс Python cv2 Кроме того, ознакомьтесь с примерами в каталоге samples/python2 к. добавьте документацию. С этими двумя вещами вы сможете решить большинство проблем.)

+0

спасибо добросердечный сэр. Я нашел «векторы векторов» в документации, но не смог найти хорошего понимания того, что это значило. – hokiebird

+0

@ Mathematical.coffee: Можете ли вы указать мне на алгоритм (документ), используемый в калибровке OpenCV для некомпланарных установок? Я считаю, что это взято из набора инструментов калибровки камеры Matlab от Bouguet [link] (http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/ref.html). Но я не уверен, является ли это алгоритмом Цая или алгоритмом Хейккилы? –

+0

@SatishKumar, я бы не понял, что они используют. [Документация] (http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=calibratecamera#bouguetmct) имеет ссылку на материал Bouget Matlab. Возможно, вы можете прочитать исходный код. –

1

После помощи математика. coffee У меня есть эта 3D-калибровка для запуска.

import cv2 
from cv2 import cv 
import numpy as np 

obj_points = [[-9.7,3.0,4.5],[-11.1,0.5,3.1],[-8.5,0.9,2.4],[-5.8,4.4,2.7],[-4.8,1.5,0.2],[-6.7,-1.6,-0.4],[-8.7,-3.3,-0.6],[-4.3,-1.2,-2.4],[-12.4,-2.3,0.9],[-14.1,-3.8,-0.6],[-18.9,2.9,2.9],[-14.6,2.3,4.6],[-16.0,0.8,3.0],[-18.9,-0.1,0.3],[-16.3,-1.7,0.5],[-18.6,-2.7,-2.2]] 
img_points = [[993.0,623.0],[942.0,705.0],[1023.0,720.0],[1116.0,645.0],[1136.0,764.0],[1071.0,847.0],[1003.0,885.0],[1142.0,887.0],[886.0,816.0],[827.0,883.0],[710.0,636.0],[837.0,621.0],[789.0,688.0],[699.0,759.0],[768.0,800.0],[697.0,873.0]] 

obj_points = np.array(obj_points,'float32') 
img_points = np.array(img_points,'float32') 

w = 1680 
h = 1050 
size = (w,h) 

camera_matrix = np.zeros((3, 3),'float32') 
camera_matrix[0,0]= 2200.0 
camera_matrix[1,1]= 2200.0 
camera_matrix[2,2]=1.0 
camera_matrix[0,2]=750.0 
camera_matrix[1,2]=750.0 

dist_coefs = np.zeros(4,'float32') 

retval,camera_matrix,dist_coefs,rvecs,tvecs = cv2.calibrateCamera([obj_points],[img_points],size,camera_matrix,dist_coefs,flags=cv.CV_CALIB_USE_INTRINSIC_GUESS) 

Единственная проблема, я сейчас почему вектор dist_coefs длиной 5 элементов при возврате из функции калибровки. в документации говорится: «Если вектор содержит четыре элемента, это означает, что K3 = 0». Но на самом деле используется K3, независимо от длины dist_coefs (4 или 5). Более того, я не могу заставить флаг CV_CALIB_FIX_K3 работать, привязанный к использованию этого флага, чтобы заставить K3 быть нулевым. cashes говорят, что требуется целое число. это может быть связано с тем, что я не знаю, как делать сразу несколько флагов, я просто делаю это, flags = (cv.CV ..., cv.CV ...).

Just to compare, from the matlab camera cal routine the results are... 
    Focal length: 2210. 2207. 
    principal point: 781. 738. 
    Distortions: 4.65e-2 -9.74e+0 3.9e-3 6.74e-3 0.0e+0 
    Rotation vector: 2.36 0.178 -0.131 
    Translation vector: 16.016 2.527 69.549 

From this code, 
    Focal length: 1647. 1629. 
    principal point: 761. 711. 
    Distortions: -2.3e-1 2.0e+1 1.4e-2 -9.5e-2 -172e+2 
    Rotation vector: 2.357 0.199 -0.193 
    Translation vector: 16.511 3.307 48.946 

Я думаю, что если бы я мог выяснить, как заставить k3 = 0, остальные значения будут выравниваться прямо вверх.

1

Сделайте вектор dist_coeffs как 5-мерный нулевой вектор, а затем используйте флаг CV_CALIB_FIX_K3. Вы можете видеть, что последний элемент в векторе (K3) будет равен нулю.

Когда дело доходит до использования нескольких флагов, вы можете их ИЛИ.

Пример: cv.CV_CALIB_USE_INTRINSIC_GUESS | cv.CV_CALIB_FIX_K3

2

Для чего это стоит, следующий фрагмент кода в настоящее время работает под 2.4.6.1:

pattern_size = (16, 12) 
    pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32) 
    pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2).astype(np.float32) 
    img_points = pattern_points[:, :2] * 2 + np.array([40, 30], np.float32) 
    print(cv2.calibrateCamera([pattern_points], [img_points], (400, 400), flags=cv2.CALIB_USE_INTRINSIC_GUESS)) 

Обратите внимание, что camera_matrix и dist_coefs не нужны.

0

Использование Point3f и Point2f вместо Point3d и Point2d определить object_points и image_points и он будет работать.

+0

, пожалуйста, сделайте оргпредприятие пользу и ** не ответьте на устаревший вопрос ** – berak

 Смежные вопросы

  • Нет связанных вопросов^_^