進行校準相機,使圖像不失真並進行視角轉換。
目標編寫一個函數,將失真的圖像作為輸入,並完成以下步驟:
1.利用帶有mtx和dist參數之cv2.undistort()函數使圖像不失真
2.轉換為灰階圖
3.找到棋盤角落
4.畫出角落
5.定義4個源點(棋盤圖案中檢測到的外部4個角)
6.定義4個目標點(必須以與src點相同的順序列出!)
6.使用cv2.getPerspectiveTransform()來獲得M,即轉換矩陣
7.使用cv2.warpPerspective()來應用M並將圖像包為自上而下的視圖
提示:源點是棋盤上任意四個角的x和y像素值,可以從cv2.findChessboardCorners()的角數組輸出中提取這些值。目標點是您希望在輸出圖像中將這四個角映射到的位置的x和y像素值。
我定義了一個函數,corner_unwarp()。 該函數引數包括圖像和我們先前計算的相機矩陣,mtx和失真係數dist。
# Define a function that takes an image, number of x and y points,
# camera matrix and distortion coefficients
def corners_unwarp(img, nx, ny, mtx, dist):
# Use the OpenCV undistort() function to remove distortion
undist = cv2.undistort(img, mtx, dist, None, mtx)
# Convert undistorted image to grayscale
gray = cv2.cvtColor(undist, cv2.COLOR_BGR2GRAY)
# Search for corners in the grayscaled image
ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)
if ret == True:
# If we found corners, draw them! (just for fun)
cv2.drawChessboardCorners(undist, (nx, ny), corners, ret)
# Choose offset from image corners to plot detected corners
# This should be chosen to present the result at the proper aspect ratio
# My choice of 100 pixels is not exact, but close enough for our purpose here
offset = 100 # offset for dst points
# Grab the image shape
img_size = (gray.shape[1], gray.shape[0])
# For source points I'm grabbing the outer four detected corners
src = np.float32([corners[0], corners[nx-1], corners[-1], corners[-nx]])
# For destination points, I'm arbitrarily choosing some points to be
# a nice fit for displaying our warped result
# again, not exact, but close enough for our purposes
dst = np.float32([[offset, offset], [img_size[0]-offset, offset],
[img_size[0]-offset, img_size[1]-offset],
[offset, img_size[1]-offset]])
# Given src and dst points, calculate the perspective transform matrix
M = cv2.getPerspectiveTransform(src, dst)
# Warp the image using OpenCV warpPerspective()
warped = cv2.warpPerspective(undist, M, img_size)
# Return the resulting image and matrix
return warped, M
輸出成果: