目录
1 仿射变换cv2.warpAffine(src, M, dsize,flags,borderMode, borderValue)
1.1 函数cv2.warpAffine(src, M, dsize,flags,borderMode, borderValue)
- 说明:一般先构建变换矩阵,然后用仿射函数cv2.warpAffine()进行变换
- 函数:cv2.warpAffine(src, M, dsize,flags,borderMode, borderValue)
其中:- src- 输入图像
- M- 变换矩阵
- dsize- 输出图像的大小
- flags- 插值方法的组合(int 类型!)
- borderMode- 边界像素模式(int 类型!)
- borderValue- (重点!)边界填充值; 默认情况下为0,填充黑色
- 上述参数中: M作为仿射变换矩阵,一般反映平移或旋转的关系,为InputArray类型
- flags表示插值方式,默认为flags=cv2.INTER_LINEAR,表示线性插值,此外还有: cv2.INTER_NEAREST(最近邻插值)、cv2.INTER_AREA (区域插值)、cv2.INTER_CUBIC(三次样条插值)、cv2.INTER_LANCZOS4(Lanczos插值)
1.2 图像平移
import cv2
import numpy as np
# 读入图像
img = cv2.imread('img2.png')
# (重点!!)构造移动矩阵H
H = np.float32([[1, 0, 50], [0, 1, 25]]) # 在x方向平移50距离,在y方向平移25距离
height, width = img.shape[:2] # 获取行和列,即高、宽
# 注意这里width和height需要反置,即先宽后高
res = cv2.warpAffine(img, H, (width, height)) # 空白处默认用0填充
cv2.imshow('origin_pic', img)
cv2.imshow('new_pic', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.3 图像缩放cv2.resize(src,dsize=None,fx,fy,interpolation)
函数:cv2.resize(src,dsize=None,fx,fy,interpolation)
- src:原图
- dsize:输出尺寸,与比例因子二选一
- fx::沿水平轴的比例因子
- fy:沿垂直轴的比例因子
- interpolation: 插值方法
- cv2.INTER_NEAREST(最近邻插值) 、cv2.INTER_AREA (区域插值) 、cv2.INTER_CUBIC(三次样条插值) 、 cv2.INTER_LANCZOS4(Lanczos插值)
import cv2
import numpy as np
img = cv2.imread('img2.png')
# 方法一:设置缩放比例,来对图像进行放大或缩小
res1 = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
height, width = img.shape[:2]
# 方法二:直接设置图像的大小,不需要缩放因子
# 注意:resize输出高宽比例与原来一样,要先width, 后height
res2 = cv2.resize(img, (int(0.8*width), int(0.8*height)),interpolation=cv2.INTER_LANCZOS4)
cv2.imshow('origin_picture', img)
#|cv2.imshow('res1', res1)
cv2.imshow('res2', res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.4 图像旋转cv2.getRotationMatrix2D()
函数:cv2.getRotationMatrix2D(center, angle, scale)
- center: 图片旋转中心
- angle: 旋转角度
- scale: 缩放比例,0.5表示缩小一半,正为逆时针,负值为顺时针
import cv2
import numpy as np
img=cv2.imread('img2.png',1)
height, width=img.shape[:2]
#参数1:旋转中心,参数2:旋转角度,
#参数3:缩放因子,正为逆时针,负值为正时针
M=cv2.getRotationMatrix2D((width/2,height/2),45,1,)
#第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(width, height))
cv2.imshow('origin_pic', img)
cv2.imshow('rotate', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.5 仿射变换cv2.getAffineTransform()
说明: 仿射变化需要一个M矩阵进行变换,但由于仿射变换比较复杂,一般直接找很难找到这个矩阵,因此cv2通过利用3个点前后变换的关系,使得图像完成平移、旋转、缩放、剪切、反射的变换。
函数:cv2.getAffineTransform(pos1, pos2)
- pos1: 变换前的位置
- pos2: 变换后的位置
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
src = cv2.imread('bird.png')
#获取图像大小
height, width = src.shape[:2]
#设置图像仿射变换矩阵
pos1 = np.float32([[50,50], [200,50], [50,200]])
pos2 = np.float32([[10,100], [200,50], [100,250]])
M = cv2.getAffineTransform(pos1, pos2)
#图像仿射变换
result = cv2.warpAffine(src, M, (2*width, 2*height))
#显示图像
cv2.imshow("origin_pic", src)
cv2.imshow("result", result)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
2 透视变换 cv2.getPerspectiveTransform(pos1,pos2)、cv2.warpPerspective(src, M, dsize)
本质:将图像投影到一个新的平面
函数:cv2.getPerspectiveTransform(pos1,pos2)
- pos1: 透视变换前的4点对应位置
- pos2: 透视变换后的4点对应位置
说明: 先使用cv2.getPerspectiveTransform(pos1, pos2),再使用cv2.warpPerspective(src, M, dsize),与cv2.warpAffine()相似。
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
src = cv2.imread('bird.png')
#获取图像大小
height, width = src.shape[:2]
#设置图像透视变换矩阵
pos1 = np.float32([[114, 82], [287, 156],[8, 100], [143, 177]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
#图像透视变换
result = cv2.warpPerspective(src, M, (2*width,2*height))
#显示图像
cv2.imshow("original", src)
cv2.imshow("result", result)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
如
2.1 使用示例:
#encoding:utf-8
import cv2
import numpy as np
#读取图片
src = cv2.imread('paper.png')
#获取图像大小
rows, cols = src.shape[:2]
#将源图像高斯模糊,去掉图像中一些噪声
img = cv2.GaussianBlur(src, (3,3), 0)
#进行灰度化处理
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#边缘检测(检测出图像的边缘信息)
edges = cv2.Canny(gray,50,250,apertureSize = 3)
cv2.imwrite("canny.jpg", edges)
cv2.imshow("canny", edges)
#通过霍夫变换得到A4纸边缘,用于检测直线
# lines 返回直线中的点
lines = cv2.HoughLinesP(edges, 1, np.pi/180,50,minLineLength=90,maxLineGap=10)
print(lines) # lines.shape : (4,1,4)
#绘制边缘
for x1, y1, x2, y2 in lines[0]:
cv2.line(gray, (x1,y1), (x2, y2), (0, 0, 255), 1)
# 透视变换,根据四个顶点设置图像透视变换矩阵
pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]]) # 左上角 右上角 左下角 右下角
M = cv2.getPerspectiveTransform(pos1, pos2) # 四个点,因此用透视变换
print(M)
result = cv2.warpPerspective(src, M, (190, 272))
# 根据3点,图像仿射变换
# pos1 = np.float32([[114, 82], [287, 156], [8, 322]])
# pos2 = np.float32([[0, 0], [188, 0], [0, 262]])
# M = cv2.getAffineTransform(pos1,pos2)
# print(M)
# result = cv2.warpAffine(src, M, (2*cols, 2*rows))
#显示图像
cv2.imshow("original", src)
cv2.imshow("result", result)
cv2.imshow("gray", gray)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
3 插值方法
3.1 最近邻插值
缺点:容易出现锯齿状