gpt4 book ai didi

python - OpenCV - 如何使用棋盘作为引用从 2D 图像获取真实世界距离

转载 作者:太空狗 更新时间:2023-10-29 18:07:26 25 4
gpt4 key购买 nike

enter image description here

查了好几段代码,拍了好几张,找到棋盘角,用它们得到相机矩阵、畸变系数、旋转和平移向量。现在,有人能告诉我需要哪个 python opencv 函数来计算现实世界中与 2D 图像的距离吗?项目积分?例如,以棋盘为引用(见图),如果棋子尺寸为5cm,则4张棋子的距离应为20cm。我看到了一些函数,如 projectPoints、findHomography、solvePnP,但我不确定我需要哪一个来解决我的问题并获得相机世界和棋盘世界之间的转换矩阵。1个单摄像头,所有情况下摄像头的位置相同但不完全在棋盘上方,棋盘放置在平面物体( table )上方

# 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)

最佳答案

你确实是对的,我认为你应该使用 solvePnP 来解决这个问题。 (在这里阅读更多关于透视 n 点问题的信息:https://en.wikipedia.org/wiki/Perspective-n-Point。)

Python OpenCV solvePnP 函数采用以下参数并返回一个输出旋转和平移向量,将模型坐标系转换为相机坐标系。

cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]) → retval, rvec, tvec

在您的情况下,imagePoints 将是棋盘的角,因此它看起来像:

ret, rvec, tvec = cv2.solvePnP(objpoints, corners, mtx, dist)

使用返回的平移向量,您可以计算从相机到棋盘的距离。 solvePnP 的输出翻译与 objectPoints 中指定的单位相同。

最后,您可以将与 tvec 的实际距离计算为欧式距离:

d = math.sqrt(tx*tx + ty*ty + tz*tz).

关于python - OpenCV - 如何使用棋盘作为引用从 2D 图像获取真实世界距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55215639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com