【OpenCV】3 图像基本处理(几何变换-- 平移、缩放、旋转,仿射变换+透视变换)

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 最近邻插值

缺点:容易出现锯齿状
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44994302/article/details/121361242