5

Вопрос по matlab – Калибровка камеры OpenCV 2.3

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

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)
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от hokiebird
  • Error: User Rate Limit ExceededThe documentationError: User Rate Limit Exceeded

    от
  • Error: User Rate Limit ExceededlinkError: User Rate Limit Exceeded

    от
  • сделайте одолжение сообществу opencv иdo not answer outdated question

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

    от mathematical.coffee
5 ответов
  • 0

    использование

    Point3f а такжеPoint2f вместоPoint3d а такжеPoint2d определитьobject_points а такжеimage_points и это будет работать.

  • 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 не нужны.

  • 1

    После помощи от математического. У меня есть эта 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 элементов при возврате из функции калибровки. в документации написано & quot; если вектор содержит четыре элемента, это означает, что K3 = 0 ". Но на самом деле используется K3, независимо от длины dist_coefs (4 или 5). Кроме того, я не могу заставить работать флаг CV_CALIB_FIX_K3, связанный с использованием этого флага, чтобы K3 был равен нулю. Денежные средства говорят, что требуется целое число. это может быть потому, что я не знаю, как сделать несколько флагов одновременно, я просто делаю это, 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

  • 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] являетсяrow i, column 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 должен бытьvectors of vectorsпотому что возможно подавать в наборах точек объекта / изображения для нескольких изображений одной шахматной доски (/ точек калибровки).

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

    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 ....
    

    Какие?! Другая ошибка по крайней мере. Но яdid поставьте исходную внутреннюю матрицу!

    Поэтому я возвращаюсь к документации и замечаюflags параметр:

    flags – Different flags that may be zero or a combination of the following values:

    CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix contains valid initial values of fx, fy, cx, cy that are optimized further

    ...

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

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

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

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