(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]