OpenCV实现透视变换的示例代码

 更新时间:2023年07月07日 09:22:33   作者:赵卓不凡  
本文主要介绍了OpenCV实现透视变换的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 引言

今天我们将焦点聚焦在我在图像处理中最喜欢的话题之一——透视变换。使用该技术,可以灵活方便的实现各种各样好玩的特效。

闲话少说,我们直接开始吧!

2. 单应矩阵

我们首先展开对单应矩阵的深入研究。作为图像处理的基本工具,它在捕捉图像中的几何变换方面发挥着至关重要的作用。更具体地说,它是实现透视变换的秘密武器。

单应矩阵被定义为图像的两个平面投影之间的映射。它由齐次坐标空间中的3x3变换矩阵表示。这些变换可以是旋转、平移、缩放等操作的组合。

我们用示意图总结如下:

3. 举个栗子

虽然上图简明地定义了常见的转换,但是如果我们将其应用到输入和输出为图像操作会怎样?根据变换,我们需要几个点来计算单应矩阵。让我们来做吧!像往常一样,让我们首先导入必要的库,如下:

# Import libraries
from skimage.io import imread, imshow
import matplotlib.pyplot as plt
import numpy as np
from skimage import transform

接着导入我们需要的测试图像,代码如下:

# Display the original image
image = imread('painting.png')
plt.figure(figsize=(20,20))
plt.imshow(image)
plt.title('Original Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()

结果如下:

4. 计算变换矩阵

接着我们想对这幅画有一个自上而下的视图。我们需要计算单应矩阵。我们必须确定这幅画明确的角点。在这种情况下,我使用画图应用程序来识别画的四个角点坐标:

# Source points
src = np.array([879, 625,                    # top left
                431, 2466,                   # bottom left
                3251, 61,                    # top right
                3416, 2767]).reshape((4, 2)) # bottom right

为了执行单应性变换,我们需要一组与源点相对应的目标点。这些目标点表示我们希望源点在输出图像中的位置。对于自上而下的视图,这里我们引用源点的最小值和最大值x和y:

# Destination points
dst = np.array([
    [np.min(src[:, 0]), np.min(src[:, 1])],  # top left
    [np.min(src[:, 0]), np.max(src[:, 1])],  # bottom left
    [np.max(src[:, 0]), np.min(src[:, 1])],  # top right
    [np.max(src[:, 0]), np.max(src[:, 1])],  # bottom right
])

接着我们用以下代码计算单应矩阵,如下:

tform = transform.estimate_transform('projective', src, dst)

5. 透视变换

经过上述处理,我们有了执行透视变换所需要的单应性矩阵,接着我们来执行对应的透视变换,如下:

tf_img = transform.warp(image, tform.inverse)
fig, ax = plt.subplots(figsize=(20,20))
ax.imshow(tf_img)
_ = ax.set_title('projective transformation')

得到结果如下:

6. 美化显示效果

观察上图,考虑到图像外围添加了白色像素,输出看起来很奇怪,我们可以编辑出代码来裁剪这些奇怪的墙和额外的像素:

# Load the image
image = imread('painting.png')
# Source points
src = np.array([879, 625,                    # top left
                431, 2466,                   # bottom left
                3251, 61,                    # top right
                3416, 2767]).reshape((4, 2)) # bottom right
# Estimate the width and height from the source points
width = np.max(src[:, 0]) - np.min(src[:, 0])
height = np.max(src[:, 1]) - np.min(src[:, 1])
# Destination points (forming a box shape)
dst = np.array([
    [0, 0],
    [0, height],
    [width, 0],
    [width, height]
])
# Compute the projective transform
tform = transform.estimate_transform('projective', src, dst)
# Apply the transformation
warped_image = transform.warp(image, tform.inverse, output_shape=(height, width))
# Convert the warped image to uint8
warped_image_uint8 = (warped_image * 255).astype(np.uint8)
# Display the transformed and cropped image
plt.figure(figsize=(20,20))
plt.imshow(warped_image_uint8)
plt.title('Transformed and Cropped Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()

最终的显示效果如下:

7. 总结

经过我们一步一步的优化,我们最终得到了,一幅美丽而干净的自上而下的油画。一般来说,一旦我们有了单应矩阵,我们也可以用它来变换一幅图像,使其与另一幅图像的视角对齐。这对于图像拼接等应用非常有用!

到此这篇关于OpenCV实现透视变换的示例代码的文章就介绍到这了,更多相关OpenCV 透视变换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Pyinstaller打包exe文件详细图文教程

    使用Pyinstaller打包exe文件详细图文教程

    PyInstaller可以用来打包python应用程序,打包完的程序就可以在没有安装Python解释器的机器上运行了,下面这篇文章主要给大家介绍了关于使用Pyinstaller打包exe文件的详细图文教程,需要的朋友可以参考下
    2022-08-08
  • python实现图像全景拼接

    python实现图像全景拼接

    这篇文章主要为大家详细介绍了python实现图像全景拼接,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Python tkinter padx参数详解

    Python tkinter padx参数详解

    这篇文章主要介绍了tkinter padx参数,帮助大家更好的理解和学习,感兴趣的朋友可以了解下,希望能够给你带来帮助
    2021-10-10
  • 在Windows系统上搭建Nginx+Python+MySQL环境的教程

    在Windows系统上搭建Nginx+Python+MySQL环境的教程

    这篇文章主要介绍了在Windows系统上搭建Nginx+Python+MySQL环境的教程,文中使用flup中间件及FastCGI方式连接,需要的朋友可以参考下
    2015-12-12
  • 对Keras自带Loss Function的深入研究

    对Keras自带Loss Function的深入研究

    这篇文章主要介绍了对Keras自带Loss Function的深入研究,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • numpy.transpose对三维数组的转置方法

    numpy.transpose对三维数组的转置方法

    下面小编就为大家分享一篇numpy.transpose对三维数组的转置方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • Python 获得13位unix时间戳的方法

    Python 获得13位unix时间戳的方法

    本篇文章主要介绍了Python 获得13位unix时间戳的方法,非常具有实用价值,需要的朋友可以参考下
    2017-10-10
  • 基于Python实现银行卡识别的示例代码

    基于Python实现银行卡识别的示例代码

    银行卡识别是一个在金融、安全等领域具有重要应用的问题,本文主要为大家介绍了如何使用Python和深度学习技术来实现银行卡识别功能,需要的可以参考下
    2024-03-03
  • Python如何使用matplotlib绘制柱状图

    Python如何使用matplotlib绘制柱状图

    这篇文章主要介绍了Python如何使用matplotlib绘制柱状图问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • Python实现FLV视频拼接功能

    Python实现FLV视频拼接功能

    这篇文章主要介绍了Python实现FLV视频拼接功能,本文给大家介绍的非常详细具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01

最新评论