Python图像处理【4】图像线性变换

news2025/1/11 2:55:18

图像线性变换

    • 0. 前言
    • 1. 2D 线性几何变换数学原理
    • 2. 使用 scipy.ndimage 旋转图像
    • 3. 使用 Numpy 翻转图像
    • 4. 使用 scipy.ndimage 实现仿射变换
      • 4.1 仿射变换原理
      • 4.2 实现仿射变换
    • 小结
    • 系列链接

0. 前言

图像线性变换是图像处理中的基本运算,通常用于调整图像的视觉效果,例如图像对比度、亮度、平移以及缩放等操作。我们可以用以下公式表示图像线性变换,对于输入图像 f ( x , y ) f(x,y) f(x,y),输出图像 g ( x , y ) g(x,y) g(x,y),线性变换表达式为:

g ( x , y ) = α f ( x , y ) + β g(x,y)=\alpha f(x,y)+\beta g(x,y)=αf(x,y)+β

在本节中,我们将学习 2D 线性变换的基本概念以及如何在图像中应用 2D 线性变换。我们首先从基础数学原理入手,以便在代码实现之前了解线性变化的核心思想,然后介绍如何在图像上应用欧几里得变换(例如,旋转、反射)和仿射转换。

1. 2D 线性几何变换数学原理

2D 线性几何变换是点转换,它们会被应用于图像中的每个像素。由于这些变换是线性的,因此可以使用矩阵乘法或加法等矩阵运算表示图像变换,有四类常见的线性变换:

  • 欧几里得变换 (euclidean transformation) 或等距映射 (isometry)
  • 相似性变换
  • 仿射变换
  • 单应性变换

最简单的变换称为欧几里得/等距转换,它保留了图像中像素间的欧几里得距离,且使用了相同的度量,属于正交变换,可以使用下式表示:

Ψ ( p ) = R p + t \Psi (p)= R p + t Ψ(p)=Rp+t
其中, R R R2×2 的正交矩阵, t t t2×1 的变换矢量, p = [ x , y ] p = [x,y] p=[x,y] 是要变换的点。欧几里得变换过程中距离、长度和面积是不变的,即等距变换后这些值保持不变。
等距映射具有三个自由度 (Degrees of Freedom, DoF),用于旋转矩阵 R R R 的角度 θ θ θ、用于沿 X X X 轴和 Y Y Y 轴方向的平移 t x t_x tx t y t_y ty,对应于变换矢量。欧几里得变换中的矩阵 R R R 是正交的,对于旋转变换而言矩阵行列式为 1,而对于反射变换而言行列式为 -1。在坐标系中,一个 2D 点表示为 [ x , y ] [x, y] [x,y],欧几里得变换的旋转和平移可以由坐标中的 3 × 3 3×3 3×3 矩阵 H H H 表示。
仅位置均匀缩放的等轴映射被称为相似性转换。它具有四个自由度,增加的自由度参数用于各向同性缩放。
仿射变换可以认为是非奇异线性变换,它具有六个自由度,增加的两个参数用于进行不均匀缩放。
投影变化是均匀坐标中的非奇异线性变换,它具有八个自由度。

四类线性变换

下图显示了 2D 线性几何变换的层次结构。如前所述,欧几里得是仿射的特殊情况,而后者又是投影变换的特殊情况:

线性几何变换的层次结构
最后,总结不同线性变换的属性如下:

线性变换的属性

2. 使用 scipy.ndimage 旋转图像

有时,我们可能需要几何变换作为图像处理任务中的预处理步骤。在本节中,我们将学习如何使用 scipy.ndimage 模块中的 rotate() 函数旋转图像。接下来,我们将逆时针旋转图像一定的角度,并使用样条插值。

(1) 从相应的 Python 库模块导入所需的函数,读取彩色输入图像:

from scipy.ndimage import rotate
from skimage.io import imread
from matplotlib import pyplot as plt
im = imread('1.png')

(2) 应用 scipy.ndimage 模块的 rotate() 函数,根据输入图像与旋转值执行旋转变换,逆时针旋转按照惯例应当以正角度表示,而顺时针则以负角度表示:

im = rotate(im, -45)
plt.figure(figsize=(5,5))
plt.imshow(im)
plt.axis('off') 
plt.show()

旋转图像

3. 使用 Numpy 翻转图像

在本节中,我们将学习如何使用 NumPy 的翻转操作来实现垂直 (flipped) 和水平 (flop) 翻转图像。

(1) 导入必需库,通过 Matplotlib.pyplot 模块读取输入图像,以获取图像 ndarray 作为输入:

import matplotlib.pyplot as plt
import numpy as np
im = plt.imread('1.png')

(2) 使用 Numpyflipud() 函数翻转图像 ndarray (垂直翻转)。

im_filpped = np.flipud(im)

(3) 绘制原始图像和翻转图像:

plt.figure(figsize=(10, 12))
plt.subplot(211), plt.imshow(im), plt.axis('off'), plt.title('original', size=10)
plt.subplot(212), plt.imshow(im_filpped), plt.axis('off'), plt.title('flipped', size=10) 
plt.show()

垂直翻转

(4) 使用函数 numpy.filphr() 水平翻转输入图像:

im = plt.imread('2.png')
im_filpped = np.fliplr(im)
plt.figure(figsize=(15, 12))
plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('original', size=10)
plt.subplot(122), plt.imshow(im_filpped), plt.axis('off'), plt.title('flopped', size=10) 
# np.fliplr(im)
plt.show()

水平翻转

4. 使用 scipy.ndimage 实现仿射变换

仿射变换将每个像素 f ( x , y ) f(x,y) f(x,y) 从输入图像变换到输出图像中的位置 ( x ′ , y ′ ) = T ( x , y ) (x',y')= T(x,y) (x,y)=T(x,y)。如果变换的像素坐标位于输出图像中的两个像素之间,通常通过反射(扭曲,warping)解决。在本节中,我们将使用 Scipy 库的 ndimage 模块函数实现图像上的仿射变换。

4.1 仿射变换原理

对于输出图像中位置 ( x ′ , y ′ ) (x',y') (x,y) 处的每个像素,利用以下公式从输入图像中相应位置处获取像素值:

( x , y ) = T − 1 ( x ′ , y ′ ) (x,y)=T^{-1}(x',y') (x,y)=T1(x,y)

如果输入图像中的像素位于两像素之间,则使用来自相邻像素的插值(例如,使用双线性插值)像素值进行计算。下图显示了向扭曲和反扭曲的概念:

扭曲和反扭曲的概念
反向映射过程如下:

  • 创建输出图像
  • 对于输出图像中的每个像素,找到输入图像中的对应像素
  • 赋予输出像素对应的像素值

下图给出了每个仿射变换操作的矩阵 (M):

仿射变换矩阵

我们将通过将仿射转换矩阵传递给 affine_transfom() 函数函数来实现图像转换,affine_transfom() 函数的输入参数如下:

scipy.ndimage.affine_transform(input, matrix, offset=0.0, output_shape= None, output=None, order=3, mode='constant', cval=0.0, prefilter=True)

应用仿射变换。输出图像中的位置 o 处的像素值由输入图像中的位置为 np.dot(matrix, o) + offset 处的像素值确定,其中矩阵和偏移量分别是传递给 affine_transform() 函数的 matriixoffset 参数。

4.2 实现仿射变换

接下来,我们使用 Scipy 库的 ndimage 模块实现仿射变换。

(1) 首先,导入所需的所有 Python 库:

from skimage.io import imread
from scipy.ndimage import affine_transform
import numpy as np
import matplotlib.pylab as plt

(2) 读取图像并通过传递 3×3 变换矩阵和偏移量使用函数 affine_transform() 来执行变换。 在这里,我们沿 x 轴和 y 轴(使用 @ 运算符乘上相应的变换矩阵)将图像沿正(逆时针)方向旋转 45 度:

im = imread("1.png")
rot_mat = np.array([[np.cos(np.pi/4),np.sin(np.pi/4), 0],[-np.sin(np.pi/4),np.cos(np.pi/4), 0], [0,0,1]])
shr_mat = np.array([[1, 0.45, 0], [0, 0.75, 0], [0, 0, 1]])
transformed = affine_transform(im, rot_mat@shr_mat, offset=[-im.shape[0]/4+25, im.shape[1]/2-50, 0], output_shape=im.shape)

(3) 绘制输入和输出图像,运行代码生成的输出图像:

plt.figure(figsize=(20,10))
plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('Input image', size=10)
plt.subplot(122), plt.imshow(transformed), plt.axis('off'), plt.title('Output image', size=10)
plt.show()

仿射变换结果

小结

图像线性变换是图像处理中的基本运算,在图像处理应用程序中用途广泛,例如增强图像对比度、调节图像亮度、平移图像以及缩放图像等操作,是常见的图像预处理技术。在本节中,我们学习了 2D 线性变换的基本概念以及如何在图像中应用 2D 线性变换,首先从基础数学原理入手,然后使用不同 Python 图像处理库实现了在图像上应用欧几里得变换(例如,旋转、反射)和仿射转换等线性变换。

系列链接

Python图像处理【1】图像与视频处理基础
Python图像处理【2】探索Python图像处理库
Python图像处理【3】Python图像处理库应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring Cloud】如何安装与配置Nacos注册中心?

本期目录1. Nacos介绍2. Nacos安装2.1 Windows安装3. 配置Nacos3.1 引入依赖3.2 修改配置文件3.3 启动并测试1. Nacos介绍 Nacos 是阿里巴巴的产品,使用 Java 语言开发。比 Eureka 功能更丰富,除了可以作注册中心,还可以作配置中心。 2. Nac…

【Java开发】Staffjoy 02 :系统架构设计

本文主要对 Staffjoy 项目的架构做一个介绍和衍生,包括数据模型、各服务接口模型及框架选择等,希望能让大家对于项目有个整体的把握和判断,本文最后也列举了 Dubbo、Spring Cloud 和 K8s 三种微服务框架的异同~ 目录 1 架构设计 1.1 总体架…

毕业设计 基于PID控制的智能平衡车 - stm32 物联网 单片机【超详细】

文章目录0 前言1 课题背景2 设计内容3 设计方案3.1 设计思路3.3 硬件设计3.4 软件设计3.4.1 关键技术 - PID控制算法3.4.2 关键技术 - 倾角估计算法3.4.3 关键技术 - 直立控制算法3.4.4 速度控制3.4.5 方向控制4 视频演示5 最后0 前言 🔥 这两年开始毕业设计和毕业…

长短时记忆网络(LSTM)负荷预测项目(matlab)

目录 1. LSTM介绍 2. 数据集准备及预处理 3. LSTM模型搭建与训练 4. 预测模型测试 1. LSTM介绍 长短期记忆网络 LSTM(long short-term memory)是 RNN 的一种变体,其核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径…

每日一道LeetCode(一):两数之和

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

刷完这1000道JAVA面试题,让你成功逆袭上岸

内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等技术栈。 由于整个笔记比较全面,内容相当的多 ,这里仅展示面经中的面试真题&#xff0…

Keras深度学习实战(41)——语音识别

Keras深度学习实战(41)——语音识别0.前言1. 模型与数据集分析1.1 数据集分析1.2 模型分析2. 语音识别模型2.1 数据加载与预处理2.2 模型构建与训练小结系列链接0.前言 语音识别(Automatic Speech Recognition, ASR,或称语音转录文本)使声音…

openssl加密base64编码

openssl OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。 首先,要安装 openssl: centos命令: sudo yum install openssl-devel ubuntu命令&#x…

WebService基于Baidu OCR和Map API的导航服务

哈尔滨工业大学国家示范性软件学院 《面向服务的软件系统》大作业 项目题目: 基于OCR和地图API的路牌定位与导航服务 项目组成员: 姓名 学号 李启明 120L021920 完成日期: 2022年 12 月 15 日 1.选题 1.1 作业…

NUS CS5477 assignment1

课程链接三维视觉 作业任务任务 课程任务就一个,实现一个Linear Sweep Algorithm,这个算法是用来检测两张图片之间的对应点。 因为SIFT检测如果把检测点的数量增大,可能会存在一些错误错误检测点,所有通常把SIFT检测的点的数量…

内网穿透:在家远程ssh访问学校内部网服务器

注册一个cpolar账号 cpolar官网注册即可(邮箱即可) cpolar支持http/https/tcp协议,不限制流量(花生壳免费只能使用1G流量),也不需要公网ip,只要在服务器上安装客户端即可配置,免费&…

攻防世界-file_include

题目 访问路径获得源码 <?php highlight_file(__FILE__);include("./check.php");if(isset($_GET[filename])){$filename $_GET[filename];include($filename);} ?> 通过阅读php代码&#xff0c;我们明显的可以发现&#xff0c;这个一个文件包含的类型题…

Java项目:ssm校内超市管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本系统分为管理员与普通用户两种角色。采用后端SSM框架&#xff0c;前端BootStrap&#xff08;前后端不分离&#xff09;的系统架构模式&#x…

python中调用命令行执行外部程序

&#x1f31e;欢迎来到python的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f320;本阶段属于练气阶段&#xff0c;希望各位仙友顺利完成…

STM32的三种更新固件的方式

说明&#xff1a; stm32有三种更新固件的方式&#xff0c;分别为&#xff08;1&#xff09;DFU模式&#xff08; Development Firmware Upgrade 即“开发固件升级”&#xff09;&#xff1b;&#xff08;2&#xff09;SWD/JLINK 下载 &#xff08;3&#xff09;第三方bootload…

NoSQL数据库原理与应用综合项目——HBase篇

NoSQL数据库原理与应用综合项目——HBase篇 文章目录NoSQL数据库原理与应用综合项目——HBase篇0、 写在前面1、本地数据或HDFS数据导入到HBase2、Hbase数据库表操作2.1 Java API 连接HBase2.2 查询数据2.3 插入数据2.4 修改数据2.5 删除数据3、Windows远程连接HBase4、数据及源…

springboot常用组件集成

今天与大家分享spring-mybatis、reids集成&#xff0c;druid数据库连接池。如果有问题&#xff0c;望指教。 1. 创建项目 File -> New -> project ...Spring Initializr选择项目需要的第三方组件注&#xff1a;可以参考第二次课演示的操作步骤&#xff0c;有详细的拷图…

java药店网站药店系统药店源码刷脸支付源码

简介 首页&#xff0c;搜索商品&#xff0c;详情页&#xff0c;根据不同规格显示不同的商品价格&#xff0c;加入购物车&#xff0c;立即购买&#xff0c;评价列表展示&#xff0c;商品详情展示&#xff0c;商品评分&#xff0c;分类商品&#xff0c;标签查询&#xff0c;更多…

MapReduce 概述原理说明

文章目录MapReduce概述一、MapReduce定义二、MapReduce 优缺点1、MapReduce 优点(1)、MapReduce 易于编程(2)、良好的扩展性(3)、高容错性(4)、适合PB级以上的海量数据的离线处理2、MapReduce 缺点(1)、不擅长实时计算(2)、不擅长流式计算(3)、不擅长DAG(有向图)计算三、MapRed…

二叉树进阶

博主的博客主页&#xff1a;CSND博客 Gitee主页&#xff1a;博主的Gitee 博主的稀土掘金&#xff1a;稀土掘金主页 博主的b站账号&#xff1a;程序员乐 公众号——《小白技术圈》&#xff0c;回复关键字&#xff1a;学习资料。小白学习的电子书籍都在这。 目录根据二叉树创建字…