python实现图像的几何变换——冈萨雷斯数字图像处理

news2024/11/20 23:25:58

1、 实现图像的平移。

原理:
图像的平移是一种基本的图像处理操作,它将图像中的每个像素沿着指定的方向和距离移动,以创建一个新的平移后的图像。平移的原理很简单,通常涉及到以下几个步骤:

  1. 确定平移的距离和方向:首先,确定您希望将图像沿着哪个方向移动以及移动多远。这可以通过定义一个平移向量来实现,该向量包含了水平和垂直方向上的移动距离。

  2. 创建一个新的图像:为了执行平移操作,您需要创建一个与原始图像相同大小的新图像,通常称为目标图像。这个目标图像将用于存储平移后的图像。

  3. 遍历原始图像的像素:对于原始图像中的每个像素,将其从原始图像中取出。

  4. 计算新的像素位置:对于每个取出的像素,根据平移向量的值计算其在目标图像中的新位置。通常,新位置的计算方法如下:
    新X坐标 = 原X坐标 + 水平平移距离
    新Y坐标 = 原Y坐标 + 垂直平移距离

  5. 将像素放置到目标图像中:将每个像素放置到目标图像的新位置上。如果新位置超出了目标图像的边界,可以选择丢弃该像素或采用某种插值方法来填充。

重复步骤3至步骤5:重复以上步骤,直到遍历了原始图像的所有像素。
完成平移操作:完成后,目标图像就包含了原始图像沿指定方向平移后的图像。

在这里,我们采用OpenCV的warpAffine函数来解决图像平移,cv2.warpAffine 是 OpenCV(Open Source Computer Vision Library)中的一个函数,用于执行仿射变换(Affine Transformation)操作。仿射变换是一种线性变换,它可以用来实现图像的平移、旋转、缩放、剪切等操作。该函数的主要作用是将输入图像应用一个仿射变换矩阵,从而生成一个经过变换的输出图像。通常,可以使用这个函数来实现图像的平移、旋转、缩放和剪切等操作,而不需要手动编写复杂的像素级操作。

以下是 cv2.warpAffine 函数的一般用法:

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

src:输入图像。
M:仿射变换矩阵,用于指定要执行的变换操作。
dsize:输出图像的大小。
dst(可选):输出图像。如果未提供,则函数会创建一个新的图像。
flags(可选):插值方法的标志,用于确定如何处理像素之间的插值。
borderMode(可选):图像边界像素的处理方式,通常用于变换后的图像可能超出原始图像边界的情况。
borderValue(可选):用于边界填充的像素值。

编写代码,输出如下图所示的结果:

在这里插入图片描述
如果(x,y)方向的平移量分别为(t_x, t_y),则变换矩阵
在这里插入图片描述

可以用类型为np.float32的numpy数组来表示它,并将其作为参数传给cv2.warpAffine函数完成几何变换。上图中
在这里插入图片描述

代码实现

import  cv2
import  numpy as np
import  matplotlib.pyplot as plt
img=cv2.imread("lena_gray_512.tif")

rows,cols,channel=img.shape


affineShrink = np.array([[1,0,100],[0,1,50]],np.float32)
shrinkTwoTimes = cv2.warpAffine(img, affineShrink, (cols, rows), borderValue=10)
plt.subplot(121),plt.imshow(img,'gray'),plt.title("original")
plt.subplot(122),plt.imshow(shrinkTwoTimes,'gray'),plt.title("translation")
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

结果展示

在这里插入图片描述

2、实现图像的旋转

原理

图像旋转是数字图像处理中的一项基本操作,它的原理可以分为几个关键步骤:

**定义旋转中心:**通常旋转是围绕图像的某一点进行的。这个点可以是图像的中心,也可以是任意一点。

旋转变换:在二维空间中,旋转可以通过旋转矩阵来实现。对于一个给定的旋转角度θ,旋转矩阵是这样的:
在这里插入图片描述
这个矩阵可以用来计算图像中每个像素旋转后的新位置。

像素映射:在旋转图像时,原始图像中的像素需要映射到新的位置。这通常涉及插值算法,如最近邻插值、双线性插值或三次样条插值,以确定新位置的像素值。

处理边界问题:旋转后,图像可能会超出原始图像的边界。这可能需要对图像进行裁剪或填充。

反走样:由于旋转可能导致像素不再对齐,因此可能需要进行反走样处理以减少锯齿效应。

但是在OpenCV 允许在任意地方进行旋转,这里旋转矩阵的形式应该修改为

在这里插入图片描述
其中:

在这里插入图片描述
为了构建这个旋转矩阵,OpenCV 提供了一个函数:cv2.getRotationMatrix2D

编写代码,输出如下图所示的结果:

在这里插入图片描述

提示:

可以先用函数cv2.getRotationMatrix2D得到变换矩阵,该函数的参数包括:旋转中心坐标、旋转角度等,所以利用该函数可以实现围绕任意中心的旋转;旋转角度为正表示逆时针旋转。之后将得到的变换矩阵作为参数传给cv2.warpAffine函数完成几何变换。上图中旋转中心为图像中心,旋转角度为45°。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('lena_gray_512.tif',0)
rows,cols=img.shape
# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,1)
# 第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(cols,rows))

plt.subplot(121),plt.imshow(img,'gray'),plt.title("original")
plt.subplot(122),plt.imshow(dst,'gray'),plt.title("rotation")
plt.show()
cv2.destroyAllWindows()

结果展示

在这里插入图片描述

3、 实现图像的缩放

原理

图像缩放是数字图像处理中的一项重要技术,它涉及改变图像的尺寸,包括放大和缩小。主要流程如下

**定义缩放比例:**首先确定缩放的比例。这个比例可以是均匀的(横向和纵向相同)或不均匀的(横向和纵向不同)。
**计算新像素位置:**根据缩放比例,为原始图像中的每个像素计算在缩放后图像中的新位置。如果是放大图像,新图像中的许多像素位置将没有直接对应的原始像素;如果是缩小图像,一些原始像素将不会在新图像中有对应位置。
**像素插值:**由于缩放过程中新像素位置可能并不对应原始图像中的确切像素,因此需要通过插值算法来确定这些新位置的像素值。常见的插值方法包括:
**最近邻插值:**将新像素的值设置为最接近的原始像素值。这种方法简单快速,但可能导致图像走样。
双线性插值:考虑最接近的四个像素,通过线性插值计算新像素值。这种方法在图像质量和计算复杂度之间提供了一个较好的平衡。
**双三次插值:**考虑最接近的16个像素,使用三次插值算法计算新像素值。这种方法可以提供更高质量的结果,但计算更为复杂。
**处理边界问题:**在缩放过程中,新图像的尺寸可能与原始图像不完全相符,特别是在不均匀缩放的情况下。这可能需要对图像进行裁剪或填充。
**质量控制:**图像缩放可能会引入各种失真,如锯齿效应或模糊。因此,可能需要采用附加的图像处理技术来优化结果,如锐化处理或反走样技术。

实现下图显示的结果

在这里插入图片描述
在这里插入图片描述

提示

用函数cv2.resize对图像进行8倍放大,参数分别为cv2.INTER_NEAREST、cv2.INTER_LINEAR和cv2.INTER_CUBIC时代表选择最近邻插值法、双线性插值法、三次样条插值法。

import  cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img=cv.imread("jellybeans.png")
img= cv.cvtColor(img,cv.COLOR_RGB2GRAY)
print(img.shape)
x, y = img.shape[0:2]
near = cv.resize(img,(0,0),  fx=8, fy=8,interpolation=cv.INTER_NEAREST)
linear= cv.resize(img, (0,0), fx=8, fy=8,interpolation=cv.INTER_LINEAR)
cubic=cv.resize(img, (0,0), fx=8, fy=8,interpolation=cv.INTER_CUBIC)



plt.subplot(221),plt.imshow(img,'gray'),plt.title("original")
plt.subplot(222),plt.imshow(near,'gray'),plt.title("nearest")
plt.subplot(223),plt.imshow(linear,'gray'),plt.title("linear")
plt.subplot(224),plt.imshow(cubic,'gray'),plt.title("cubic")
plt.show()

结果展示

在这里插入图片描述

import cv2
import numpy as np
import matplotlib.pyplot as plt


img=cv2.imread("binarysmall.png")
img=cv2.cvtColor(img,cv2.COLOR_RGV2GRAY)
print(img.shape)
x,y=img.shape[0:2]
near=cv2.resize(img,(0,0),fx=8,fy=8,interpolation=cv2.INTER_NEAREST)
linear=cv2.resize(img,(0,0),fx=8,fy=8,interpolation=cv2.INTER_LINEAR)
cubic=cv2.resize(img,(0,0),fx=8,fy=8,interpolation=cv2.INTER_CUBIC)

plt.subplot(221),plt.imshow(img,"gray"),plt.title("original")
plt.subplot(222),plt.imshow(near,"gray"),plt.title("nearst")
plt.subplot(223),plt.imshow(linear,"gray"),plt.title("linear")
plt.subplot(224),plt.imshow(cubic,"gray"),plt.title("cubic")
plt.show()

结果展示

在这里插入图片描述

结果分析
INTER_NEAREST - 最近邻插值
根据名字也知道,这是插入的数值采用与原图像最近的那个点的数值,这种方法比较简单,但是人为痕迹有点重。
插值后的边缘效果:由于是以最近的点作为新的插入点,因此边缘不会出现缓慢的渐慢过度区域,这也导致放大的图像容易出现锯齿的现象
INTER_LINEAR - 线性插值
在这里插入图片描述

比如插值点为(x,y),这个像素是由围着他的4个点的像素决定的,
先求得:
f(x,0)=f(0,0)+x[f(1,0)-f(0,0)]
f(x,1)=f(0,1)+x[f(1,1)-f(0,1)]
在对求得值做一次线性插值:
f(x,y)=f(x,0)+y[f(x,1)-f(x,0)]
即可。这个准确的说是双线性
插值后的边缘效果:可以有效避免出现锯齿的现象

INTER_CUBIC –三次样条插值
基本的原理跟线性插值类似,都是做完一个方向再做另一个,不过他是用4*4的像素来计算的,但是在求权的时候不是线性的,而是逼近sin(x)/x:
在这里插入图片描述

插值后的边缘效果:可以有效避免出现锯齿的现象
总的来说,最近邻插值会出现锯齿现象,导致图片变形,感觉不太好。

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

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

相关文章

L1-060:心理阴影面积

题目描述 这是一幅心理阴影面积图。我们都以为自己可以匀速前进(图中蓝色直线),而拖延症晚期的我们往往执行的是最后时刻的疯狂赶工(图中的红色折线)。由红、蓝线围出的面积,就是我们在做作业时的心理阴影面…

kubernetes集群 应用实践 zookeeper部署

kubernetes集群 应用实践 zookeeper部署 零、环境说明 一、zookeeper持久存储准备 zookeeper属于有状态应用,需要为zookeeper部署后端存储服务。 1.1 在NFS服务器添加一块硬盘vdc [rootnfsserver ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT …

Python安装及配置

一、前置说明 Python的安装有两种方式:1. 访问Python官方网站下载安装;2. 使用Python的开源发行版进行安装。 Anaconda 是一个用于科学计算、数据分析和机器学习的开源发行版,它包含了许多常用的科学计算和数据分析库。Anaconda 不仅仅是 P…

2023美团机器人研究院学术年会成功举办

2023年12月19日,深圳市美团机器人研究院学术年会在清华大学深圳国际研究生院成功落下帷幕。会议回顾了研究院成立一年来的进展和成果,并邀请了各界专家共同讨论机器人技术的未来发展趋势。此外,年会期间还举办了首届低空经济智能飞行管理挑战…

网络基础知识制作网线了解、集线器、交换机与路由器

目录 一、网线的制作 1.1、材料 1.2、网线的标准类别 二、集线器、交换机介绍 2.1、概念: 2.2、OSI七层模型 2.3、TCP/IP四层 三、路由器的配置 3.1、概念 3.2、四个模块 1、 网络状态 2、设备管理 3、应用管理 无人设备接入控制 无线桥接 信号调节…

基于alibaba druid的血缘解析工具

基于alibaba druid的血缘解析 1、前言 SQL血缘解析指的是通过sql语句来分析该语句中表与表之间的依赖关系和字段和字段之间的依赖关系。 本血缘解析工具仅仅对mysql数据库的select查询语句进行了血缘解析(后续会持续扩展),该血缘解析包含了…

C# 使用Socket进行简单的通讯

目录 写在前面 代码实现 服务端部分 客户端部分 运行示例 总结 写在前面 在.Net的 System.Net.Sockets 命名空间中包含托管的跨平台套接字网络实现。 System.Net 命名空间中的所有其他网络访问类均建立在套接字的此实现之上。 其中的Socket 类是基于与 Linux、macOS 或 W…

python 使用 pip 安装第三方库 导入不成功

本文是什么意思呢? 就是你需要使用一些库安装老师或者网上说的 通过pip 安装下载了第三方库,但是使用 import xxx from xxx import xx ,pycharm ide 导入的下面还有红色波浪线,导入不成功。 这是什么原因? 这是pyc…

网络安全行业术语

病毒 是在计算机程序中插入的破坏计算机功能或者数据的代码,能影响计算机使用,能自我复制的一组计算机指令或者程序代码。 抓鸡 利用使用大量的程序的漏洞,使用自动化方式获取肉鸡的行为,即设法控制电脑,将其沦为肉…

【论文笔记】NeuRAD: Neural Rendering for Autonomous Driving

原文链接:https://arxiv.org/abs/2311.15260 1. 引言 神经辐射场(NeRF)应用在自动驾驶中,可以创建可编辑的场景数字克隆(可自由编辑视角和场景物体),以进行仿真。但目前的方法或者需要大量的训…

六大开源 OA 办公系统

OA,即Office Automation的缩写,意思是办公自动化、协同办公。在现代办公环境中,办公自动化已经成为了必不可少的一部分,它可以代替办公人员传统的手动部分或重复性业务活动,优质而高效地处理办公事务和业务信息,实现对…

Opencv中的滤波器

一副图像通过滤波器得到另一张图像,其中滤波器又称为卷积核,滤波的过程称之为卷积。 这就是一个卷积的过程,通过一个卷积核得到另一张图片,明显发现新的到的图片边缘部分更加清晰了(锐化)。 上图就是一个卷…

java并发编程十 原子累加器和Unsafe

文章目录 原子累加器cas 锁原理之伪共享 UnsafeUnsafe CAS 操作 原子累加器 累加器性能比较 private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {T adder adderSupplier.get();long start System.nanoTime();List<Thread…

ubuntu20.04安装timeshift最新方法

总结&#xff1a; 现在可以使用如下代码安装 sudo apt-get update sudo apt-get install timeshift原因&#xff1a; 在尝试Timeshift系统备份与还原中的方法时&#xff0c; sudo apt-add-repository -y ppa:teejee2008/ppa运行失败。 更改为以下代码&#xff1a; sudo a…

【PHY6222】绑定详解

1.函数详解 bStatus_t GAPBondMgr_SetParameter( uint16 param, uint8 len, void* pValue ) 设置绑定参数。 bStatus_t GAPBondMgr_GetParameter( uint16 param, void* pValue ) 获取绑定参数。 param&#xff1a; GAPBOND_PAIRING_MODE&#xff0c;配对模式&#xff0c;…

第4章 | 安徽某高校《统计建模与R软件》期末复习

第4章 参数估计 参数估计是统计建模的关键步骤之一&#xff0c;它涉及根据样本数据推断总体参数的过程。在统计学中&#xff0c;参数通常用于描述总体的特征&#xff0c;如均值、方差等。通过参数估计&#xff0c;我们可以利用样本信息对这些未知参数进行推断&#xff0c;从而…

LDO频率补偿

频率补偿 为了维持系统稳定的条件&#xff0c;一般的做法是建立一个低频几点&#xff0c;并把第二个极点放在单位增益频率 f0db 附近。在线性稳压器中&#xff0c;这两个极点是输出极点Po和误差放大器极点Pe。在确定了哪一个极点应该是主极点后&#xff0c;补偿的目的就是理解系…

【FPGA】Verilog 实践:优先级编码器 | Priority encoder

0x00 优先级编码器&#xff08;Priority encoder&#xff09; "能将多个二进制输入压缩成更少数目输出的电路或算法的编码器" 优先级编码器是一种编码器&#xff0c;它考虑了两个或更多输入位同时变为 1 但没有收到输入的情况。当输入进来时&#xff0c;优先级编码…

Flink实时电商数仓(五)

FlinkSQL的join Regular join普通join&#xff0c;两条流的数据都时存放在内存的状态中&#xff0c;如果两条流数据都很大&#xff0c;对内存压力很大。Interval Join: 适合两条流到达时间有先后关系的&#xff1b;一条流的存活时间短&#xff0c;一条流的存活时间长。Lookup …

使用office打开word文档时候提示错误:0x426-0x0的解决方案

在使用office打开word文档时候提示错误&#xff1a;0x426-0x0。如下图&#xff1a; 昨天还用的好好的&#xff0c;怎么今天就不行了&#xff1f;为什么呢&#xff1f; 更多工作中遇到问题见&#xff1a;凯哥BK 这个错误导致office无法启动通常是由于office软件所依赖的服务无…