2016-12-01 4 views
0

J'ai deux caméras placées horizontalement (proches l'une de l'autre). J'ai quitté la caméra cam1 et la caméra droite cam2.Erreur RMS élevée lors de l'affichage "en ligne" cv: stereoCalibration

d'abord calibrer les caméras (je veux calibrer 50 paires d'images):

  1. calibrer les deux caméras à l'aide séparement cv :: calibrateCamera()
  2. calibrer stéréo à l'aide cv :: stereoCalibrate()

Mes questions:

  1. Dans stereoCalibrate - Je suppose que l'ordre des caméras les données sont importantes. Si les données de la caméra gauche doivent être les points image1 et de la caméra droite, il doit s'agir de points image2 ou vice versa ou cela n'a pas d'importance tant que l'ordre des caméras est le même dans chaque point du programme?
  2. En stéréoCalibrate - j'obtiens une erreur RMS autour de 15,9319 et une erreur moyenne de reprojection autour de 8,4536. J'obtiens ces valeurs si j'utilise toutes les images des caméras. Dans les autres cas: d'abord je sauvegarde des images, je sélectionne des paires où tout l'échiquier est visible (tous les carrés de chessborad sont en vue caméra et tous les carrés sont visibles dans leur intégralité). Si cela signifie que seul l'étalonnage hors ligne est bon et si je veux calibrer l'appareil photo, je devrais sélectionner les bonnes images manuellement? Ou il y a un moyen de faire l'étalonnage en ligne? En ligne, je veux dire que je commence à capturer la vue de la caméra et sur chaque vue, j'ai trouvé des coins d'échiquier et après l'arrêt de la capture de la caméra, je calibre l'appareil photo.
  3. Je n'ai besoin que de quatre valeurs de distorsion mais j'en ai cinq (avec k3). Dans l'ancienne version d'api cvStereoCalibrate2 j'ai seulement quatre valeurs mais dans cv :: stereoCalibrate je ne sais pas comment faire cela? Est-il même possible ou le seul moyen est d'obtenir 5 valeurs et d'en utiliser seulement 4 plus tard?

Mon code:

Mat cameraMatrix[2], distCoeffs[2]; 
distCoeffs[0] = Mat(4, 1, CV_64F); 
distCoeffs[1] = Mat(4, 1, CV_64F); 

vector<Mat> rvec1, rvec2, tvec1, tvec2; 

double rms1 = cv::calibrateCamera(objectPoints, imagePoints[0], imageSize, cameraMatrix[0], distCoeffs[0],rvec1, tvec1, CALIB_FIX_K3, TermCriteria(
            TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON)); 

double rms2 = cv::calibrateCamera(objectPoints, imagePoints[1], imageSize, cameraMatrix[1], distCoeffs[1],rvec2, tvec2, CALIB_FIX_K3, TermCriteria(
            TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON)); 

qDebug()<<"Rms1: "<<rms1; 
qDebug()<<"Rms2: "<<rms2; 

Mat R, T, E, F; 

double rms = cv::stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1], 
    cameraMatrix[0], distCoeffs[0], 
    cameraMatrix[1], distCoeffs[1], 
    imageSize, R, T, E, F, 
    TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5), 
    CV_CALIB_FIX_INTRINSIC+ 
    CV_CALIB_SAME_FOCAL_LENGTH); 

Répondre

0

J'ai eu un problème similaire. Mon problème était que je lisais les images de gauche et les bonnes images en supposant que les deux étaient triés. Voici une partie du code en Python J'ai corrigé en utilisant "trié" dans la deuxième ligne.

images = glob.glob(path_left) 
for fname in sorted(images): 
    img = cv2.imread(fname) 
    gray1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
    # Find the chess board corners 
    ret, corners1 = cv2.findChessboardCorners(gray1, (n, m), None) 
    # If found, add object points, image points (after refining them) 
    if ret == True: 
     i = i + 1 
     print("Cam1. Chess pattern was detected") 
     objpoints1.append(objp) 
     cv2.cornerSubPix(gray1, corners1, (5, 5), (-1, -1), criteria) 
     imgpoints1.append(corners1) 
     cv2.drawChessboardCorners(img, (n, m), corners1, ret) 
     cv2.imshow('img', img) 
     cv2.waitKey(100)