# 相机标定正畸并生成鸟瞰图

## 实验内容和原理

，可以用它来将世界坐标转换为像素坐标：

``````img = cv2.imread(fname)
img = cv2.resize(img, (0, 0), fx = 0.5, fy = 0.5)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('img', img)
cv2.waitKey(1)
plt.subplot(2,2,1), plt.title('original image')
plt.imshow(img)
print('Donen')

# Find the chess board corners
print('nFinding Chessboard...')
print('-----------------------------------------')
ret, corners = cv2.findChessboardCorners(gray, (9,6),None)

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

corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)

img_ = img.copy()
# Draw and display the corners
# Use img_ here instead of img is for the later use of undistorted image
img_ = cv2.drawChessboardCorners(img_, (9,6), corners2,ret)
cv2.imshow('img',img)
cv2.waitKey(1)
``````

``````# Using the cv2.calibrateCamera function, it can generate the needed matrices for the camera pose and how the image is distorted
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
``````

``````# serialize the matrices
np.savez('coefs.npz', mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)
cv_file = cv2.FileStorage("./save/matrices.xml", cv2.FILE_STORAGE_WRITE)
cv_file.write("mtx", mtx)
cv_file.write("dist", dist)
cv_file.write("rvecs", rvecs[0])
cv_file.write("tvecs", tvecs[0])
cv_file.release()
``````

``````# undistort
h,  w = img.shape[:2]
# generate the new matrix of camera pose after undistortion
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# here we can get how the pixels are mapped to the new image
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)

``````

``````x,y,w,h = roi
cropped = dst[y:y+h, x:x+w]
``````

``````# use the undistorted image as the source, find the corners for generate the birdview image
img = dst
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (9,6),None)
print('ret = ', ret)
if ret == True:
objpoints.append(objp)

corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)

img_ = img.copy()
# Draw and display the corners
img_ = cv2.circle(img_, (corners[0][0][0], corners[0][0][1]), 63, (0, 0, 255), 5)
img_ = cv2.circle(img_, (corners[8][0][0], corners[8][0][1]), 63, (0, 255, 0), 5)
img_ = cv2.circle(img_, (corners[45][0][0], corners[45][0][1]), 63, (255, 255, 0), 5)
img_ = cv2.circle(img_, (corners[53][0][0], corners[53][0][1]), 63, (255, 0, 255), 5)
img_ = cv2.drawChessboardCorners(img_, (9,6), corners2,ret)
cv2.imshow('img',img_)
cv2.waitKey(1)

corners = np.squeeze(corners)

``````

``````Scale = 50
objpts = np.float32([[0, 0], [8, 0], [0, 5], [8, 5]])
objpts = objpts * Scale
print(objpts)
imgpts = np.float32([corners[0],corners[8],corners[45],corners[53]])
print(imgpts)

cv2.destroyAllWindows()

# find how it transformed
H = cv2.getPerspectiveTransform(imgpts, objpts)

``````

``````print("nPress 'd' for lower birdseye view, and 'u' for higher (it adjusts the apparent 'Z' height), Esc to exit")

Z = H[2, 2]
while True:
H[2, 2] = Z
Perspective_img = cv2.warpPerspective(img, H, (img.shape[1], img.shape[0]))
cv2.imshow("Birdseye View", Perspective_img)
KEY = cv2.waitKey() & 0xFF

if KEY == ord('u'):
Z += 0.05
if KEY == ord('d'):
Z -= 0.05
if KEY == 27:
cv2.destroyAllWindows()
exit()

``````

## 实验结果

``````<?xml version="1.0"?>
<rows>3</rows><cols>3</cols>
<dt>d</dt>
<data> 1.9185538075266456e+03 0. 6.6351052686831258e+02 0. 1.9239847846858713e+03 5.2501768650563508e+02 0. 0. 1.</data></mtx><rows>1</rows><cols>5</cols>
<dt>d</dt>
<data> -6.5131737583550275e-01 1.2672234354930185e+00 -7.6049220720545881e-03 -1.1437164634492115e-02 -5.9703308825363361e+00</data></dist><rows>3</rows><cols>1</cols>
<dt>d</dt>
<data> 3.2420766902989018e-01 -6.4589768076974197e-01 1.1011907909749442e-01</data></rvecs><rows>3</rows><cols>1</cols>
<dt>d</dt>
<data> -2.6876180482710543e+00 -1.2541719558169395e+00 1.5495572059324372e+01</data></tvecs></opencv_storage>
``````

（顺便利用以前写的小工具生成了相机视角的 ply 文件）：

• 课程给出的测试图片（由于效果非常好所以不做 undistort 直接运行）
• 由于电脑内存较小，所以稍微改了一下对老师给出的图像进行处理的程序。希望验收的时候使用我自己拍的图（效果更好 QAQ）

THE END