Home > Enterprise >  Calculate the normal equation for a checkerboard found through pose estimation
Calculate the normal equation for a checkerboard found through pose estimation

Time:02-22

I am working on a laserscanning project. For this, I am following this image of a checkerboard After calculating/finding the intrinsic camera matrix with OpenCv (Python 3)

cv.findChessboardCorners()

cv.cornerSubPix()

following this tutorial by opencv.org, I am using the

cv.solvePnP()

function to get the rotational and translational vector of the planes. With the following code, I am calculating now the normal and the signed distance from the camera center following the authors formula:

normalvector = rotationmatrix * [[0][0][1]]
distance = (normalvector * -1)T * translational vector

(T = vector got transposed)

import numpy as np
import cv2 as cv

with np.load("vectorsRT.npz", "r") as file:
    rvecs, tvecs = [file[i] for i in ("rotationVectors", "translationVectors")]

rot_matrix = cv.Rodrigues(rvecs)[0]
mult_matrix = np.array([[0],[0],[1]])

normal_vector = np.matmul(rot_matrix, mult_matrix)
normal_vector_neg = normal_vector * -1
normal_vector_neg_transposed = np.transpose(normal_vector_neg)

signed_distance = np.matmul(normal_vector_neg_transposed, tvecs)

print("normal_vector:", normal_vector)    
print("signed_distance:", signed_distance)

With this, I am getting now a normal vector and a distance from the camera center, eg.: normal_vector:

[[-0.0604253 ]
 [ 0.16923283]
 [ 0.98372203]]

signed_distance:

[[[-51.67514398]]]

from blender I am getting the following normal

[[-0.00117647]
 [-0.00333335]
 [-0.01939508]]

The normals are more or less equivalent, however, how is the signed distance now converted to a support vector of plane in the world coordinate system, so I can get the full plane equation?

CodePudding user response:

I think I found the answer: Following this post, I introduced a scale factor s for the signed distance, to convert the distance into a real world distance (in mm).

calc_distance_camera_plane = signed_distance * s 

This scale factor is calculated through dividing a known distance from a plane (e.g.: the chessboard is on Z = 0 in the world coordinate frame, with the camera beeing fixed at a postion, e.g.: Z = 25 mm, looking downwards) by the signed_distance of that exact image

scale_factor = dist_camera_world_orign / signed_distance

With that scale factor, one can the transformed each signed_distance to a real world distance (camera-plane) and also get the real world distance (world orign-plane)

 dist_world_orign_plane = dist_camera_world_orign - calc_distance_camera_plane

The plane equation I looked for is then given by the calculated normal and a point with

(0, 0, dist_world_orign_plane)

Beeing that I have the exact values of the orignal planes (images were calculated with blender), I could compare the calculated distances of the camera_plane with the real distances (real distance/calculated distance):

n = 10
mean difference: 1.005
standard deviation: 0.0281

I think this is a good starting point for further testing. Hope this answer can help others too, cheers

  • Related