我正在嘗試改變這個足球場的形象

鳥瞰圖,最初warpPerspective只嘗試過(python 中的 OpenCV),但結果是

這表明原始影像存在失真。
我已經研究了使影像不失真的方法,但從我目前所讀到的,我需要進行相機校準。這里的問題是我沒有關于用于記錄足球場鏡頭的相機屬性的任何資訊(這是唯一使相機校準變得困難的角度)。
我正在尋找有關如何在不了解相機屬性的情況下對影像進行不失真以擁有完美的鳥瞰視野的任何建議。我也可以從中學習任何后續步驟或資源。
這是我目前在 Python 中的代碼:
import cv2 as cv
import numpy as np
img = cv.imread("/Users/laulpee/Desktop/python/Screen Shot 2022-05-20 at 2.44.15 AM.png")
print(img.shape)
# Field Size 60' x 90'
h = 900
w = 1200
# 4 Points on Original Image
pt1 = np.float32([[2125,382],[1441,502],[3236,773],[3252,530]])
# 4 Corresponding Points of Desired Bird Eye View Image
pt2 = np.float32([[0,0],[0,h],[w,h],[w,0]])
matrix = cv.getPerspectiveTransform(pt1, pt2)
output = cv.warpPerspective(img,matrix,(w,h))
for i in range(0,4):
cv.circle(img,(int(pt1[i][0]),int(pt1[i][1])),5,(0,0,255),cv.FILLED)
window1 = cv.namedWindow("w1")
cv.imshow(window1,img)
cv.waitKey(0)
cv.destroyWindow(window1)
window2 = cv.namedWindow("w2")
cv.imshow(window2,output)
cv.waitKey(0)
cv.destroyWindow(window2)
uj5u.com熱心網友回復:
通常,您需要“校準”相機。這意味著要估計鏡頭畸變系數、光學中心、焦距,甚至可能是剪切系數。所有這些都取決于相機傳感器和它前面的鏡頭(包括對焦和變焦)。這通常通過校準模式來完成。
代替適當的校準,您可以假設一些默認值。
im = cv.imread("L91xP.jpg")
(height, width) = im.shape[:2]
assert (width, height) == (1280, 720), "or whatever else"
K = np.eye(3)
K[0,0] = K[1,1] = 1000 # 500-5000 is common
K[0:2, 2] = (width-1)/2, (height-1)/2
# array([[1000. , 0. , 639.5],
# [ 0. , 1000. , 359.5],
# [ 0. , 0. , 1. ]])
中心在中心,焦距是一些適中的值。此處錯誤的焦距只會影響失真系數,并且是其中的一個因素。
可以假設失真系數全為 0。您可以調整它們并觀察會發生什么。
dc = np.float32([-0.54, 0.28, 0. , 0. , 0. ]) # k1, k2, p1, p2, k3
Undistortion... 可以應用于整個圖片或單個點。
要點:
- 要么
cv.undistortImagePoints(impts, K, dc)(新的 API,因為undistortPoints做的比某些人需要的要多) - 或
cv.perspectiveTransform(cv.undistortPoints(impts, K, dc), K)(perspectiveTransform撤消了undistortPoints的一些作業)
圖片:
im_undistorted = cv.undistort(im, K, dc)
現在您有了沒有鏡頭失真的影像和點。
modelpts = np.float32([
[45., 0.],
[90., 0.],
[90., 60.],
[45., 60.]]) * 15 # 15 pixels per foot
impts = [
[511.54881, 184.64497],
[758.16124, 141.19525],
[1159.37185, 191.21864],
[1153.4168, 276.2696]
]
impts_undist = np.float32([
[ 508.38733, 180.3246 ],
[ 762.08234, 133.98148],
[1271.5339 , 154.91203],
[1250.6611 , 260.52057]]).reshape((-1, 1, 2))
透視變換至少需要四對點。在每一對中,一個點定義在一個透視圖(場的一側)中,另一個點定義在另一個透視圖(自上而下/“模型”)中。
H = cv.getPerspectiveTransform(impts_undist, modelpts)
您可以將更多轉換鏈接到該單應性 (H),例如在任一影像空間中的平移/縮放,以將圖片移動到您想要的位置。這只是矩陣乘法。
# add some in the X and Y dimension
Tscale = np.array([
[ 1., 0., 75.], # arbitrary values
[ 0., 1., 25.],
[ 0., 0., 1.]])
然后將單應性應用于未失真的輸入影像:
topdown = cv.warpPerspective(im_undistorted, H, dsize=(90*15, 60*15))
這些是構建塊。然后,您可以構建一些互動式createTrackbar的東西來處理失真系數,直到輸出看起來很直。
不要指望它會變得完美。除了失真系數之外,光學中心可能并不是它應該在的位置。并且側視圖上的拾取點可能會偏離一個像素左右,但這會以如此小的角度和跨場的距離轉化為幾英尺。
最好得到一個校準圖案并在相機前揮動它(嗯......保持不動!)。我推薦“ChArUco”板。它們是最容易產生可用結果的,因為您不需要將整個電路板都放在視野中。
以下是一些圖片:
輸入你給它...
不失真:

自上而下的視圖:(
為了獲得更多的環境,在單應性前面乘以一些平移,例如H2 = T @ H將其移動到右下角一點,并給 warpPerspective 一個更大的dsize)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/495957.html
