OpenCV学习(4.2) 图像的几何变换

2024-06-05 08:44

本文主要是介绍OpenCV学习(4.2) 图像的几何变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.目标

  • 学习将不同的几何变换应用到图像上,如平移、旋转、仿射变换等。
  • 你会看到这些函数: cv.getPerspectiveTransform

2.缩放

缩放是调整图片的大小。 OpenCV 使用 cv.resize() 函数进行调整。可以手动指定图像的大小,也可以指定比例因子。可以使用不同的插值方法。对于下采样(图像上缩小),最合适的插值方法是 cv.INTER_AREA 对于上采样(放大),最好的方法是 cv.INTER_CUBIC (速度较慢)和 cv.INTER_LINEAR (速度较快)。默认情况下,所使用的插值方法都是 cv.INTER_AREA 。你可以使用如下方法调整输入图片大小:

代码:

import cv2image = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
image = cv2.imread(image)#图像几何变换
import numpy as npres11 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_AREA)
res12 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_LINEAR)
res13 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
#OR
height, width = image.shape[:2]
res2 = cv2.resize(image,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)cv2.imshow('res11',res11)
cv2.imshow('res12',res12)
cv2.imshow('res13',res13)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在OpenCV中,cv2.resize() 函数用于改变图像的大小。您提供的代码行演示了如何将输入图像 image 放大到原来的两倍。

这里是代码行的详细解释:

  • res11 = cv2.resize(image, None, fx=2, fy=2, interpolation = cv2.INTER_AREA):这行代码执行了图像放大的操作。
    • image 是您想要调整大小的图像。
    • None 表示输出图像的大小会根据 fx 和 fy 参数自动计算。如果您想显式指定输出图像的大小,可以传递一个元组 (width, height)
    • fx=2 和 fy=2 表示图像在 x 轴和 y 轴方向上放大两倍。
    • interpolation=cv2.INTER_AREA 是插值方法,用于在放大或缩小图像时确定新像素值。cv2.INTER_AREA 是一种适合缩小图像的插值方法,但如果您是在放大图像,通常使用 cv2.INTER_LINEAR 或 cv2.INTER_CUBIC 会得到更好的结果,因为它们可以提供更平滑的边缘和更少的锯齿效果。

如果您的目的是放大图像,通常建议使用 cv2.INTER_LINEAR 或 cv2.INTER_CUBIC 作为插值方法。

 

输出结果: 

3.平移变换

平移变换是物体位置的移动。如果知道 (x,y) 方向的偏移量,假设为 (t_x,t_y)**,则可以创建如下转换矩阵 **M

您可以将变换矩阵存为 np.float32 类型的 numpy 数组,并将其作为 cv.warpAffine 的第二个参数。请参见以下转换(100,50)的示例:

import numpy as np
import cv2 as cvimg = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)
print(img.shape)
rows,cols = img.shape[0],img.shape[1]
M1 = np.float32([[1,0,100],[0,1,50]])
M2 = np.float32([[1,0,50],[0,1,100]])
M3 = np.float32([[1,0,-100],[0,1,-50]])
M4 = np.float32([[1,0,-50],[0,1,-100]])
dst1 = cv.warpAffine(img,M1,(cols,rows))
dst2 = cv.warpAffine(img,M2,(cols,rows))
dst3 = cv.warpAffine(img,M3,(cols,rows))
dst4 = cv.warpAffine(img,M4,(cols,rows))
cv.imshow('img1',dst1)
cv.imshow('img2',dst2)
cv.imshow('img3',dst3)
cv.imshow('img4',dst4)
cv.waitKey(0)
cv.destroyAllWindows()

dst1 = cv.warpAffine(img,M1,(cols,rows))

在OpenCV中,cv.warpAffine() 函数用于对图像进行仿射变换。这个函数可以将图像按照给定的变换矩阵进行旋转、平移、缩放等变换。

以下是代码行的详细解释:

  • dst1 = cv.warpAffine(img, M1, (cols, rows))
    • img 是您想要进行仿射变换的输入图像。
    • M1 是一个2x3的变换矩阵,它定义了如何变换图像。这个矩阵通常是通过计算得到的,它包含了图像的旋转、平移和缩放信息。
    • (cols, rows) 是输出图像的大小,cols 是输出图像的列数,rows 是输出图像的行数。这个参数确定了变换后图像的大小。

例如,如果您想要将图像绕其中心旋转30度,您可以首先计算旋转矩阵 M1,然后使用 cv.warpAffine() 函数进行变换

 

cv.warpAffine 函数的第三个参数是输出图像的大小,其形式应为(宽度、高度)。记住宽度=列数,高度=行数。 

输入:

输出:

4.旋转 

以 \theta角度旋转图片的转换矩阵形式为:

但 Opencv 提供了可变旋转中心的比例变换,所以你可以在任意位置旋转图片,修改后的转换矩阵为:

其中:

为了找到这个转换矩阵,opencv 提供了一个函数, cv.getRotationMatrix2D 。请查看下面的示例,它将图像相对于中心旋转 90 度,而不进行任何缩放。

import cv2 as cvimg = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)rows,cols = img.shape[0],img.shape[1]
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('dst',dst)cv.waitKey(0)
cv.destroyAllWindows()

cv.getRotationMatrix2D 是 OpenCV 库中的一个函数,用于计算二维旋转的变换矩阵。这个变换矩阵可以随后用于 cv.warpAffine 函数中,以实现对图像的旋转。

函数原型如下:

cv.getRotationMatrix2D(center, angle, scale)

参数说明:

  • center:旋转的中心点,通常是一个二元组 (x, y),表示图像中的旋转中心。
  • angle:旋转角度,正值表示逆时针旋转。
  • scale:缩放因子,用于在旋转的同时对图像进行缩放。

返回值是一个 2x3 的浮点型 NumPy 数组,表示旋转变换矩阵。

 

5.仿射变换

仿射变换是一种二维变换,它在平面内将一个图形变换成另一个图形,同时保持原图形中所有点之间的相对位置关系(即直线经过变换后仍然是直线,且平行线经过变换后仍然平行)。在仿射变换中,直线段保持直线且比例不变,但直线段可能会变短或变长。

仿射变换可以由以下几种基本变换组合而成:

  1. 平移(Translation):在平面上沿着某个方向移动所有点。
  2. 旋转(Rotation):围绕某个点旋转所有点。
  3. 缩放(Scaling):放大或缩小所有点,可以有不同的缩放比例沿 x 轴和 y 轴。
  4. 剪切(Shear):使平面上的点沿某个方向移动,移动的距离与点到某条参考线的距离成正比。

在数学上,仿射变换通常表示为一个矩阵和一个向量的组合,形式如下:

                                                               T(x)=Ax+b

其中,A 是一个 2x2 的矩阵,表示旋转、缩放和剪切,b 是一个 2 元素的向量,表示平移,x 是原始点的坐标,T(x) 是变换后点的坐标。

在图像处理中,仿射变换常用于校正图像的视角、校正由于相机镜头造成的畸变、或者将图像中的对象进行几何变换。在 OpenCV 中,可以使用 cv.getAffineTransform 来计算仿射变换矩阵,然后使用 cv.warpAffine 来应用这个变换到图像上。

在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要从输入图像中取三个点及其在输出图像中的对应位置。然后 cv.getAffineTransform 将创建一个 2x3 矩阵,该矩阵将传递给 cv.warpAffine 。

查看下面的示例,并注意我选择的点(用绿色标记):

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)rows,cols = img.shape[0],img.shape[1]
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.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()cv.waitKey(0)
cv.destroyAllWindows()

6.透视变换 

透视变换(Perspective Transformation)是一种更加一般的变换,它可以将一个平面上的图像映射到另一个平面上,同时保持直线的直线性质,但不保持平行线的平行性。这意味着,透视变换可以改变物体的视角,使得原本平行的线在变换后的图像中会相交,产生一种深度感或透视效果

透视变换在图像处理中的应用非常广泛,比如在图像校正、三维重建、虚拟现实和增强现实等领域。它允许我们从一个特定的视角观察一个物体,就像我们通过窗户看外面的世界,窗户的框架会提供一个不同的视角,即使窗户外的物体是平面的。

在数学上,透视变换通常通过一个3x3的变换矩阵来表示,这个矩阵可以将一个二维坐标系中的点映射到另一个二维坐标系中的点。透视变换矩阵的构造通常需要四个对应的点对,即原始图像中的四个点及其在目标图像中的对应位置。

在OpenCV中,可以使用cv.getPerspectiveTransform函数来计算透视变换矩阵,然后使用cv.warpPerspective函数来应用这个变换到图像上

对透视转换,你需要一个 3x3 变换矩阵。即使在转换之后,直线也将保持直线。要找到这个变换矩阵,需要输入图像上的 4 个点和输出图像上的相应点。在这四点中,任意三点不应该共线。然后通过 cv.getPerspectiveTransform 找到变换矩阵。然后对这个 3x3 变换矩阵使用 **cv.warpPerspective**。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = r'D:\study\EmotionDetection_RealTime-master\data\data\te\01.jpg'
img = cv.imread(img)
cv.imshow('img',img)rows,cols = img.shape[0],img.shape[1]
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(rows,cols))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()cv.waitKey(0)
cv.destroyAllWindows()

cv.getPerspectiveTransform 是 OpenCV 库中的一个函数,用于计算透视变换矩阵。透视变换是一种投影变换,它可以将一个平面上的图像映射到另一个平面上,同时保持直线的直线性质,但不保持平行线的平行性。这种变换通常用于校正图像中的透视畸变,例如将照片中的矩形对象(如建筑物的立面)转换为正视图像。

函数原型如下:

cv.getPerspectiveTransform(src, dst)

参数说明:

  • src:一个包含四个源点的 numpy 数组,这些点代表原始图像中的四个角点。
  • dst:一个包含四个目标点的 numpy 数组,这些点代表变换后图像中对应角点的期望位置。

返回值是一个 3x3 的浮点型 NumPy 数组,表示透视变换矩阵。

 

这篇关于OpenCV学习(4.2) 图像的几何变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032606

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识