Après avoir vérifié plusieurs morceaux de codes, j'ai pris plusieurs photos, trouvé les coins de l'échiquier et les ai utilisés pour obtenir la matrice de la caméra, les coefficients de distorsion, la rotation et les vecteurs de translation. Maintenant, quelqu'un peut-il me dire quelle fonction python opencv ai-je besoin pour calculer la distance dans le monde réel à partir de l'image 2D? Points de projet? Par exemple, en utilisant un échiquier comme référence (voir l'image ), si la taille des carreaux est de 5 cm, la distance pour 4 carreaux doit être de 20 cm. J'ai vu certaines fonctions comme projectPoints, findHomography, resolvePnP mais je ne sais pas lequel dois-je résoudre mon problème et obtenir la matrice de transformation entre les le monde de la caméra et le monde de l'échiquier.1 caméra unique, même position de la caméra dans tous les cas mais pas exactement sur l'échiquier, et l'échiquier est placé sur un objet plan (tableau)
# 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)
Votre problème concerne principalement l'étalonnage de la caméra, en particulier dans la mauvaise mise en œuvre de la résolution de la caméra distorsion en opencv. Vous devez approximer la fonction de distorsion de votre appareil photo en prenant quelques sondes de distance dans différentes coordonnées de votre échiquier. La bonne idée sera de prendre d'abord une petite distance au centre de la lentille, puis un carré loin en prenant une seconde distance un peu plus longue et de répéter l'opération jusqu'à la frontière. Il vous donnera des coefficients de votre fonction de distorsion. Matlab a sa propre bibliothèque pour résoudre votre problème avec une grande précision, malheureusement c'est assez cher.
Selon:
Maintenant, quelqu'un peut-il me dire quelle fonction python opencv ai-je besoin pour calculer la distance dans le monde réel à partir de l'image 2D?
Je pense que cet article prend une bonne explication de python ensemble de fonctions opencv pour générer une mesure réelle. Avec la résolution des coefficients comme je l'ai dit ci-dessus, vous pouvez faire une bonne précision. pense pas si c'est une implémentation open source de fonction comme
cv2.GetRealDistance(...)