1. 向量,基向量
说到向量,你的脑海里回应的是什么?没有一个非常具体清晰的概念, 在之后的问题理解中就会带来阻碍。
向量是一个有方向的箭头,也是在坐标中的某一个点(可以想象成原点到该点的箭头)。
基向量i,j能够组合线性空间中的任何的向量。在线性空间中,所有向量的运动是一致的。
2. 矩阵乘法
向量是一个有方向的箭头,也可以看成在某个位置上的点。那么,我们如何去表示向量从这里到那里的运动呢?或者从这个点到那个点的运动。
在线性空间中,由于整个空间的变换效果是一致的,我们只需要跟踪基向量的变换就行了。(只根据变换后的i,j,就能推断出变换后的向量V。)
所以,见到矩阵乘法,我们就认为这是一种变换,一种运动,实现把某个(些)点从这里拖到那里。而且,为了形象定性理解,我们可以直接想象基向量的运动。
那么,大家继续深入一些思考:
图像是矩阵,矩阵的乘法同样适用于图像。
(1) 如果想把图像旋转90度,我们应该对图像进行什么变换?
假如说,这里我们指的是逆时针旋转90度,在我们的脑海里,原来的基向量i(1,0)旋转后运动到(0,1),而原来的基向量j(0,1)运动到了(-1,0),
那么,图像旋转90度,是不是可以通过矩阵乘法实现?
代码如下:
import cv2
import numpy as np
img = cv2.imread('1.jpg', 0)
rows, cols = img.shape
# rotate 90
M = np.float32([[0, 1, 0], [1, 0, 0]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img',img)
cv2.imshow('img_rotate', dst)
k = cv2.waitKey(0)
实现效果如下:
猜想一下:如果是旋转一般的角度呢?如30度。变换矩阵是什么?
不要动手,仅仅是在大脑里面思考,能想出来吗?试试看!
(2) 如果想把图像翻转,我们应该对图像进行什么变换?
现在想起来是不是很简单了,如果是关于X轴翻转,那么原来的基向量i(1,0)运动到(-1,0),而原来的基向量j(0,1)还是原来的(0,1)。
代码如下:
import cv2
import numpy as np
img = cv2.imread('1.jpg', 0)
rows, cols = img.shape
#flipx
M = np.float32([[-1, 0, rows], [0, 1, 0]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img',img)
cv2.imshow('img_rotate', dst)
k = cv2.waitKey(0)
效果如下:
(3) 如果我们想把图像横向缩放0.4,纵向缩放0.5,该怎么做呢?
代码如下:
import cv2
import numpy as np
img = cv2.imread('1.jpg', 0)
rows, cols = img.shape
# resize factor
M = np.float32([[.4, 0, 0], [0, .5, 0]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img',img)
cv2.imshow('img_rotate', dst)
k = cv2.waitKey(0)
效果如下:
(4) 图像剪切
import cv2
import numpy as np
img = cv2.imread('1.jpg', 0)
rows, cols = img.shape
# Shear
M = np.float32([[1, .3, 0], [0, 1.2, 0]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img',img)
cv2.imshow('img_rotate', dst)
k = cv2.waitKey(0)
效果如下:
(5) 我们前面说的都是线性变换,那么仿射变化呢?毕竟仿射变换在图像中应用的更为广泛。
其实,仿射变换就是图像的线性变换(旋转,缩放)加上平移动作。
在实际的项目中,由于平台的振动,皮带运动的不稳定,我们得到的图像往往会发生一些偏转和平移。
对于这种情况,我们可以构建多个仿射变换点,基于这些仿射变换点计算出变换矩阵,然后对图像进行处理,得到对偏转和平移校正后的图像,再进行后续的分析处理就会方便很多了。
可见,我们把矩阵的乘法看做一种变换,并能够基于基向量大致想象出这种运动形式。对于我们理解图像的平移,缩放,旋转,剪切以及仿射变换都有很大的帮助。
网友评论