1.2.3 透视变换 perspective_transform.py
- 引入相关的包
import numpy as np import cv2 import matplotlib.pyplot as plt import matplotlib.image as mpimg import pickle from combined_thresh import combined_thresh
- 定义透视变换函数
def perspective_transform(img): """ Execute perspective transform """ img_size = (img.shape[1], img.shape[0]) # 求解透视变换矩阵所需要的的四个点是怎么找的? src = np.float32( [[200, 720], [1100, 720], [595, 450], [685, 450]]) dst = np.float32( [[300, 720], [980, 720], [300, 0], [980, 0]]) m = cv2.getPerspectiveTransform(src, dst) m_inv = cv2.getPerspectiveTransform(dst, src) warped = cv2.warpPerspective(img, m, img_size, flags=cv2.INTER_LINEAR) unwarped = cv2.warpPerspective(warped, m_inv, (warped.shape[1], warped.shape[0]), flags=cv2.INTER_LINEAR) # DEBUG return warped, unwarped, m, m_inv
- 测试透视变换函数
if __name__ == '__main__': img_file = 'test_images/test5.jpg' with open('calibrate_camera.p', 'rb') as f: save_dict = pickle.load(f) mtx = save_dict['mtx'] dist = save_dict['dist'] img = mpimg.imread(img_file) img = cv2.undistort(img, mtx, dist, None, mtx) img, abs_bin, mag_bin, dir_bin, hls_bin = combined_thresh(img) warped, unwarped, m, m_inv = perspective_transform(img) plt.imshow(warped, cmap='gray', vmin=0, vmax=1) plt.show() plt.imshow(unwarped, cmap='gray', vmin=0, vmax=1) plt.show()
- python+opencv图像变换的两种方法:cv2.warpAffine和cv2.warpPerspective
以下转自博客
# usr/bin/env python
# coding: utf-8
##################### 对图像进行变换(旋转)
# 2018年6月17日07:33:54
import cv2
import numpy as np
# 这里说一下旋转的opencv中为旋转提供的三个要素
# 旋转的中心点(center)
# 旋转角度()
# 旋转后进行放缩
# 我们可以通过cv2.getRotationMatrix2D函数得到转换矩阵
img = cv2.imread('cat.jpg')
rows,cols,_ = img.shape
matrix = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
# 得到变换的矩阵,通过这个矩阵再利用warpAffine来进行变换
# 第一个参数就是旋转中心,元组的形式,这里设置成相片中心
# 第二个参数90,是旋转的角度
# 第三个参数1,表示放缩的系数,1表示保持原图大小
img1 = cv2.warpAffine(img,matrix,(cols,rows))
cv2.imshow('img',img)
cv2.imshow('img1',img1)
##################### 对图像进行变换(三点得到一个变换矩阵)
# 我们知道三点确定一个平面,我们也可以通过确定三个点的关系来得到转换矩阵
# 然后再通过warpAffine来进行变换
img = cv2.imread('dog.jpg')
rows,cols,_ = img.shape
points1 = np.float32([[50,50],[200,50],[50,200]])
points2 = np.float32([[10,100],[200,50],[100,250]])
matrix = cv2.getAffineTransform(points1,points2)
output = cv2.warpAffine(img,matrix,(cols,rows))
cv2.imshow('input',img)
cv2.imshow('output',output)
##################### 对图像进行变换(四点得到一个变换矩阵)
# 进行透视变换
# 可以先用四个点来确定一个3*3的变换矩阵(cv2.getPerspectiveTransform)
# 然后通过cv2.warpPerspective和上述矩阵对图像进行变换
img = cv2.imread('cat.jpg')
rows,cols,_ = img.shape
points1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
points2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
matrix = cv2.getPerspectiveTransform(points1,points2)
# 将四个点组成的平面转换成另四个点组成的一个平面
output = cv2.warpPerspective(img, matrix, (cols, rows))
# 通过warpPerspective函数来进行变换
cv2.imshow('img',img)
cv2.imshow('output',output)
cv2.waitKey()
cv2.destroyAllWindows()
- 相机前视图转换为鸟视图
- 无相机标定时
通过选取四个点对求取单应性矩阵。
如何获取四个点对?M = cv2.getPerspectiveTransform(src, dst) warped = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0] + 1080)) cv2.getPerspectiveTransform 从四个点对中计算透视变换,返回值为3*3的透视变换矩阵 cv2.warpPerspective 计算透视变换后的图像
现在的目标是将图像由前视图转化为鸟瞰图,根据先验知识,在鸟瞰图下,长方形物体显示出来肯定是长方形,因此,我们只要在前视图中找到一个正方形的物体,并指定他在俯视图中的坐标就可以了,这里有个但是,由于先验信息里面只有矩形这个信息,具体的长宽比什么的,以及实际的大小未知,所以转化到鸟瞰图下并不能反应物体的真实长度。这里怎么定义转化后的坐标要自己把握。 - 有相机标定时
这个转化就是真实的了,因为知道相机的内参,还有相机的pitch角以及相机距离地面的高度。
matlab里面转的,要标定的参数
https://ww2.mathworks.cn/help/driving/ref/birdseyeview.transformimage.html
可以参考的透视变换
https://github.com/ckirksey3/lane-detection-with-opencv