QQ:3020889729 小蔡
毫无疑问,一个个图像——本质就是一个个多维数组,它包含像素点的排布,以及像素点的信息。
既然多维数组,我们将图像中前两维度——对应行列,当作一个矩阵进行处理。
第一维——也就是对应着行;第二维——也就是对应着列。
举例:将一个多维数组当作矩阵
[[1, 2, 3]
[4, 5, 6]
[7, 8, 9]]
这里应该能明白:第一维的每一个元素是一个list,且等大,每一个list作为一个行,list里边的元素——就一一对应着属于列。
opencv提供的矩阵(图像)转换函数有两个:
cv.warpAffine()——对应23的矩阵转换——可以实现平移和翻转(反转还需要一个cv.getRotationMatrix2D来获取旋转后的移动坐标),以及仿射变换——getAffineTransform
cv.warpPerspective()——对应33的矩阵转换——可以应用透射变换
以及一个图像大小按比例修改的函数:cv.resize()
opencv使用该函数实现了任一点旋转的方法——并且返回一个warpAffine的平移参数矩阵(2*3)
opencv使用该函数实现了通过取图像三点以及变化后的对应位置,来实现变换的方法——并且返回一个warpAffine的平移参数矩阵(2*3)——实现仿射变换
cv.warpPerspective实现透射变换——所以需要对空间有一个坐标——也就是对应着23到33矩阵变化的需要——当然实现透射变换还需要一个函数的帮助,来获取这样的移动参数矩阵
该函数为透色变换提供移动参数——一个3*3的移动参数矩阵。
而这样的参数,来源于原图像中的4个点坐标,以及设置的改变后对应的坐标
这里不要设置窗体可调——不然会显示不出来伸缩变换的。
import cv2 as cv
import numpy as np
if __name__ == "__main__":
img = cv.imread('../imag_in_save/open_class.png')
# cv.namedWindow('imag', cv.WINDOW_NORMAL)
img_size_h, img_size_w = img.shape[:2] # 获取形状大小——即第一位为行数,第二位为列数
res = cv.resize(img, (img_size_w*1, img_size_h*3), interpolation=cv.INTER_CUBIC)
# 高度变为3倍
# 除了这样的操作外,还可以如此
# res = cv.resize(img, None, fx=1, fy=3, interpolation=cv.INTER_CUBIC)
cv.imshow('imag', res)
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
if __name__ == "__main__":
img = cv.imread('../imag_in_save/open_class.png')
img_size_h, img_size_w = img.shape[:2] # 获取形状大小——即第一位为行数,第二位为列数
move_value = np.float32([[1, 0, 66], [0, 1, 66]]) # 前面的公式可知:这里是移动x = 66, y = 66
res = cv.warpAffine(img, move_value, (img_size_w, img_size_h))
cv.imshow('imag', res)
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
if __name__ == "__main__":
img = cv.imread('../imag_in_save/open_class.png')
# cv.namedWindow('imag', cv.WINDOW_NORMAL)
img_size_h, img_size_w = img.shape[:2] # 获取形状大小——即第一位为行数,第二位为列数
move_value = cv.getRotationMatrix2D((img_size_w/2.0, img_size_h/2.0), 90, 1) # 获取旋转后的移动坐标矩阵
res = cv.warpAffine(img, move_value, (img_size_w, img_size_h)) # 实现平移旋转
cv.imshow('imag', res)
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
if __name__ == "__main__":
img = cv.imread('../imag_in_save/open_class.png')
img_size_h, img_size_w = img.shape[:2] # 获取形状大小——即第一位为行数,第二位为列数
pst1 = np.float32([[20, 30], [50, 100], [100, 100]]) # 原图像的点坐标
pst2 = np.float32([[40, 30], [50, 100], [80, 120]]) # 原点一一对应的变换点坐标
move_value = cv.getAffineTransform(pst1, pst2) # 获取仿射变换的平移坐标
res = cv.warpAffine(img, move_value, (img_size_w, img_size_h)) # 实现平移——得到仿射变换的图形
cv.imshow('res_imag', res) # 显示变化后的图形
cv.imshow('imag', img) # 显示原图形
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
if __name__ == "__main__":
img = cv.imread('../imag_in_save/open_class.png')
img_size_h, img_size_w = img.shape[:2] # 获取形状大小——即第一位为行数,第二位为列数
pst1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]]) # 需要四个点坐标_要求三个点不共线,# 将四点间内容作为显示内容
pst2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]]) # 四点的坐标变化
move_value = cv.getPerspectiveTransform(pst1, pst2) # 获取投射变换的平移坐标
res = cv.warpPerspective(img, move_value, (300, 300)) # 获取投射变换的图形——大小尽量与变化后的四点坐标等大宽度
cv.imshow('res_imag', res)
cv.imshow('imag', img)
cv.waitKey(0)
cv.destroyAllWindows()
效果:操作前后——如果图形是2d平整的,可能就会编程内凹或者其它的一些畸变。
以下图形实现通过透视变换,得到更平整的图像
视角变浅
**我的效果:**确实有透视的视角变深等变化