web-dev-qa-db-ja.com

OpenCV-チェスボードを参照として使用して2D画像から実世界の距離を取得する方法

enter image description here

いくつかのコードをチェックした後、私はいくつかのショットを取り、チェス盤のコーナーを見つけ、それらを使用してカメラマトリックス、歪み係数、回転、および並進ベクトルを取得しました。さて、誰かがどのpython opencv関数で2D画像からの現実世界の距離を計算する必要がありますか?プロジェクトポイントですか?たとえば、チェスボードを参照として使用して(図を参照)教えてください。 )、タイルサイズが5cmの場合、4つのタイルの距離は20 cmになるはずです。projectPoints、findHomography、solvePnPなどの関数をいくつか見ましたが、問題を解決して、カメラの世界とチェス盤の世界。1台のカメラ、すべてのケースで同じカメラの位置ですが、チェス盤の上ではなく、平面オブジェクト(テーブル)の上に置かれます

# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
    objp = np.zeros((nx * ny, 3), np.float32)
    objp[:, :2] = np.mgrid[0:nx, 0:ny].T.reshape(-1, 2)

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

    # Make a list of calibration images
    images = glob.glob(path.join(calib_images_dir, 'calibration*.jpg'))
    print(images)
    # Step through the list and search for chessboard corners
    for filename in images:

        img = cv2.imread(filename)

        imgScale = 0.5
        newX,newY = img.shape[1]*imgScale, img.shape[0]*imgScale
        res = cv2.resize(img,(int(newX),int(newY)))

        gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)

        # Find the chessboard corners
        pattern_found, corners = cv2.findChessboardCorners(gray, (nx,ny), None)

        # If found, add object points, image points (after refining them)
        if pattern_found is True:
            objpoints.append(objp)

            # Increase accuracy using subpixel corner refinement
            cv2.cornerSubPix(gray,corners,(5,5),(-1,-1),(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1 ))
            imgpoints.append(corners)

            if verbose:
                # Draw and display the corners
                draw = cv2.drawChessboardCorners(res, (nx, ny), corners, pattern_found)
                cv2.imshow('img',draw)
                cv2.waitKey(500)

    if verbose:
        cv2.destroyAllWindows()

    #Now we have our object points and image points, we are ready to go for calibration
    # Get the camera matrix, distortion coefficients, rotation and translation vectors
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
    print(mtx)
    print(dist)
    print('rvecs:', type(rvecs),' ',len(rvecs),' ',rvecs)
    print('tvecs:', type(tvecs),' ',len(tvecs),' ',tvecs)

    mean_error = 0
    for i in range(len(objpoints)):
        imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
        error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
        mean_error += error

    print("total error: ", mean_error/len(objpoints))


    imagePoints,jacobian = cv2.projectPoints(objpoints[0], rvecs[0], tvecs[0], mtx, dist)
    print('Image points: ',imagePoints)
11
Pablo Gonzalez

あなたの問題は、主にカメラのキャリブレーションに関連しています。特に、opencvでのリゾルビングカメラ distortion の貧弱な実装での問題です。チェス盤のさまざまな座標で距離のいくつかのプローブを取ることによって、カメラレンズの歪み関数を概算する必要があります。良いアイデアは、レンズの中心で最初に短い距離を取り、次に1スクエア離れて2番目に少し長い距離を取り、境界まで操作を繰り返すことです。それはあなたの歪み関数の係数を与えます。 Matlabには独自のライブラリがあります 非常に正確に問題を解決するために、残念ながらそれは非常に高価です。
による:

さて、誰かがどのpython opencv関数を使用して、2D画像から現実世界の距離を計算する必要があるかを教えてもらえますか?

私は この記事 はpython opencv関数セットを適切に説明して実際の測定値を生成します。上で述べたように係数を解決することで、優れた精度を得ることができます。とにかくのような機能のオープンソース実装である場合はそうは思いません

cv2.GetRealDistance(...)
0
ElConrado