前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Opencv实现透视形变

Opencv实现透视形变

作者头像
小白学视觉
发布2022-02-14 10:32:04
6710
发布2022-02-14 10:32:04
举报

计算机视觉现在很流行,世界各地的人们都在从事某种形式的基于深度学习的计算机视觉项目。但在深度学习出现之前,图像处理技术已被用来处理和转换图像,以获得有助于我们完成任务的见解。今天,让我们看看如何实现一种简单而有用的技术,即透视投影来扭曲图像。

那么扭曲图像是什么意思?我可以用很多花哨的词和技术术语来解释它。但是,展示最终结果很容易,这样我们就可以通过观察来学习。

基础图像——主题图像——扭曲的输出

所以基本上,我们需要拍摄一个图像并剪切它以使其适合任何所需形状的画布。请注意,反过来也是可能的。现在,这已经不成问题了,让我们就来看看如何使用 OpenCV 和 Python 来实现这一点。

在进入代码的主要部分之前,我们必须首先导入必要的库。

代码语言:javascript
复制
import cv2
import numpy as np

现在,让我们按如下方式读取基本图像和主题图像。

代码语言:javascript
复制
base_image = cv2.imread('base_img.jpg')
base_image_copy = base_image.copy()
subject_image = cv2.imread('subject.jpg')

基本图像(左)——主体图像(右)

初始化一个数组来存储我们想要覆盖主题图像的 4 个角的坐标,我们可以使用setMouseCallback()函数手动选择这 4 个点,如下所示。

代码语言:javascript
复制
def click_event(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(base_image_copy, (x, y), 4, (0, 0, 255), -1)
        points.append([x, y])
        if len(points) <= 4:
            cv2.imshow('image', base_image_copy)
points = []
base_image = cv2.imread('base_img.jpg')
base_image_copy = base_image.copy()
subject_image = cv2.imread('subject.jpg')

cv2.imshow('image', base_image_copy)
cv2.setMouseCallback('image', click_event)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面给出的代码片段中,我们定义了一个名为click_event()的函数,并将其作为参数传递给setMouseCallback()函数。使用这种方法,我们将首先显示基础图像,然后我们可以手动选择图像中的四个点作为目标。我们的主题图像会扭曲到这个目标上,按下鼠标左键时记录坐标,这些存储在我们之前初始化的点数组中。选定的点以红点突出显示,如下所示。

选择角点

众所周知,我们每个人都可以按任意顺序选择 4 个点。因此需要在所选点之间保持恒定的排序。我选择以顺时针方式对点进行排序,即从左上到右上,再到右下然后到左下,这是通过如下所示的sort_pts()方法实现的。我们使用以下事实:x 和 y 坐标的总和在左上角最小,在右下角最大。同样,它们之间的差异在右上角最小,在左下角最大。请记住,对于图像,原点位于图像的左上角。

代码语言:javascript
复制
def sort_pts(points):
    sorted_pts = np.zeros((4, 2), dtype="float32")
    s = np.sum(points, axis=1)
    sorted_pts[0] = points[np.argmin(s)]
    sorted_pts[2] = points[np.argmax(s)]

    diff = np.diff(points, axis=1)
    sorted_pts[1] = points[np.argmin(diff)]
    sorted_pts[3] = points[np.argmax(diff)]

    return sorted_pts
sorted_pts = sort_pts(points)

对点进行排序后,让我们用它们来计算变换矩阵。我们创建一个名为“pts1”的 numpy 数组,它保存了主题图像的四个角的坐标。同样,我们创建一个名为“pts2”的列表,其中包含已排序的点。“pts1”的坐标顺序应该与“pts2”坐标的顺序相匹配。

代码语言:javascript
复制
h_base, w_base, c_base = base_image.shape
h_subject, w_subject = subject_image.shape[:2]

pts1 = np.float32([[0, 0], [w_subject, 0], [w_subject, h_subject],                     [0, h_subject]])
pts2 = np.float32(sorted_pts)

现在我们获得了扭曲对象图像所需的变换矩阵。这是使用函数cv2.getPerspectiveTransform() 获得的。由于我们希望以适合我们在基础图像中选择的框的方式变化主题图像,因此“ src ”应为“ pts1 ”,“ dst ”应为“ pts2 ”。生成的图像的大小可以指定为元组。我们确保生成的图像具有基本图像的尺寸。使用生成的矩阵,我们可以使用cv2.warpPerspective()方法扭曲图像,如给定的代码片段所示。

代码语言:javascript
复制
transformation_matrix = cv2.getPerspectiveTransform(pts1, pts2)

warped_img = cv2.warpPerspective(subject_image, transformation_matrix, (w_base, h_base))
cv2.imshow('Warped Image', warped_img)

变形的图像看起来像这样:

变形的图像

下一步是创建一个蒙版,我们为其创建一个具有基本图像形状的空白图像。

代码语言:javascript
复制
mask = np.zeros(base_image.shape, dtype=np.uint8)

初始蒙版

在这个空白蒙版上,我们绘制一个具有由“ sorted_pts ”指定的角的多边形,并使用cv2.fillConvexPoly()方法将其填充为白色,生成的蒙版将如下所示。

代码语言:javascript
复制
roi_corners = np.int32(sorted_pts)

cv2.fillConvexPoly(mask, roi_corners, (255, 255, 255))

填充蒙版

现在我们使用cv2.bitwise_not()方法反转蒙版颜色。

代码语言:javascript
复制
mask = cv2.bitwise_not(mask)

倒置蒙版

现在我们使用cv2.bitwise_and()方法获取蒙版和基础图像并执行按位与运算。

代码语言:javascript
复制
masked_image = cv2.bitwise_and(base_image, mask)

这将为我们提供如下所示的图像。我们可以看到单独放置对象图像的区域是黑色的。

蒙面基础图像

最后一步是使用cv2.bitwise_or()方法获取变形图像和蒙版图像并执行按位或运算,这将生成我们想要完成的融合图像。

代码语言:javascript
复制
output = cv2.bitwise_or(warped_img, masked_image)
cv2.imshow('Fused Image', output)
cv2.imwrite('Final_Output.png', output)
cv2.waitKey(0)
cv2.destroyAllWindows()

我们做到了!我们已经成功地将一张图片叠加到另一张图片上。

融合图像

这是透视变换的一个非常简单的用例。当我们跟踪框架中物体/人物的运动时,可以使用它来生成区域的鸟瞰图。

Github代码连接:

https://github.com/GSNCodes/Image_Overlaying_Using_Perspective_Transform

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档