(550,807), (943,807),(1749,945),(8,945) (0,0), (600,0), (600,800),(0,800)車道線選上面四點。
自己決定 mapping 到 600x800 的矩形。
然後用:
pts1 = np.float32([[550,807],[943,807],[1749,945],[8,945]]) pts2 = np.float32([[ 0, 0],[600, 0],[ 600,800],[0,800]]) matrix = cv2.getPerspectiveTransform(pts1,pts2)得到 perspective matrix
然後用 warpPerspective( ) 把 source image , 轉換..
result = cv2.warpPerspective(frame,matrix,(600,900))因為我們選四個點的時候,沒有選到照片的最底端。
所以 warpPerspective( ) 最後一個 destinate image size,長度要比 mapping 的 800 還多一些...才能把沒被包進去的下面部份也納入。
完整的程式就是:
import cv2
import numpy as np
frame = cv2.imread('p1.png')
pts1 = np.float32([[550,807],[943,807],[1749,945],[8,945]])
pts2 = np.float32([[ 0, 0],[600, 0],[ 600,800],[0,800]])
matrix = cv2.getPerspectiveTransform(pts1,pts2)
result = cv2.warpPerspective(frame,matrix,(600,900))
cv2.imshow('result',result)
cv2.waitKey(0)
另外,如果要把整個 video 都做 mapping 的話:
import cv2
import numpy as np
import sys
import os
input_file = sys.argv[1]
print(input_file)
path, filename = os.path.split(input_file)
filename, ext = os.path.splitext(filename)
output_file = filename + '_ipm' + ext
print(output_file)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_file,fourcc,30.0,(600,900))
pts1 = np.float32([[550,807],[943,807],[1749,945],[8,945]])
pts2 = np.float32([[ 0, 0],[600, 0],[ 600,800],[0,800]])
matrix = cv2.getPerspectiveTransform(pts1,pts2)
cap = cv2.VideoCapture(input_file)
while(cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
result = cv2.warpPerspective(frame,matrix,(600,900))
out.write(result)
cap.release()
cv2.destroyAllWindows()
另外,得到 perspective transform matrix 後,如果要知道 某一點 transform 後的位置。
相乘完,還要 scale
import numpy as np
with open('matrix.npy','rb') as f:
matrix = np.load(f)
Point = np.float32([100,60,1])
PPoint = matrix.dot(Point)
PPoint /= PPoint[2] // Scalse
TransformPoint = PPoint[:2]

