2

以下の画像では、Z=0 で定義されたワールド プレーン座標 (X,Y,0) を確認できます。私たちが見ることができるカメラは、定義された世界平面に向かっています。

ワールド基準点は、グリッド (0,0,0) の左上にあります。2 つの黄色い点の間の距離は 40 cm です

World_coordinate

チェッカーボードを使用してカメラを調整し、組み込み関数cv2.solvePnPを使用して、定義したワールド座標に対するカメラの回転ベクトルと平行移動ベクトルを推定しました。結果は次のとおりです。

   tvec_cam= [[-5.47884374]
               [-3.08581371]
               [24.15112048]]
   rvec_cam= [[-0.02823308]
              [ 0.08623225]
              [ 0.01563199]]

結果によると、(tx,ty,tz) は、カメラが X,Y ワールド座標の負の 4 分の 1 に位置しているため、正しいようです。

しかし、私は回転ベクトルを解釈することで混乱しています.!

結果の回転ベクトルは、カメラ座標がワールド座標軸とほぼ一致していることを示していますか (つまり、ほとんど回転していないことを意味します!)?

OPENCVのカメラ座標によると、カメラの Z 軸はシーンの方向 (ワールド平面の方向を意味します) を指し、X 軸は画像の書き込み方向を指します (つまり、反対の方向を意味します)。カメラの Y 軸は画像の下部を指します (これは、Y ワールド軸の反対も意味します)。

また、tvecの単位は何ですか?

注:平行移動ベクトルの結果に従って、定義されたワールド座標軸の向きを示しました (tx と ty の両方が負です)。

回転ベクトルと並進ベクトルを計算するために使用したコードを以下に示します。

import cv2 as cv 
import numpy as np


WPoints = np.zeros((9*3,3), np.float64)
WPoints[:,:2] = np.mgrid[0:9,0:3].T.reshape(-1,2)*0.4




imPoints=np.array([[20,143],[90,143],[161,143],[231,144],[303,144],
              [374,144],[446,145],[516,146],[587,147],[18,214],[88,214]
               ,[159,215],[230,215],[302,216],[374,216],[446,216]
               ,[517,217],[588,217],[16,285],[87,285],[158,286],[229,287], 
                [301,288]
               ,[374,289],[446,289],[518,289],[589,289]],dtype=np.float64)
      
    
#load the rotation matrix [[4.38073915e+03 0.00000000e+00 1.00593352e+03]
                       #  [0.00000000e+00 4.37829226e+03 6.97020491e+02]
                     #    [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
with np.load('parameters_cam1.npz') as X:
mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]


ret,rvecs, tvecs = cv.solvePnP(WPoints, imPoints, mtx, dist)


np.savez("extrincic_camera1.npz",rvecs=rvecs,tvecs=tvecs)

print(tvecs)
print(rvecs)
cv.destroyAllWindows()

組み込みを推定するためのコードを以下に示します

import numpy as np
import cv2
import glob
import argparse
import pathlib
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--path", required=True, help="path to images folder")
ap.add_argument("-e", "--file_extension", required=False, default=".jpg", 
help="extension of images")
args = vars(ap.parse_args())
path = args["path"] + "*" + args["file_extension"]
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# prepare object points, like (0,0,0), (0.03,0,0), (0.06,0,0) ...., 
#(0.18,0.12,0)
objp = np.zeros((5*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:5].T.reshape(-1,2)*0.03
#print(objp)


# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.

#images = glob.glob('left/*.jpg') #read a series of images

images = glob.glob(path)

path = 'foundContours'
#pathlib.Path(path).mkdir(parents=True, exist_ok=True) 

found = 0
for fname in images: 
    
  img = cv2.imread(fname) # Capture frame-by-frame
  #print(images[im_i])
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  # Find the chess board corners
  ret, corners = cv2.findChessboardCorners(gray, (7,5), None)
  #  print(corners)
  # If found, add object points, image points (after refining them)
  if ret == True:
    print('true')
    objpoints.append(objp)   # Certainly, every loop objp is the same, in 3D.
    #print('obj_point',objpoints)
    corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
    # print(corners2)
    imgpoints.append(corners2)
    print(imgpoints)
    print('first_point',imgpoints[0])
    #print(imgpoints.shape())
    # Draw and display the corners
    img = cv2.drawChessboardCorners(img, (7,5), corners2, ret)
    found += 1
    cv2.imshow('img', img)
    cv2.waitKey(1000)
    # if you want to save images with detected corners 
    # uncomment following 2 lines and lines 5, 18 and 19
    image_name = path + '/calibresult' + str(found) + '.jpg'
    cv2.imwrite(image_name, img)

print("Number of images used for calibration: ", found)

# When everything done, release the capture
# cap.release()
cv2.destroyAllWindows()
#calibration
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, 
gray.shape[::-1],None,None)


#save parameters needed in undistortion
np.savez("parameters_cam1.npz",mtx=mtx,dist=dist,rvecs=rvecs,tvecs=tvecs)
np.savez("points_cam1.npz",objpoints=objpoints,imgpoints=imgpoints)

print ("Camera Matrix = |fx  0 cx|")
print ("                | 0 fy cy|")
print ("                | 0  0  1|")
print (mtx)
print('distortion coefficients=\n', dist)
print('rotation vector for each image=', *rvecs, sep = "\n")
print('translation vector for each image=', *tvecs, sep= "\n")

これを理解するのを手伝ってくれることを願っています

前もって感謝します

4

1 に答える 1