前文传送门:

「Python 图像处理 OpenCV (1):入门」

「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」

「Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理」

「Python 图像处理 OpenCV (4):图像算数运算以及修改颜色空间」

图像缩放

图像缩放只是调整图像的大小,为此, OpenCV 为我们提供了一个函数 cv.resize() ,原函数如下:

resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)

src 表示的是输入图像,而 dsize 代表的是输出图像的大小,如果为 0 ,则:

$$\texttt{dsize = Size(round(fxsrc.cols), round(fysrc.rows))}$$

dsize 和 fx 、 fy 不能同时为 0 。

fx 、 fy 是沿 x 轴和 y 轴的缩放系数,默认取 0 时,算法如下:

$$\texttt{fx=(double)dsize.width/src.cols}$$

$$\texttt{fy=(double)dsize.height/src.rows}$$

最后一个参数 interpolation 表示插值方式:

  • INTER_NEAREST - 最近邻插值
  • INTER_LINEAR - 线性插值(默认)
  • INTER_AREA - 区域插值
  • INTER_CUBIC - 三次样条插值
  • INTER_LANCZOS4 - Lanczos插值

看一个简单的示例:

import cv2 as cv

#读取图片
src = cv.imread('maliao.jpg')
print(src.shape) #图像缩放
result = cv.resize(src, (300, 150))
print(result.shape) #显示图像
cv.imshow("src", src)
cv.imshow("result", result) #等待显示
cv.waitKey()
cv.destroyAllWindows()

结果如下:

需要注意的是,这里的 (300, 150) 设置的是 dsize 的列数为 300 ,行数为 150 。

同理,我们可以通过设定一个比例进行缩放,可以是等比例缩放,也可以是不等比例缩放,下面是等比例缩放的示例:

import cv2 as cv

# 设定比例
scale = 0.5 #读取图片
src = cv.imread('maliao.jpg')
rows, cols = src.shape[:2] #图像缩放
result = cv.resize(src, ((int(cols * scale), int(rows * scale))))
print(result.shape) #显示图像
cv.imshow("src", src)
cv.imshow("result", result) #等待显示
cv.waitKey()
cv.destroyAllWindows()

结果如下:

除了可通过设定 dszie 对图像进行缩放,我们还可以通过设定 fx 和 fy 对图像进行缩放:

import cv2 as cv

#读取图片
src = cv.imread('maliao.jpg')
print(src.shape) #图像缩放
result = cv.resize(src, None, fx=0.5, fy=0.5)
print(result.shape) #显示图像
cv.imshow("src", src)
cv.imshow("result", result) #等待显示
cv.waitKey()
cv.destroyAllWindows()

结果如下:

图像平移

图像平移是通过仿射函数 warpAffine() 来实现的,原函数如下:

warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

在图像平移中我们会用到前三个参数:

  1. 需要变换的原始图像
  2. 移动矩阵M
  3. 变换的图像大小(如果这个大小不和原始图像大小相同,那么函数会自动通过插值来调整像素间的关系)。

图像的平移是沿着 x 方向移动 tx 距离, y 方向移动 ty 距离,那么需要构造移动矩阵:

$$ M = [\begin{matrix} 1 & 0 & tx \ 0 & 1 & ty \end{matrix}] $$

我们通过 Numpy 来产生这个矩阵(必须是float类型的),并将其赋值给仿射函数 warpAffine() ,下面来看个示例:

import cv2 as cv
import numpy as np #读取图片
src = cv.imread('maliao.jpg')
rows, cols = src.shape[:2] # 定义移动距离
tx = 50
ty = 100 # 生成 M 矩阵
affine = np.float32([[1, 0, tx], [0, 1, ty]])
dst = cv.warpAffine(src, affine, (cols, rows)) # 显示图像
cv.imshow('src', src)
cv.imshow("dst", dst) # 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

结果如下:

注意: warpAffine 函数的第三个参数是输出图像的大小,我这里设置的大小是原图片的大小,所以结果会有部分遮挡。

图像旋转

图像旋转主要调用 getRotationMatrix2D() 函数和 warpAffine() 函数实现,绕图像的某一个中心点旋转,具体如下:

  • M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)

    参数分别为:旋转中心、旋转度数、scale

  • rotated = cv2.warpAffine(src, M, (cols, rows))

    参数分别为:原始图像、旋转参数、原始图像宽高

图像旋转:设( x0 , y0 )是旋转后的坐标,( x , y )是旋转前的坐标,( m , n )是旋转中心, a 是旋转的角度(顺时针),( left , top )是旋转后图像的左上角坐标,则公式如下:

$$ \begin{bmatrix}x0 & y0 & 1\end{bmatrix} = \begin{bmatrix}x & y & 1\end{bmatrix} \begin{bmatrix}1 & 0 & 0 \ 0 & -1 & 0 \ -m & n & 1\end{bmatrix} \begin{bmatrix}\cos a & -\sin a & 0 \ \sin a & \cos a & 0 \ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \ 0 & -1 & 0 \ left & top & 1 \end{bmatrix}$$

上面这个公式具体的推导过程可以参考这篇文章:https://www.cnblogs.com/xuanyuyt/p/7112876.html

示例如下:

import cv2 as cv

#读取图片
src = cv.imread('maliao.jpg') # 原图的高、宽
rows, cols = src.shape[:2] # 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
M = cv.getRotationMatrix2D((cols/2, rows/2), 90, 1)
#
dst = cv.warpAffine(src, M, (cols, rows)) # 显示图像
cv.imshow("src", src)
cv.imshow("dst", dst) # 等待显示
cv.waitKey()
cv.destroyAllWindows()

结果如下:

图像翻转

第一个图像翻转,这个可是制作表情包的利器。

图像翻转在 OpenCV 中调用函数 flip() 实现,原函数如下:

flip(src, flipCode, dst=None)
  • src:原始图像。
  • flipCode:翻转方向,如果 flipCode 为 0 ,则以 X 轴为对称轴翻转,如果 fliipCode > 0 则以 Y 轴为对称轴翻转,如果 flipCode < 0 则在 X 轴、 Y 轴方向同时翻转。

示例如下:

import cv2 as cv
import matplotlib.pyplot as plt # 读取图片 由 GBR 转 RGB
img = cv.imread('maliao.jpg')
src = cv.cvtColor(img, cv.COLOR_BGR2RGB) # 图像翻转
# flipCode 为 0 ,则以 X 轴为对称轴翻转,如果 fliipCode > 0 则以 Y 轴为对称轴翻转,如果 flipCode < 0 则在 X 轴、 Y 轴方向同时翻转。
img1 = cv.flip(src, 0)
img2 = cv.flip(src, 1)
img3 = cv.flip(src, -1) # plt 显示图形
titles = ['Source', 'Ima1', 'Ima2', 'Ima3']
images = [src, img1, img2, img3] for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(images[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([]) plt.show()

结果如下:

示例代码

如果有需要获取源码的同学可以在公众号回复「OpenCV」进行获取。

参考

https://blog.csdn.net/Eastmount/article/details/82454335

https://www.cnblogs.com/korbin/p/5612427.html

http://www.woshicver.com/

Python 图像处理 OpenCV (5):图像的几何变换的更多相关文章

  1. Python 图像处理 OpenCV (6):图像的阈值处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  2. Python 图像处理 OpenCV (14):图像金字塔

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  3. Python 图像处理 OpenCV (15):图像轮廓

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  4. Python 图像处理 OpenCV (16):图像直方图

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  5. Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 图像属性 图像 ...

  6. Python 图像处理 OpenCV (4):图像算数运算以及修改颜色空间

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  7. Python 图像处理 OpenCV (7):图像平滑(滤波)处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  8. Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  9. Python 图像处理 OpenCV (10):图像处理形态学之顶帽运算与黑帽运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

随机推荐

  1. AMD 开源照片级渲染引擎 Radeon ProRender

    除了Radeon Pro WX.Radeon Pro Solid State两款全新的专业显卡,AMD今天还宣布,Radeon ProRender渲染引擎即将开放源代码,开发人员可任意使用.AMD去年 ...

  2. Linux下实现文件共享配置[samba]

    Linux下实现文件共享配置[samba] 第一步:安装samba软件 1.命令:rpm –q samba #查询是否已安装sambayum install samba #使用yum源安装samba, ...

  3. salesforce零基础学习(九十七)Event / Task 针对WhoId的浅谈

    我们在Sales Cloud中经常会创建顾客,如果针对TO C业务,会启用个人顾客,比如针对车企行业,有一些场景是需要卖给个人的,而不只是企业采购.当通过打电话或者其他的场景有潜在客户并且转换成客户以 ...

  4. 001_python变量,if,while

    Python介绍 python的出生与应用 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时间, ...

  5. Hexo+GitHub Actions 完美打造个人博客

    Hexo简介 Hexo是一款基于Node.js的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在GitHub和Coding上,是搭建博客的首选框架.大家可以进入hexo官网进行详细查看, ...

  6. ubuntu文件系统修改( for arm)

    系统:ubuntu14.04 镜像:ubuntu-rootfs.img for aarch64 创建一个文件夹 ubuntu-mount mkdir ubuntu-mount 将ubuntu-root ...

  7. 移动端H5支付(微信和支付宝)

    我们直接进入主题吧,先说功能: 1.用户通过我们的页面输入充值帐号和金额调起支付(微信或者支付宝),支付成功返回获取支付结果. 2.微信支付成功后重定向到指定页面(没有设置重定向地址的话,默认返回调起 ...

  8. 浅谈mybatis如何半自动化解耦和ORM实现

    在JAVA发展过程中,涌现出一系列的ORM框架,JPA,Hibernate,Mybatis和Spring jdbc,本系列,将来研究Mybatis. 通过研究mybatis源码,可将mybatis的大 ...

  9. WEB程序报错Address localhost:1099 is already in use的解决方案(网络端口被占用导致程序无法运行)

    首先,这是说明你的本地端口1099已经被占用了,解决的方法有两个: 1.停止本地占用端口 打开cmd 按如下指令进行命令输入,就能找出占用端口的进程并停止啦 2.修改程序运行端口 一个问题,两种解决办 ...

  10. JAVA异常以及字节流

    异常 JAVA异常可以分为编译时候出现的异常和执行时候出现的异常 JVM默认处理异常的方法是抛出异常 异常处理 //第一种 try{ 可能会出错的代码 }catch{ 发生异常后处置方法 }final ...