>>> 点击进入:OpenCV专栏<<<
手工标定转换的位置→设置鸟瞰图对应的位置→生成转化矩阵(生成正向和反向转化矩阵)
参考博客:几何变换
# -*- coding:utf-8 -*-
'''
@Author: knocky
@Blog: https://blog.csdn.net/zzx188891020
@E-mail: [email protected]
@File: perspect_transform.py
@CreateTime: 2020/6/10 8:29
'''
import cv2
import numpy as np
# 透视变换
# 获取透视变换的参数矩阵
def cal_perspective_params(img, points):
offset_x = 330
offset_y = 0
img_size = (img.shape[1], img.shape[0])
src = np.float32(points)
# 设置俯视图中的对应的四个点
dst = np.float32([[offset_x, offset_y], [img_size[0] - offset_x, offset_y],
[offset_x, img_size[1] - offset_y], [img_size[0] - offset_x, img_size[1] - offset_y]])
# 原图像转换到俯视图
M = cv2.getPerspectiveTransform(src, dst)
# 俯视图到原图像
M_inverse = cv2.getPerspectiveTransform(dst, src)
return M, M_inverse
# 根据参数矩阵完成透视变换
def img_perspect_transform(img, M):
img_size = (img.shape[1], img.shape[0])
return cv2.warpPerspective(img, M, img_size)
if __name__ == '__main__':
# 设置透视变换的点
# 这里的图片最好是两条直线,最后在图像中相交到灭点。如果是弧线,容易有偏差
img = cv2.imread('../test/straight_lines2.jpg')
# 这几个点是人工选择的,所以需要自己调整
points = [[601, 448], [683, 448], [230, 717], [1097, 717]]
img = cv2.line(img, (601, 448), (683, 448), (0, 0, 255), 3)
img = cv2.line(img, (683, 448), (1097, 717), (0, 0, 255), 3)
img = cv2.line(img, (1097, 717), (230, 717), (0, 0, 255), 3)
img = cv2.line(img, (230, 717), (601, 448), (0, 0, 255), 3)
cv2.imshow('img',img)
cv2.imwrite('./perspect_img/img_line.jpg',img)
M, M_inverse = cal_perspective_params(img, points)
# 这里只针对透视变化功能,相机去畸变的功能跳过
trasform_img = img_perspect_transform(img, M)
cv2.imshow('trasform_img',trasform_img)
cv2.waitKey(0)
cv2.imwrite('./perspect_img/trasform_line_img.jpg',trasform_img)
img = cv2.imread('./pipline_img/color_binary.jpg')
# 保存输出二值图的鸟瞰图
img_transform = img_perspect_transform(img,M)
cv2.imwrite('./perspect_img/img_transform.jpg', img_transform)
points = [[601, 448], [683, 448], [230, 717], [1097, 717]]这四个点的顺序一定是左上、右上、左下、右下。
不然转换出来的就是错的
自己标定的点画出的线,建议尽量使用透视图为直线的车道线,也就是两线相交于灭点。
转化前后对比效果