【计算机视觉】OpenCV篇(3) - 图像几何变换(仿射变换/透视变换)
图像的几何变换从原理上看主要包括两种:基于2×3矩阵的仿射变换(平移、缩放、旋转和翻转等)、基于3×3矩阵的透视变换。
- 仿射变换
基本的图像变换就是二维坐标的变换:从一种二维坐标(x,y)到另一种二维坐标(u,v)的线性变换:
如果写成矩阵的形式,那就是:
作如下定义:
矩阵T(2×3)就称为仿射变换的变换矩阵,R为线性变换矩阵,t为平移矩阵,简单来说,仿射变换就是线性变换+平移。变换后直线依然是直线,平行线依然是平行线,直线间的相对位置关系不变,因此非共线的三个对应点便可确定唯一的一个仿射变换,线性变换4个自由度+平移2个自由度→仿射变换自由度为6。
仿射变换在OpenCV中的实现如下:
import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('drawing.jpg')
rows, cols = img.shape[:2]# 变换前的三个点
pts1 = np.float32([[50, 65], [150, 65], [210, 210]])
# 变换后的三个点
pts2 = np.float32([[50, 100], [150, 65], [100, 250]])# 生成变换矩阵,维数:2*3
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))plt.subplot(121), plt.imshow(img), plt.title('input')
plt.subplot(122), plt.imshow(dst), plt.title('output')
plt.show()
运行结果:
其实平移、旋转、缩放和翻转等变换就是对应了不同的仿射变换矩阵,下面分别来看:
(1)平移
平移就是x和y方向上的直接移动,可以上下/左右移动,自由度为2,变换矩阵可以表示为:
# 平移图片
import numpy as nprows, cols = img.shape[:2]# 定义平移矩阵,需要是numpy的float32类型
# x轴平移100,y轴平移50
M = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv2.warpAffine(img, M, (cols, rows))cv2.imshow('shift', dst)
cv2.waitKey(0)
(1)通过比例进行缩放
import cv2 as cv
import numpy as np# 图片缩放
img = cv.imread('images/animal.jpg', flags=1) # flags=1读取为彩色,flags=0读取为灰度
cv.imshow('i', img)
h, w, channel = img.shape # 以行列形式存储, 第几行到第几行为图像高度
dst_h = int(h*0.5)
dst_w = int(w*0.5)
# 最近邻域差值 双线性插值 像素关系重采样 立方差值
dst = cv.resize(img, (dst_w, dst_h)) # 默认双线性差值
cv.imshow('img', dst)
cv.waitKey(0)
OpenCV提供了resize函数来改变图像的大小,C++中的函数原型如下:
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );
函数参数说明:
src:输入,原图像,即待改变大小的图像;
dst:输出,改变大小之后的图像,这个图像和原图像具有相同的内容,只是大小和原图像不一样而已;
dsize:输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数为0,那么原图像缩放之后的大小就要通过下面的公式来计算:
dsize = Size(round(fx*src.cols), round(fy*src.rows))
其中,fx和fy就是下面要说的两个参数,是图像width方向和height方向的缩放比例。
fx:width方向的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算;
fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;
interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:
- INTER_NEAREST - 最邻近插值
- INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
- INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
- INTER_CUBIC - 4x4像素邻域内的双立方插值
- INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值
函数使用说明:
- dsize和fx/fy不能同时为0,要么你就指定好dsize的值,让fx和fy空置直接使用默认值,就像resize(img, imgDst, Size(30,30)); 要么你就让dsize为0,指定好fx和fy的值,比如fx=fy=0.5,那么就相当于把原图两个方向缩小一倍!
- 至于最后的插值方法,正常情况下使用默认的双线性插值就够用了。几种常用方法的效率是:最邻近插值>双线性插值>双立方插值>Lanczos插值;但是效率和效果成反比,所以根据自己的情况酌情使用。
- 正常情况下,在使用之前dst图像的大小和类型都是不知道的,类型从src图像继承而来,大小也是从原图像根据参数计算出来。但是如果你事先已经指定好dst图像的大小,那么你可以通过下面这种方式来调用函数:
resize(src, dst, dst.size(), 0, 0, interpolation);
(2)通过矩阵变换进行缩放
import cv2 as cv
import numpy as np# 图片缩放
img = cv.imread('../images/moon.jpg', flags=1) # flags=1读取为彩色,flags=0读取为灰度
h, w = img.shape[:2]
mat_shift = np.float32([[0.5, 0, 0], [0, 0.5, 0]]) # 缩放矩阵
dst = cv.warpAffine(img, mat_shift, (int(w/2), int(h/2)))
cv.imshow('img1', img)
cv.imshow('img2', dst)
cv.waitKey(0)
转载于:https://www.cnblogs.com/carsonzhu/p/10763438.html
【计算机视觉】OpenCV篇(3) - 图像几何变换(仿射变换/透视变换)相关推荐
- [Python从零到壹] 三十九.图像处理基础篇之图像几何变换(镜像仿射透视)
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- opencv python 图像缩放/图像平移/图像旋转/仿射变换/透视变换
Geometric Transformations of Images 1图像转换 OpenCV提供了两个转换函数cv2.warpAffine和cv2.warpPerspective,可以使用它们进行 ...
- opencv android 透视,OpenCV图像几何变换之透视变换
本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 1. 基本原理 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面 ...
- 图像几何变换之透视变换
1. 基本原理 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式为: (u,v)为原始图像像素坐标,(x=x'/w',y=y'/w') ...
- 【图像处理opencv】_图像几何变换
目录 0 程序环境与所学函数 1 裁剪.放大.缩小 2 平移变换 3 错切变换 4 镜像变换 5 旋转变换 6 透视变换 7 最近邻插值.双线性插值 0 程序环境与所学函数 本章程序运行需要导入下面三 ...
- 【opencv】鱼眼图像畸变校正——透视变换
原图 球面透视投影(以空间左手坐标系,x轴为水平,y为竖直,z为光轴,投影面法线与xoz面夹角55度) 经过球面透视投影后,会存在两个灭点,此时,需要消去由于球面透视投影面存在角度引入的灭点.在这里采 ...
- 计算机视觉OpenCV(五):图像金字塔与轮廓检测
目录 图像金字塔 1. 高斯金字塔(Gaussian Pyramid) 2. 拉普拉斯金字塔(Laplacian Pyramid) 图像轮廓 1. 查找检测物体的轮廓 2. 绘制轮廓 3. 轮廓特征 ...
- [Python从零到壹] 四十一.图像处理基础篇之图像采样处理
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
最新文章
- php5.4版本不爆错误,PHP5.4以上版本出现的错误:Fatal error: Call-time pass-by-reference has been removed | 严佳冬...
- byte数组转file不写入磁盘_Linux 环境写文件如何稳定跑满磁盘 I/O 带宽?
- “共享工程师”?看锐捷“网络青年”如何携手500位工程师提供最优IT服务
- SAP Spartacus里使用defer的一个例子
- .NET Core使用FluentEmail发送邮件
- ListView原理简单介绍(着重介绍getView被调用的一系列过程)
- 版本控制系统(译文) 2 - 基础
- python 读取csv文件
- NYOJ 42一笔画问题||欧拉图
- 使用WIN32汇编语言实现一个基本windows窗口的过程分析
- 【转】一个程序员分享8年的开发经验
- 2022年安全员-A证考题模拟考试平台操作
- 历史的味道(美国人拍摄的1974-1978年中国)
- python中print是什么意思中文-python里print是什么意思
- QT简单添加背景图片
- 本科就学人工智能有意义吗?
- python学习-06(模块化编程)
- 王朝落日,读《万历十五年》
- Python面向对象之六:类的约束和super函数
- 注册dll文件的方法集合