详解Python+OpenCV对图像进行几何变换操作

OpenCV是一个用于计算机视觉和图像操作的免费开源库,有数千种优化的算法和函数用于各种图像操作。本文将使用OpenCV在Python中进行一些图像操作。

Opencv介绍:

  • 开源发行的跨平台计算机视觉库,是数字图像处理和计算机视觉领域非常常见的工具包

  • 安装:打开终端/命令行cmd/虚拟环境,

    使用命令:pip install opencv-contrib-python 或 pip install opencv-python
    使用清华镜像源:pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

图像处理基础

  • 数字图像概念
    数字图像:又称数码图像,一幅二维图像可以由一个数组或矩阵表示。数字图像可以理解为一个二维函数f(x,y),其中x和y是空间(平面)坐标,而在任意坐标出的值f称为图像在该点处的强度或灰度。
    图像处理的目的:改善图示的信息便于人们理解,有利于存储、传输和表示。
    详解Python+OpenCV对图像进行几何变换操作_第1张图片

  • 数字图像的应用
    传统领域:医学,空间应用,生物学,军事
    最新领域:数码相机,指纹识别,人脸识别,图像检索,游戏,电影特技等;
    图像处理、机器视觉、人工智能关系

    • 图像处理主要研究二维图像,处理一个图像或一组图像之间的相互转换过程,包括图像滤波、图像识别、图像分割等;

    • 计算机视觉主要研究映射到单幅或多幅图像上的三维场景,从图像中提取抽象的语义信息,实现图像理解是计算机视觉的追求目标;

    • 人工智能在计算机视觉上的目标就是解决像素值和语义之间关系,主要的问题又图片检测、图片识别、图片分割和图片检索等。

图像属性

  • 图像格式

    • BMP格式:Windows系统下的标准位图格式,未经过压缩,一般图像文件比较大

    • JPEG格式:应用最广泛的格式之一,它采用一种特殊的有损压缩算法,达到较大的压缩比(可达到2:1甚至40:1)

    • GIF格式:可以是一张静止的图片,也可以是动画,支持透明背景图像,适用于多种操作系统,“体型”很小。但是其色域不太广,只支持256种颜色。

    • PNG格式:与JPG格式类似,压缩比高于GIF,支持图像透明,支持Alpha通道调节图像的透明度。

    • TIFF:特点是图像格式复杂,存储信息多,在Mac中广泛使用,非常有利于原稿的复制。很多地方将TIFF格式用于印刷。

  • 图像尺寸

    • 图像尺寸的长度和宽度以像素为单位。
    • 像素(pixel):像素是数码影像最基本的单位,每个像素就是一个小点,不同颜色的点聚集起来即成为一幅图片。灰度像素点数值范围在0到255之间,0表示黑,255表示白,其他值表示处于黑白之间;
    • 彩色图用红、绿、蓝三通道的二维矩阵来表示。每个数值也是在0~255之间,0表示相应的基色,而255则表示相应的基色在该像素中取得最大值。
  • 图像分辨率和通道

    • 分辨率:单位长度中的像素数目。每英寸图像中的像素点数,单位是像素每英寸(PPI)。图像分辨率越高,像素的点密度越高,图像越清晰。
    • 通道数:图像的位深度,是指描述图像中每个pixel数值所占的二进制数。位深度越大则图像能表示的颜色数就越多,色彩越丰富逼真。
    • 8位:单通道图像,也就是灰度图,灰度值范围2^8=256
    • 24位:三通道3*8=24
    • 32位:三通道加透明度Alpha通道
      详解Python+OpenCV对图像进行几何变换操作_第2张图片

opencv图像处理

  • 显示图像

    img1 = cv.imread("image.png")
    cv.imshow("orignal", img1)
    cv.waitKey(0)
    
  • 图像缩放

    缩放是对图像的大小进行调整,即使图像放大或缩小。

    API

    cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
    

    参数:

    src : 输入图像

    dsize: 绝对尺寸,直接指定调整后图像的大小

    fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可

    interpolation:插值方法

详解Python+OpenCV对图像进行几何变换操作_第3张图片

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 读取图片
img1 = cv.imread("image.png")
# 2.图像缩放
# 2.1 绝对尺寸
rows, cols = img1.shape[:2]
res = cv.resize(img1, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC)
# 2.2 相对尺寸
res1 = cv.resize(img1, None, fx=0.5, fy=0.5)
# # 3 图像显示
# # 3.1 使用opencv显示图像(不推荐)
# cv.imshow("orignal", img1)
# cv.imshow("enlarge", res)
# cv.imshow("shrink)", res1)
# cv.waitKey(0)

# 3.2 使用matplotlib显示图像
plt.rcParams['font.family'] = 'SimHei' #使用黑体
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(res[:, :, ::-1])
axes[0].set_title("绝对尺度(放大)")
axes[1].imshow(img1[:, :, ::-1])
axes[1].set_title("原图")
axes[2].imshow(res1[:, :, ::-1])
axes[2].set_title("相对尺度(缩小)")
plt.show()

详解Python+OpenCV对图像进行几何变换操作_第4张图片

  • 图像平移
    图像平移将图像按照指定方向和距离,移动到相应的位置。
    API
    cv.warpAffine(img,M,dsize)
    参数:

    • img: 输入图像
    • M: 移动矩阵
    • dsize: 输出图像的大小

    注意:输出图像的大小,它应该是(宽度,高度)的形式。请记住,width=列数,height=行数。

    示例

    需求是将图像的像素点移动(50,100)的距离:

    
    # 1. 读取图片
    img1 = cv.imread("image.png")
    # 2. 图像平移
    rows, cols = img1.shape[:2]
    M = M = np.float32([[1, 0, 100], [0, 1, 50]])  # 平移矩阵
    dst = cv.warpAffine(img1, M, (cols, rows))
    
    plt.rcParams['font.family'] = 'SimHei' #使用黑体
    # 3. 图像显示
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(img1[:, :, ::-1])
    axes[0].set_title("原图")
    axes[1].imshow(dst[:, :, ::-1])
    axes[1].set_title("平移后结果")
    plt.show()
    

    详解Python+OpenCV对图像进行几何变换操作_第5张图片

  • 图像旋转
    在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。

    API

    cv2.getRotationMatrix2D(center, angle, scale)
    

    参数:
    center:旋转中心
    angle:旋转角度
    scale:缩放比例
    返回:
    M:旋转矩阵
    调用cv.warpAffine完成图像的旋转

    
    # 1. 读取图片
    img1 = cv.imread("image.png")
    # 2 图像旋转
    rows, cols = img1.shape[:2]
    # 2.1 生成旋转矩阵
    M = cv.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
    # 2.2 进行旋转变换
    dst = cv.warpAffine(img1, M, (cols, rows))
    
    plt.rcParams['font.family'] = 'SimHei' #使用黑体
    # 3 图像展示
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(img1[:, :, ::-1])
    axes[0].set_title("原图")
    axes[1].imshow(dst[:, :, ::-1])
    axes[1].set_title("旋转后结果")
    plt.show()
    

    详解Python+OpenCV对图像进行几何变换操作_第6张图片

  • 仿射变换
    图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。

    那什么是图像的仿射变换,如下图所示,图1中的点1, 2 和 3 与图二中三个点一一映射, 仍然形成三角形, 但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。
    详解Python+OpenCV对图像进行几何变换操作_第7张图片

    
    # 1. 读取图片
    img1 = cv.imread("image.png")
    
    # 2 仿射变换
    rows, cols = img1.shape[:2]
    # 2.1 创建变换矩阵
    pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
    pts2 = np.float32([[100, 100], [200, 50], [100, 250]])
    M = cv.getAffineTransform(pts1, pts2)
    # 2.2 完成仿射变换
    dst = cv.warpAffine(img1, M, (cols, rows))
    
    # 3 图像显示
    plt.rcParams['font.family'] = 'SimHei' #使用黑体
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(img1[:, :, ::-1])
    axes[0].set_title("原图")
    axes[1].imshow(dst[:, :, ::-1])
    axes[1].set_title("仿射后结果")
    plt.show()
    
    

    详解Python+OpenCV对图像进行几何变换操作_第8张图片

  • 透射变换
    透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
    详解Python+OpenCV对图像进行几何变换操作_第9张图片

    # 1. 读取图片
    img1 = cv.imread("image.png")
    # 2 透射变换
    rows, cols = img1.shape[:2]
    # 2.1 创建变换矩阵
    pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
    pts2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
    T = cv.getPerspectiveTransform(pts1, pts2)
    # 2.2 进行变换
    dst = cv.warpPerspective(img1, T, (cols, rows))
    # 3 图像显示
    plt.rcParams['font.family'] = 'SimHei' #使用黑体
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(img1[:, :, ::-1])
    axes[0].set_title("原图")
    axes[1].imshow(dst[:, :, ::-1])
    axes[1].set_title("透射后结果")
    plt.show()
    

    详解Python+OpenCV对图像进行几何变换操作_第10张图片

总结

  1. 图像缩放:对图像进行放大或缩小
    cv.resize()
  2. 图像平移:
    指定平移矩阵后,调用cv.warpAffine()平移图像
  3. 图像旋转:
    调用cv.getRotationMatrix2D获取旋转矩阵,然后调用cv.warpAffine()进行旋转
  4. 仿射变换:
    调用cv.getAffineTransform将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()进行变换
  5. 透射变换:
    通过函数cv.getPerspectiveTransform()找到变换矩阵,将cv.warpPerspective()进行投射变换

你可能感兴趣的:(人生苦短-我用Python,python)