Python OpenCV 图像的几何变换,先说不平凡的 resize 函数
Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 41 篇。
基础知识铺垫
在 OpenCV 中常见的几何变换有缩放,仿射,透视变换,之前的内容中已经学习过缩放函数了,今天一边复习旧知识,一边学习新知识。
先看一下三个几何变换对应的函数原型是:
先从缩放说起,函数名为 cv2.resize()
,非空参数有 2 个,分别是 src
与 dsize
,含义为源图像与缩放后图像的尺寸。
上述为最简单的代码,运行效果如下,实现了一个简单的变化
该案例会出现一个常见的错误,缩放的数值提供的是浮点类型,错误提示为
还有需要注意的是,元组 dsize
的两个值说明如下,顺序不要记错。
这个地方深究下去,其实需要记忆的细节很多,例如在笛卡尔坐标系里面,记录一个坐标点都是先 x 轴,后 y 轴,但是在计算机中,图像是以矩阵的形式保存的,先行后列,所以 宽x高x通道
的图片会保存在 高x宽x通道
的三位数组中,在图像处理的时候,都是按照 高x宽x通道
记忆,例如通过 shape
获取形状。
输出的结果就是 (高,宽,通道)
,但是这一点 resize
函数没有遵守,它依旧采用的是 (宽,高)
设置。
fx
,fy
为图像x
,y
方向的缩放比例,使用该参数,需要提前将 dsize
设置为 (0,0)
,测试代码如下:
测试结果为,如果不提前设置 dsize
为 (0,0)
,那 fx
与 fy
不会生效。注意 dsize=(0,0)
,如果数据类型不对,会出现如下错误:
interplolation 缩放时的插值方式
interplolation 为缩放时的插值方式,有以下几种方式,这些是今天要探索的重点内容。
cv.INTER_NEAREST
:最近邻插值;cv.INTER_LINEAR
:双线形插值(默认设置);cv.INTER_CUBIC
:4x4 像素邻域的双三次插值;cv2.INTER_AREA
:基于局部像素的重采样。它可能是图像抽取的首选方法,因为它会产生无云纹理的结果。 但是当图像缩放时,它类似于INTER_NEAREST
方法。
最近邻插值
这部分比较吃精力,所以今天这一个小时,我们争取搞定一个插值算法,即最近邻插值就好。
这个算法的思想是,通过已经像素值去获取目标像素值。我在学习的时候找到最通俗的解释,接下来由我说明给你。
假设有一个 3x3 的灰度图,需要通过最近邻插值算法,得到一个 4x4 的灰度图。
先通过坐标系去了解像素在缩放的时候的变化。
上图中最后可以到的结论是:
目标像素的 x 值 = 原像素的 x 值 * 倍数;
目标像素的 y 值 = 原像素的 y 值 * 倍数;
本案例的倍数是多少呢?很容易计算,原来的图像是 3x3,现在是 4x4,那倍数在 x,y
上都是 4/3 = 0.75
。
先看一下运算之后得到的结果如下所示:
这里列举两个点的像素值计算,拿目标图像 4x4灰度图
中的 (3,0)
与 (3,3)
两个点进行说明。
(3x0)
点的值等于(3 x 0.75 ≈ 2,0 x 0.75 = 0)
,原图像(2,0)
点的颜色为222
。(3x3)
点的值等于(3 x 0.75 ≈ 2,3 x 0.75 ≈ 2)
,原图像(2,2)
点的颜色为45
;
掌握了原理之后,就可以自己实现这个算法了,首先看一下 OpenCV 内置的函数实现结果。
运行之后发现确实官方的算法更优一些。
橡皮擦的小节
希望今天的 1 个小时你有所收获,我们下篇博客见~
版权声明: 本文为 InfoQ 作者【梦想橡皮擦】的原创文章。
原文链接:【http://xie.infoq.cn/article/f7609f0d9f8b28f1a40c587e1】。文章转载请联系作者。
评论