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 个小时(貌似不太够)你有所收获,我们下篇博客见~
博主 ID:梦想橡皮擦,希望大家<font color="red">点赞</font>、<font color="red">评论</font>、<font color="red">收藏</font>。
评论