【小应用】使用OpenCV进行图片鸟瞰转换(俯视图)

鸟瞰转换效果图

引言

  本博客是翻墙阅读其他博客的翻译。利用OpenCV的v2.getPerspectiveTransform()、cv2.warpPerspective()函数,实现图片的鸟瞰转换。
  OpenCV 和 Python版本满足:Python 2.7/Python 3.4+ 和 OpenCV 2.4.X/OpenCV 3.0+.
  代码地址:https://github.com/wangwangwang97/GitProject/tree/master/get-perspective-transform-example

示例

  之前的文章:构建真实Pokedexhttps://pyimagesearch.com/2014/05/05/building-pokedex-python-opencv-perspective-warping-step-5-6/提到了用透视变换来获得图像的自顶向下的‘鸟瞰图’,前提是找到参考点。
  本篇文章:继续对图像的自上而下的‘鸟瞰’进行讨论,但这次会分享进行四点转换时的代码。

代码1:order_points函数

  将四个点坐标表示为有序列表的形式
在这里插入图片描述

  • 代码2-3行:导入所需的包,numpy包用于数值计算,cv2包用于绑定OpenCV。
  • 代码第5行:定义order_points函数,这个函数只有一个参数,即pts,它包含矩形的四个(x,y)形式点的坐标。
  • 代码第10行:创建一个有序列表rect用于有序的存储四个矩形点坐标(列表中矩形点的顺序很重要,事实上在实际项目中只要保持顺序一致即可,个人喜欢的顺序为左上、右上、右下和左下)
  • 代码14-16行:在矩形中,左上角点会有最小的x+y总和,右下角点会有最大的x+y总和,通过这个信息为有序列表添加左上角rect[0]和右下角rect[2]元素。
  • 代码第21行:计算点的差异,即(x-y),这一操作可以通过np.diff实现。
  • 代码第22-23行:差异最小的是右上角的点,差异最大的是左下角,通过这个信息为有序列表添加右上角rect[1]和左下角rect[3]元素
  • 代码第26行:返回原始点(pts)的有序列表
代码2:four_point_transform函数

  透视图转鸟瞰图
在这里插入图片描述

  • 代码第28行:定义four_point_transform函数,需要两个参数,image和pts。image是我们将要应用透视变换的图像,pts是我们想要转换的图像中的感兴趣区域的四个点列表。
  • 代码第31-32行:调用代码1的函数,将pts中的坐标点变为有序,并获取每个点的坐标。
  • 代码第37-39行:确定新图像的宽度,其中宽度是右下角和左下角x坐标或右上角和左上角x坐标的距离,选择最大距离为新图像的宽。
  • 代码第44-46行:确定新图像的高度,其中高度是左上角和左下角y坐标或右上角和右下角y坐标之间的最大距离,选择最大距离为新图像的高。
  • 代码第53-57行:定义四个点组成的列表dst,代表自顶向下表示的图像。第一个元素为(0,0)代表左上角,第二个元素为(maxWidth - 1, 0)代表右上角坐标,第三个元素为(maxWidth - 1, maxHeight - 1)代表右下角,第四个元素为(0, maxHeight - 1)代表左下角。
  • 代码第60行:使用cv2.getPerspectiveTransform函数,此函数需要两个参数:rect(四个感兴趣点坐标组成的列表),dst(想让四个感兴趣点转换后的坐标位置组成的列表)。这个函数将返回一个转换矩阵M.
  • 代码第61行:使用cv2.warpPerspective函数,参数为:图像、转换矩阵M、输出图片的宽度和高度。
  • 代码第64行:返回自顶向下的视图。
代码3:驱动代码

  图片调用转换函数的驱动代码
在这里插入图片描述

  • 代码第2行:导入我们定义的four_point_transform函数。
  • 代码第3-5行:导入其他所需要的包,NumPy用于数组功能, argparse 用于解析命令行参数, cv2 用于OpenCV绑定。
  • 代码第8-12行:解析命令行参数,使用两个开关:–image表示我们将要转换的图像,–coords是四个点的列表,这些点代表我们想要获得鸟瞰视角的图像区域的坐标点。
  • 代码第19行:加载图像
  • 代码第20行:加载坐标点,并转换为numpy数组形式。
  • 代码第24行:应用透视变换
  • 代码第27-29行:展示原图和透视变换后的图。
      本文中需要自己选择需要透视变换的四个点的坐标(即感兴趣区域的四个点坐标,rect)有一些自动确定透视变换所需4个点的方法(如角点检测、边缘检测等),而无需人工操作,这里就不进行陈述。
代码运行

  在shell中执行:

python transform_example.py --image images/example_03.png --coords "[(63, 242), (291, 110), (361, 252), (78, 386)]"

在这里插入图片描述

  • 7
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于使用OpenCV处理棋盘格鸟瞰图,你可以按照以下步骤进行操作: 1. 首先,使用OpenCV的摄像头校准功能来获取相机的内部参数和畸变系数。这可以通过拍摄一系列棋盘格图像并使用`cv2.calibrateCamera()`函数来完成。 2. 然后,在获取到相机的内部参数后,你可以使用`cv2.undistort()`函数来校正图像的畸变。 3. 接下来,通过对校正后的图像进行透视变换,将其转换鸟瞰图。透视变换需要定义一个转换矩阵,可以通过OpenCV的`cv2.getPerspectiveTransform()`函数来获得。 4. 使用获得的透视变换矩阵,可以使用`cv2.warpPerspective()`函数将图像转换鸟瞰图。 下面是一个示例代码,展示了如何使用OpenCV处理棋盘格鸟瞰图: ```python import cv2 import numpy as np # 标定棋盘格参数 rows = 6 cols = 9 square_size = 1 # 棋盘格角点坐标 objp = np.zeros((rows*cols, 3), np.float32) objp[:, :2] = np.mgrid[0:cols, 0:rows].T.reshape(-1, 2) * square_size # 存储棋盘格角点的世界坐标和图像坐标 objpoints = [] # 世界坐标 imgpoints = [] # 图像坐标 # 根据摄像头拍摄的棋盘格图像进行标定 def calibrate_camera(): # 读取棋盘格图像 images = glob.glob('chessboard/*.jpg') for fname in images: img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 寻找棋盘格角点 ret, corners = cv2.findChessboardCorners(gray, (cols, rows), None) if ret == True: objpoints.append(objp) imgpoints.append(corners) # 校准相机 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) return mtx, dist # 校正图像的畸变 def undistort_image(image, mtx, dist): undistorted_img = cv2.undistort(image, mtx, dist, None, mtx) return undistorted_img # 获取透视变换矩阵 def get_perspective_transform(image): # 定义棋盘格四个角点的像素坐标 src_points = np.float32([(x, y) for y in range(0, rows) for x in range(0, cols)]) # 定义鸟瞰图四个角点的像素坐标 dst_points = np.float32([[0, 0], [cols-1, 0], [cols-1, rows-1], [0, rows-1]]) # 计算透视变换矩阵 M = cv2.getPerspectiveTransform(src_points, dst_points) return M # 将图像转换鸟瞰图 def transform_to_birdseye(image, M): birdseye_img = cv2.warpPerspective(image, M, (cols, rows)) return birdseye_img # 主程序 if __name__ == '__main__': # 读取原始图像 image = cv2.imread('chessboard_image.jpg') # 相机校准 mtx, dist = calibrate_camera() # 校正图像的畸变 undistorted_img = undistort_image(image, mtx, dist) # 获取透视变换矩阵 M = get_perspective_transform(undistorted_img) # 将图像转换鸟瞰图 birdseye_img = transform_to_birdseye(undistorted_img, M) # 显示结果 cv2.imshow('Original Image', image) cv2.imshow('Undistorted Image', undistorted_img) cv2.imshow('Birdseye Image', birdseye_img) cv2.waitKey(0) ``` 请确保你已经准备好了标定棋盘格图像,并将其存储在`chessboard/`文件夹中,原始图像命名为`chessboard_image.jpg`。你可以根据自己的需求修改代码中的参数和路径。该代码将显示原始图像、校正后的图像和鸟瞰图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值