取经之旅第 55 天,Python OpenCV 透视变换前置知识轮廓坐标点

举报
梦想橡皮擦 发表于 2021/09/24 14:16:51 2021/09/24
【摘要】 Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 55 篇。 学在前面正式学习之前,先将上一篇 博客的内容回顾一下,通过一系列的轮廓操作,得到了目标图像的轮廓。本篇博客的目标将逐步实现对其进行透视变换。 获取轮廓的四个顶点坐标上篇博客已经获取到了轮廓坐标,但是每个坐标对应的位置是不确定的,需要通过计算将其明确出来。轮廓坐标从三维修改为二维cv...

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 55 篇。

学在前面

正式学习之前,先将上一篇 博客的内容回顾一下,通过一系列的轮廓操作,得到了目标图像的轮廓。

本篇博客的目标将逐步实现对其进行透视变换。

获取轮廓的四个顶点坐标

上篇博客已经获取到了轮廓坐标,但是每个坐标对应的位置是不确定的,需要通过计算将其明确出来。
轮廓坐标从三维修改为二维

cv.drawContours(src, [screen_cnt], -1, (0, 0, 255), 2)

print(screen_cnt)
print(screen_cnt.shape)
print(screen_cnt.reshape(4, 2))

代码运行效果如下,图片不同得到的数值不同。

[[[ 30  94]]
 [[ 17 273]]
 [[469 278]]
 [[462 106]]]
(4, 1, 2)
[[ 30  94]
 [ 17 273]
 [469 278]
 [462 106]]

坐标转换之后,对应到图片的位置如下图所示。

一般情况下,我们描述一个矩形区域,在 OpenCV 中,采用的是 左上,右上,右下,左下 顺时针顺序,所以接下来需要对这四个坐标进行转换。

声明一个函数进行相应的计算工作。

def change_points(input_points):
	pass

# 函数调用
change_points(screen_cnt.reshape(4, 2))

计算 4 个点横纵坐标之和

def change_points(input_points):
    s = input_points.sum(axis=1)
    print(s)

核心用到的是 numpy 中的 sum 函数,注意 axis 轴参数,0 表示竖向,1 表示横向,这里的横向就是该点的横纵坐标之和。

对于一个矩形区域,左上点与右下点分别是横纵坐标之和最小的点与最大的点,基于此,继续完善代码。

下述代码使用了 np.argmin()np.argmax() 函数,可以通过搜索引擎进行快速学习。

def change_points(input_points):
    s = input_points.sum(axis=1)
    p1 = input_points[np.argmin(s)]
    p3 = input_points[np.argmax(s)]
    print(p1,p3)

得到的数据如下:

[[ 30  94]
 [ 17 273]
 [469 278]
 [462 106]]
[30 94] [469 278]

左下点与右上点的计算方式为,使用 np.diff() 函数,计算横纵坐标之差最小找到右上角的点,横纵坐标之差最大找到左下角的点。对应下图可以辅助理解,左下点 300-100 = 200,右上点 100-400 = -300

def change_points(input_points):
    s = input_points.sum(axis=1)
    p1 = input_points[np.argmin(s)]
    p3 = input_points[np.argmax(s)]
    print(p1,p3)

    diff = np.diff(input_points,axis=1)
    p2 = input_points[np.argmin(diff)]
    p4 = input_points[np.argmax(diff)]
    print(p2,p4)

此时,4 个坐标都已经获取到,最后声明一个空矩阵,赋值之后进行返回。

def change_points(input_points):
    s = input_points.sum(axis=1)
    p1 = input_points[np.argmin(s)]
    p3 = input_points[np.argmax(s)]

    diff = np.diff(input_points, axis=1)
    p2 = input_points[np.argmin(diff)]
    p4 = input_points[np.argmax(diff)]

    # 声明一个所有元素都为 0 的矩阵
    rect = np.zeros((4, 2), dtype="float32")
    rect[0] = p1
    rect[1] = p2
    rect[2] = p3
    rect[3] = p4
    print(rect)
    return rect
change_points(screen_cnt.reshape(4, 2))

坐标数值与图片对应位置如下:

橡皮擦的小节

希望今天的 1 个小时(貌似不太够)你有所收获,我们下篇博客见~

相关阅读

  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 游戏世界(更新中,目标文章数 50+,现在订阅,都是老粉)
  3. Python 爬虫小课,精彩 9 讲

今天是持续写作的第 115 / 200 天。
如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。