机器视觉学习(五)—— 图像的几何-程序员宅基地

技术标签: 机器视觉  笔记  计算机视觉  学习方法  opencv  

目录

一、图像的几何变化

1.1 图像的翻转

1.2 图像的仿射变化

1.3 图像的平移

1.4 图像的旋转

1.5 图像的缩放

1.5.1 使用resize函数

1.5.2 使用pyrUp和pyrDown函数

1.5.3 使用图像金字塔

1.6 图像的透视变换


一、图像的几何变化

图像的几何变化指的是通过改变图像的位置、尺寸和方向等参数来实现的图像变换。常见的图像几何变化包括平移、旋转、缩放和翻转等。

  1. 平移:将图像在平面上按照指定的平移距离水平或垂直移动。

  2. 旋转:按照指定的角度将图像绕中心或其他指定点进行旋转。

  3. 缩放:按照指定的比例增大或缩小图像的尺寸。

  4. 翻转:在水平或垂直方向上反转图像,得到镜像效果。

除了上述基本的几何变换,还可以进行透视变换、扭曲变换、仿射变换等复杂的图像变换,实现更加丰富的效果。

1.1 图像的翻转

在OpenCV中,可以使用函数cv2.flip()来实现图像的翻转。该函数接受三个参数:

  • src:要翻转的输入图像。
  • flipCode:指定翻转的方式。可以是以下三个值之一:
    • 0:沿x轴翻转(垂直翻转)
    • 1:沿y轴翻转(水平翻转)
    • -1:同时沿x轴和y轴翻转(同时水平和垂直翻转)
  • dst:可选参数,指定输出图像。如果不提供,则函数会在原始图像上进行翻转。

下面是一个使用cv2.flip()函数来对图像进行翻转的示例:

import cv2

# 加载图像
image = cv2.imread('image.png')            # 在运行代码时将image.png替换为您的图像文件路径

# 垂直翻转图像
flipped_image = cv2.flip(image, 0)

# 水平翻转图像
flipped_image = cv2.flip(image, 1)

# 同时水平和垂直翻转图像
flipped_image = cv2.flip(image, -1)

# 显示原始图像和翻转后的图像
cv2.imshow('Original', image)              # 显示图像
cv2.imshow('Flipped', flipped_image)
cv2.waitKey(0)                             # 等待用户按下任意键
cv2.destroyAllWindows()                    # 关闭窗口

1.2 图像的仿射变化

cv2.warpAffine()是OpenCV中的一个函数,用于对图像进行仿射变换。仿射变换是一种线性变换,可以用来旋转、平移、缩放和剪切图像。

函数如下: dst = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

参数解释:

  • src:输入图像。
  • M:仿射变换的3x2变换矩阵。可以通过cv2.getRotationMatrix2D()、cv2.getAffineTransform()等函数获得。
  • dsize:输出图像的大小。
  • dst(可选):输出图像。
  • flags(可选):插值方法的标志。默认值为cv2.INTER_LINEAR,可选的插值方法有:
    • cv2.INTER_NEAREST:最近邻插值。
    • cv2.INTER_LINEAR:双线性插值。
    • cv2.INTER_CUBIC:双三次插值。
    • cv2.INTER_LANCZOS4:Lanczos插值。
  • borderMode(可选):边界填充模式。默认为cv2.BORDER_CONSTANT,可选的边界填充模式有:
    • cv2.BORDER_CONSTANT:边界填充为常数,默认为黑色。
    • cv2.BORDER_REPLICATE:边界复制。
    • cv2.BORDER_REFLECT:边界反射。
    • cv2.BORDER_REFLECT_101:边界反射101。
    • cv2.BORDER_WRAP:边界包裹。
  • borderValue(可选):边界填充的值,当borderMode为cv2.BORDER_CONSTANT时生效。

函数返回值:

  • dst:仿射变换后的图像。

变换矩阵是一个2x3的矩阵,可以通过cv2.getAffineTransform()函数来计算。变换矩阵需要三个点的坐标作为输入,分别是原始图像中的三个点和目标图像中的三个点。

下面是一个使用OpenCV进行仿射变换的示例代码:

import cv2
import numpy as np

# 读取图像
img = cv2.imread(image.png')      # 在运行代码时将image.png替换为您的图像文件路径

# 原始图像中的三个点
pts1 = np.float32([[50,50], [200,50], [50,200]])

# 目标图像中的三个点
pts2 = np.float32([[10,100], [200,50], [100,250]])

# 计算变换矩阵
M = cv2.getAffineTransform(pts1, pts2)

# 进行仿射变换
dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))

# 显示结果
cv2.imshow('Original Image', img)     # 名称可修改
cv2.imshow('Transformed Image', dst)     # 名称可修改
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面的代码中,我们首先读取一张图像,然后定义了原始图像中的三个点和目标图像中的三个点。接下来,我们使用cv2.getAffineTransform()函数计算变换矩阵,然后使用cv2.warpAffine()函数进行变换。最后,我们将原始图像和变换后的图像显示出来。

1.3 图像的平移

上述中提到,我们可以使用cv2.warpAffine()函数。该函数可以根据指定的平移参数对图像进行平移操作。

以下是一个简单的例子,展示如何使用OpenCV对图像进行平移:

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg')    # 在运行代码时将image.jpg替换为您的图像文件路径

# 获取图像的高度和宽度
height, width = img.shape[:2]

# 定义平移矩阵
M = np.float32([[1, 0, 100], [0, 1, 50]])

# 使用平移矩阵进行图像平移
translated_img = cv2.warpAffine(img, M, (width, height))

# 显示原始图像和平移后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Translated Image', translated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中,我们先读取了一张图像,并使用img.shape[:2]获取图像的高度和宽度。然后,我们定义了一个2x3的平移矩阵M,其中M[0,2]表示水平平移量,M[1,2]表示垂直平移量。在本例中,我们将图像向右平移100个像素,向下平移50个像素。

最后,我们使用cv2.warpAffine()函数对图像进行平移操作,传入参数为原始图像、平移矩阵M以及输出图像的大小。平移后得到的图像存储在translated_img变量中,并通过cv2.imshow()函数显示出来。

注意:

  • 平移后的图像可能会超出原始图像的边界,因此可以根据需要调整平移参数以确保图像不被裁剪。

1.4 图像的旋转

以下是一个基本的旋转图像的示例代码:

import cv2

# 加载图像
img = cv2.imread("image.jpg")

# 获取图像宽度和高度
height, width = img.shape[:2]

# 定义旋转角度和缩放比例
angle = 45
scale = 1.0

# 计算旋转后的图像尺寸
new_width = int(width * scale)
new_height = int(height * scale)

# 定义旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D((width / 2, height / 2), angle, scale)

# 进行旋转操作
rotated_img = cv2.warpAffine(img, rotation_matrix, (new_width, new_height))

# 显示结果
cv2.imshow("Rotated Image", rotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面的代码中,我们首先加载图像并获取图像的宽度和高度。然后定义旋转角度和缩放比例。通过cv2.getRotationMatrix2D函数创建一个旋转矩阵,该矩阵可以在后续的旋转操作中使用。最后,使用cv2.warpAffine函数将旋转矩阵应用于图像,得到旋转后的图像。最后,通过cv2.imshow函数显示旋转结果。

注意:

  • 在这个示例中,旋转中心点被设置为图像的中心点,你可以根据需要修改旋转中心点的位置。

1.5 图像的缩放

使用OpenCV进行图像缩放有多种方法,以下是其中几种常用的方法:

1.5.1 使用resize函数

可以通过resize函数来将图像缩放到指定的大小。该函数的参数包括待缩放的源图像,目标图像的大小和插值方法。示例代码如下:

import cv2

# 读取图像
img = cv2.imread('image.jpg')

# 缩放图像
resized_img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_LINEAR)

# 显示缩放后的图像
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.5.2 使用pyrUp和pyrDown函数

这两个函数可以实现图像的金字塔缩放,即通过不断下采样或上采样来达到缩放效果。示例代码如下:

import cv2

# 读取图像
img = cv2.imread('image.jpg')

# 下采样缩放
resized_img = cv2.pyrDown(img)

# 上采样缩放
resized_img = cv2.pyrUp(img)

# 显示缩放后的图像
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.5.3 使用图像金字塔

通过使用cv2.pyrDown和cv2.pyrUp函数,可以构建一个多层图像金字塔,并通过逐层降采样和上采样来实现缩放。示例代码如下:

import cv2

# 读取图像
img = cv2.imread('image.jpg')

# 构建图像金字塔
pyramid = [img]
for i in range(levels):
    img_down = cv2.pyrDown(pyramid[i])
    pyramid.append(img_down)

# 获取指定层级的图像缩放结果
resized_img = pyramid[target_level]

# 显示缩放后的图像
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.6 图像的透视变换

透视变换是一种对图像进行形状变换的技术,可以将一个平面上的任意四边形区域变换为一个矩形区域。

在OpenCV中,可以使用cv2.getPerspectiveTransform()函数来计算透视变换的转换矩阵,然后使用cv2.warpPerspective()函数将图像进行透视变换。

下面是一个简单的示例代码,展示了如何进行透视变换:

import cv2
import numpy as np

# 读取原始图像
image = cv2.imread('image.jpg')

# 定义原始图像的四个顶点坐标
points1 = np.float32([[50,50], [200,50], [50,200], [200,200]])

# 定义变换后的图像的四个顶点坐标
points2 = np.float32([[0,0], [300,0], [0,300], [300,300]])

# 计算透视变换矩阵
matrix = cv2.getPerspectiveTransform(points1, points2)

# 进行透视变换
result = cv2.warpPerspective(image, matrix, (300,300))

# 显示原始图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Perspective Transformation', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这个示例中,我们首先读取了一张原始图像,然后定义了原始图像的四个顶点坐标(points1)和变换后的图像的四个顶点坐标(points2)。使用cv2.getPerspectiveTransform()函数计算透视变换矩阵,并使用cv2.warpPerspective()函数对图像进行透视变换。

最后,使用cv2.imshow()函数显示原始图像和变换后的图像,使用cv2.waitKey()函数等待用户按下任意键后关闭窗口,并使用cv2.destroyAllWindows()函数释放所有窗口的资源。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_74375828/article/details/136793224

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签