03- 通过OpenCV进行图像变换 (OpenCV系列) (机器视觉)

本文介绍了OpenCV库在图像处理中的基本操作,包括图像的放大缩小(resize)、翻转(flip)、旋转(rotate)以及仿射和透视变换。重点讲解了如何使用变换矩阵实现图像的平移、旋转和缩放,以及如何通过getRotationMatrix2D和getPerspectiveTransform计算变换矩阵。此外,还讨论了不同的插值算法对图像质量的影响。
摘要由CSDN通过智能技术生成

知识重点

  • resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])  图像的放大与缩小, 变形

  • flip(src, flipCode)  图像的翻转

  • rotate(img, rotateCode)  图像的旋转

  • warpAffine(src, M, dsize, flags, mode, value)  仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 关键就是这个矩阵.

    • getRotationMatrix2D(center, angle, scale)  仿射变换的难点就是计算变换矩阵, OpenCV提供了计算变换矩阵的API

  • warpPerspective(img, M, dsize,....)  透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".


4. 图像的基本变换

4.1 图像的放大与缩小

  • resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

    • src: 要缩放的图片

    • dsize: 缩放之后的图片大小, 元组和列表表示均可.

    • dst: 可选参数, 缩放之后的输出图片

    • fx, fy: x轴和y轴的缩放比, 即宽度和高度的缩放比.

    • interpolation: 插值算法, 主要有以下几种:

      • INTER_NEAREST, 邻近插值, 速度快, 效果差.

      • INTER_LINEAR, 双线性插值, 使用原图中的4个点进行插值. 默认.

      • INTER_CUBIC, 三次插值, 原图中的16个点.

      • INTER_AREA, 区域插值, 效果最好, 计算时间最长.

import cv2
import numpy as np
#导入图片
dog = cv2.imread('./dog.jpeg')
print(dog.shape)    # (360, 499, 3)

# x,y放大一倍
new_dog = cv2.resize(dog,dsize=(800, 800), interpolation=cv2.INTER_NEAREST)
cv2.imshow('dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()

                

4.2 图像的翻转

  • flip(src, flipCode)

    • flipCode =0 表示上下翻转

    • flipCode >0 表示左右翻转

    • flipCode <0 上下 + 左右

# flip
import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')
new_dog = cv2.flip(dog, -1)
# new_dog = dog[::-1, ::-1]  # 同样的效果

cv2.imshow('dog', np.hstack((dog, new_dog)))
cv2.waitKey(0)
cv2.destroyAllWindows()

   

4.3 图像的旋转

  • rotate(img, rotateCode)

    • ROTATE_90_CLOCKWISE 90度顺时针

    • ROTATE_180 180度

    • ROTATE_90_COUNTERCLOCKWISE 90度逆时针

import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')
new_dog = cv2.rotate(dog, rotateCode=cv2.ROTATE_90_COUNTERCLOCKWISE)
print(dog.shape)    # (360, 499, 3)
print(new_dog.shape)   # (499, 360, 3)

cv2.imshow('dog', dog)
cv2.imshow('new_dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()

        

4.4 仿射变换之图像平移

  • 仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 所以关键就是这个矩阵.

  • warpAffine(src, M, dsize, flags, mode, value)

    • M:变换矩阵

    • dsize: 输出图片大小

    • flag: 与resize中的插值算法一致

    • mode: 边界外推法标志

    • value: 填充边界值

  • 平移矩阵

    • 矩阵中的每个像素由(x,y)组成,(x, y)表示这个像素的坐标. 假设沿x轴平移​​​​​​​​\small t_x, 沿y轴平移\small t_y​​​​​​​, 那么最后得到的坐标为\small (\hat x, \hat y) = (x + t_x, y + t_y)​​​​, 用矩阵表示就是:

                 \small \left(\begin{matrix}\hat x \\\hat y \\1\end{matrix}\right) = \left(\begin{matrix}1 & 0 & t_x\\0 & 1 & t_y\\0 & 0 & 1\end{matrix}\right)\left(\begin{matrix}x \\y \\1\end{matrix}\right)

import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')
h, w, ch = dog.shape
print(h, w, ch)   # 360 499 3
# 变换矩阵,最少是float32位
M = np.float32([[1, -0.5, 50], [0, 1, -50]])
# 平移操作
# 注意opencv中是先宽度, 后高度.
new_dog = cv2.warpAffine(dog, M, dsize=(w, h))

cv2.imshow('dog', dog)
cv2.imshow('new_dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()

        

4.5 仿射变换之获取变换矩阵

仿射变换的难点就是计算变换矩阵, OpenCV提供了计算变换矩阵的API

  • getRotationMatrix2D(center, angle, scale)

    • center 中心点 , 以图片的哪个点作为旋转时的中心点.

    • angle 角度: 旋转的角度, 按照逆时针旋转.

    • scale 缩放比例: 想把图片进行什么样的缩放.

# 在进行旋转操作的时候, 不方便手动计算变换矩阵, 
# opencv提供了获取变换矩阵的API.
import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')
h, w, ch = dog.shape
# 获取变换矩阵
# 规定按照逆时针转动图片
M = cv2.getRotationMatrix2D((w/2, h/2), 45, 1)
new_dog = cv2.warpAffine(dog, M, (w, h))

cv2.imshow('new_dog', np.hstack((dog, new_dog)))
cv2.waitKey(0)
cv2.destroyAllWindows()

  • getAffineTransform(src[], dst[]) 通过三点可以确定变换后的位置, 相当于解方程, 3个点对应三个方程, 能解出偏移的参数和旋转的角度.
    • src 原目标的三个点

    • dst 对应变换后的三个点

# 通过三个点来确定变换矩阵
import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')
h, w, ch = dog.shape
src = np.float32([[100, 100], [200, 100], [200, 300]])
dst = np.float32([[100, 150], [360, 200], [280, 120]])
# 需要原始图片的三个点坐标, 和变换之后的三个对应的坐标
M = cv2.getAffineTransform(src, dst)
new_dog = cv2.warpAffine(dog, M, (w, h))

cv2.imshow('new_dog', np.hstack((dog, new_dog)))
cv2.waitKey(0)
cv2.destroyAllWindows()

       

4.6 透视变换

透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".

  • warpPerspective(img, M, dsize,....)

  • 对于透视变换来说, M是一个3 * 3 的矩阵.

  • getPerspectiveTransform(src, dst) 获取透视变换的变换矩阵, 需要4个点, 即图片的4个角.

import cv2
import numpy as np

img = cv2.imread('./123.png')
print(img.shape)
# 获取变换矩阵
# src是原图的4个坐标
src = np.float32([[100, 1100], [2100, 1100], [0, 4000], [2500, 3900]])
dst = np.float32([[0, 0], [2300, 0], [0, 3000], [2300, 3000]])
M = cv2.getPerspectiveTransform(src, dst)

# 透视变换
new_img = cv2.warpPerspective(img, M, (2300, 3000))
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 480)
cv2.imshow('img', img)

cv2.namedWindow('new_img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('new_img', 640, 480)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值