侧边栏壁纸
博主头像
Dioxide-CN博主等级

茶边话旧,看几许星迢露冕,从淮海南来。

  • 累计撰写 50 篇文章
  • 累计创建 49 个标签
  • 累计收到 21 条评论

目 录CONTENT

文章目录

计算机视觉:6.2~6.5 图像的基本变换与仿射变换

Dioxide-CN
2022-07-09 / 0 评论 / 3 点赞 / 150 阅读 / 3,698 字
温馨提示:
本文最后更新于 2022-08-02,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

图像的基本变换与仿射变换

6.2 图像的翻转和旋转

图像的翻转

  • flip(src, flipCode)
    • flipCode=0:上下翻转;
    • flipCode>0:左右翻转;
    • flipCode<0:上下 + 左右翻转;
# 图像的翻转
import cv2
import numpy as np

# 读取图片
doge = cv2.imread('./doge.jpg')

new_doge1 = cv2.flip(doge, flipCode=0)
new_doge2 = cv2.flip(doge, flipCode=1)
new_doge3 = cv2.flip(doge, flipCode=-1)

cv2.imshow('flip', np.hstack((doge, new_doge1, new_doge2, new_doge3)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220709200655

使用ndarray进行上下+左右翻转:

# 图像的翻转
import cv2
import numpy as np

doge = cv2.imread('./doge.jpg')
new_doge = dog[::-1, ::-1]

cv2.imshow('ndarray_flip', np.hstack((doge, new_doge)))
cv2.waitKey(0)
cv2.destroyAllWindows()

图像的旋转

  • rotate(src, rotateCode)
    • ROTATE_90_CLOCKWISE:90度顺时针
    • ROTATE_180:180度
    • ROTATE_90_COUNTERCLOCKWISE:90度逆时针
# 图像的旋转
import cv2
import numpy as np

# 读取图片
dog = cv2.imread('./dog.jpg')

new_dog1 = cv2.rotate(dog, rotateCode=cv2.ROTATE_90_CLOCKWISE)
new_dog2 = cv2.rotate(dog, rotateCode=cv2.ROTATE_180)
new_dog3 = cv2.rotate(dog, rotateCode=cv2.ROTATE_90_COUNTERCLOCKWISE)

cv2.imshow('flip', np.hstack((dog, new_dog1, new_dog2, new_dog3)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220709201311

6.3 仿射变换之平移

在CSS3的transform属性中,matrix(n,n,n,n,n,n)值就使用了仿射变换来操作图像的旋转、缩放、平移。

  • 仿射变换是图像旋转,缩放,平移的总称。具体的做法是通过一个矩阵和原图片坐标进行计算,得到新的坐标,完成变换,其关键在于变换矩阵。
  • warpAffine(src, M, dsize, flags, mode, value)
    • M:变换矩阵;
    • dsize:输出图片大小;
    • flag:类似于resize中的插值算法;
    • mode:边界外推法标志;
    • value:填充边界值;

平移矩阵

  • 矩阵中的每个像素由(x,y)组成,(x,y)表示这个像素的坐标,假设沿x轴平移t_x,沿y轴平移t_y,则最后得到的坐标为:

(x^,y^)=(x+tx,y+ty)(\hat x, \hat y) = (x + t_x, y + t_y)

使用矩阵表示就是(线性回归中的矩阵乘法):

(x^y^1)=(10tx01ty001)(xy1)=(1x+0y+tx10x+1y+ty10x+0y+11)=(x+txy+ty1)\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) = \left( \begin{matrix} 1 * x + 0 * y + t_x * 1 \\ 0 * x + 1 * y + t_y * 1 \\ 0 * x + 0 * y + 1 * 1 \end{matrix} \right) = \left( \begin{matrix} x + t_x \\ y + t_y \\ 1 \end{matrix} \right)

# 仿射变换之平移
import cv2
import numpy as np

# 导入图片
dog = cv2.imread('./dog.jpg')

h, w, ch = dog.shape

# x轴正向偏移50,y轴正向偏移50
M = np.float32([[1, 0, 50], [0, 1, 50]])

# 注意OpenCV中先宽度后高度
new = cv2.warpAffine(dog, M, (w, h))

cv2.imshow('Affine', new)
cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220709205718

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

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

  • getRotationMatrix2D(center, angle, scale)
    • center:中心点,以图片的哪个点作为旋转时的中心点;
    • angle:角度,旋转的角度,按照逆时针旋转;
    • scale:缩放比例,对图片进行缩放;
# 除了平移,仿射矩阵还可以完成图像的旋转
# 旋转同样需要进行矩阵计算,为了方便计算旋转矩阵
# 使用getRotationMatrix2D方法可以获得想要的旋转矩阵
import cv2
import numpy as np

# 导入图片
dog = cv2.imread('./dog.jpg')

h, w, ch = dog.shape

# 获取变换矩阵,逆时针45度转动并缩放至0.7倍
M = cv2.getRotationMatrix2D((w/2, h/2), 45, 0.7)

new = cv2.warpAffine(dog, M, (w, h))

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

Pasted image 20220709211100

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

Pasted image 20220709211822

# 通过三点的起止位置来获得变换矩阵
import cv2
import numpy as np

dog = cv2.imread('./dog.jpg')
h, w, ch = dog.shape

# 顺时针旋转90度后的起止三个点的坐标
src = np.float32([[0,0], [100,0], [0,100]])
dst = np.float32([[100,0], [100,100], [0,0]])
# 需要原始图片的三点坐标,和变换之后三个对应的坐标
M = cv2.getAffineTransform(src, dst)
new = cv2.warpAffine(dog, M, (w, h))
cv2.imshow('Affine', np.hstack((dog, new)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220709212347

6.5 仿射变换之透视变换

透视变换就是将二位坐标系转变为三维坐标系。

Pasted image 20220709212735

  • warpPerspective(img, M, dsize, flags, mode, value)
# 通过三点的起止位置来获得变换矩阵
import cv2
import numpy as np

img = cv2.imread('./book.jpg')

print(img.shape)
# 获取变换矩阵
# src是原图中对象的最小外接矩形的4个顶点坐标
src = np.float32([[0, 540], [2000, 540], [2500, 1986], [0, 1986]])
dst = np.float32([[0, 0], [2000, 0], [2100, 1446], [0, 1446]])

M = cv2.getPerspectiveTransform(src, dst)

# 透视变换
new = cv2.warpPerspective(img, M, (1600, 1446))
cv2.imshow('Affine_raw', img)
cv2.imshow('Affine_new', new)
cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220709215051

3

评论区