数字图像处理:图像内插
图像内插
内插通常在图像放大、缩小`旋转和几何校正等任务中使用。内插是用已知数据来估计未知位置的值的过程°下面用—个简单的例子开始这—主题的探讨。假设大小为500×500像素的—幅图像要放大1.5倍即放大到750×750像素。一种简单的放大方法是,创建—个大小为750×750像素的假想网格’网格的像素间隔完全与原图像的像素间隔相同,然后收缩网格’使它完全与原图像重叠。显然’收缩后的750×750网格的像素间隔要小于原图像的像素间隔。
数字图像处理中的图像插值是一种处理图像的方法,它涉及在已知像素值的位置上估计未知像素值的过程。图像插值在图像缩放、旋转、变形等操作中经常用到。以下是一些常见的图像插值算法:
最邻近插值(Nearest-Neighbor Interpolation)
- 基本思想是选择离目标位置最近的已知像素值作为插值结果。
- 算法简单,但可能导致图像锯齿状伪影。
最邻近插值是一种简单而直观的图像插值方法,其基本思想是在目标位置的附近选择最近的已知像素值作为插值结果。下面是最邻近插值的详细解释和Python实现示例:
最邻近插值算法:
- 目标位置确定: 对于目标位置
(x, y),找到最近的整数坐标(round(x), round(y))。 - 插值计算: 目标位置的像素值由最近的整数坐标对应的已知像素值确定。
Python实现:
import numpy as np
from PIL import Imagedef nearest_neighbor_interpolation(image, new_size):# 输入:image - 原始图像,new_size - 插值后的图像尺寸# 输出:插值后的图像# 获取原始图像尺寸old_size = image.size# 计算尺寸缩放比例scale_x = new_size[0] / old_size[0]scale_y = new_size[1] / old_size[1]# 创建新图像new_image = Image.new("RGB", new_size)# 最邻近插值for y in range(new_size[1]):for x in range(new_size[0]):# 计算原始图像中对应位置old_x = round(x / scale_x)old_y = round(y / scale_y)# 获取原始图像中的像素值pixel = image.getpixel((old_x, old_y))# 在新图像中设置像素值new_image.putpixel((x, y), pixel)return new_image# 示例:加载图像并进行最邻近插值
input_image_path = "path/to/your/image.jpg"
output_size = (400, 300)# 打开原始图像
original_image = Image.open(input_image_path)# 进行最邻近插值
result_image = nearest_neighbor_interpolation(original_image, output_size)# 显示原始图像和插值后的图像
original_image.show(title="Original Image")
result_image.show(title="Nearest Neighbor Interpolation Result")
这个示例中使用了Pillow库(PIL库的一个分支)来处理图像。确保你已经安装了这个库,你可以使用以下命令来安装:
pip install Pillow
请替换 input_image_path 为你实际的图像路径。这段代码演示了最邻近插值的基本原理和如何在Python中实现。
双线性插值(Bilinear Interpolation)
- 在最邻近插值的基础上,考虑目标位置周围的4个邻近像素,通过对这些像素进行线性插值得到目标位置的像素值。
- 较最邻近插值更平滑,但仍可能引入一些模糊。
双线性插值是一种比最邻近插值更精细的图像插值方法,它考虑了目标位置周围的四个已知像素值,通过线性插值计算目标位置的像素值。下面是双线性插值的详细解释和Python实现示例:
双线性插值算法:
- 目标位置确定: 对于目标位置
(x, y),找到其周围四个已知像素的坐标(x1, y1), (x1, y2), (x2, y1), (x2, y2)。 - 水平方向插值: 在水平方向上对目标位置的像素值进行线性插值。
- 计算水平方向上的权重:
tx = x - x1。 - 对左右两个已知像素进行线性插值:
pixel_horizontal = pixel1 * (1 - tx) + pixel2 * tx。
- 计算水平方向上的权重:
- 垂直方向插值: 在垂直方向上对水平插值后的两个像素值进行线性插值。
- 计算垂直方向上的权重:
ty = y - y1。 - 对上下两个已知像素进行线性插值:
pixel_final = pixel_top * (1 - ty) + pixel_bottom * ty。
- 计算垂直方向上的权重:
Python实现:
import numpy as np
from PIL import Imagedef bilinear_interpolation(image, new_size):# 输入:image - 原始图像,new_size - 插值后的图像尺寸# 输出:插值后的图像# 获取原始图像尺寸old_size = image.size# 计算尺寸缩放比例scale_x = new_size[0] / old_size[0]scale_y = new_size[1] / old_size[1]# 创建新图像new_image = Image.new("RGB", new_size)for y in range(new_size[1]):for x in range(new_size[0]):# 计算目标位置周围四个已知像素的坐标x1 = int(x / scale_x)y1 = int(y / scale_y)x2 = min(x1 + 1, old_size[0] - 1)y2 = min(y1 + 1, old_size[1] - 1)# 计算水平方向的插值tx = x / scale_x - x1pixel1 = image.getpixel((x1, y))pixel2 = image.getpixel((x2, y))pixel_horizontal = (1 - tx) * pixel1 + tx * pixel2# 计算垂直方向的插值ty = y / scale_y - y1pixel_top = pixel_horizontalpixel_bottom = image.getpixel((x, y2))pixel_final = (1 - ty) * pixel_top + ty * pixel_bottom# 在新图像中设置像素值new_image.putpixel((x, y), tuple(map(int, pixel_final)))return new_image# 示例:加载图像并进行双线性插值
input_image_path = "path/to/your/image.jpg"
output_size = (400, 300)# 打开原始图像
original_image = Image.open(input_image_path)# 进行双线性插值
result_image = bilinear_interpolation(original_image, output_size)# 显示原始图像和插值后的图像
original_image.show(title="Original Image")
result_image.show(title="Bilinear Interpolation Result")
这个示例同样使用了Pillow库(PIL库的一个分支)。确保你已经安装了这个库。替换 input_image_path 为你实际的图像路径。这段代码演示了双线性插值的基本原理和如何在Python中实现。
双三次插值(Bicubic Interpolation):
- 使用更多的邻近像素进行插值,通过对16个邻近像素进行三次插值得到目标位置的像素值。
- 提供更高的插值精度,但计算复杂度也更高。
双三次插值(Bicubic Interpolation)是一种更高阶的图像插值方法,它使用目标位置周围的16个已知像素值进行三次插值,以获得更精确的插值结果。以下是双三次插值的详细解释和Python实现示例:
- 目标位置确定: 对于目标位置
(x, y),找到其周围16个已知像素的坐标。 - 水平方向插值:
- 在水平方向上对目标位置的像素值进行三次插值。
- 计算水平方向上的权重:
tx = x - x1,其中x1为目标位置(x, y)的左侧最近的已知像素坐标。 - 对左右两个已知像素进行三次插值,得到水平方向的插值结果。
- 垂直方向插值:
- 在垂直方向上对水平插值后的四个像素值进行三次插值。
- 计算垂直方向上的权重:
ty = y - y1,其中y1为水平插值结果的上侧最近的已知像素坐标。 - 对上下两个已知像素进行三次插值,得到最终的插值结果。
Python实现:
import numpy as np
from PIL import Imagedef cubic(x):# 三次插值函数a = -0.5if abs(x) <= 1:return (a + 2) * abs(x)**3 - (a + 3) * abs(x)**2 + 1elif 1 < abs(x) < 2:return a * abs(x)**3 - 5 * a * abs(x)**2 + 8 * a * abs(x) - 4 * aelse:return 0def bicubic_interpolation(image, new_size):# 输入:image - 原始图像,new_size - 插值后的图像尺寸# 输出:插值后的图像# 获取原始图像尺寸old_size = image.size# 计算尺寸缩放比例scale_x = new_size[0] / old_size[0]scale_y = new_size[1] / old_size[1]# 创建新图像new_image = Image.new("RGB", new_size)for y in range(new_size[1]):for x in range(new_size[0]):# 计算目标位置周围16个已知像素的坐标x1 = max(0, int(x / scale_x) - 1)y1 = max(0, int(y / scale_y) - 1)x2 = min(old_size[0] - 1, x1 + 3)y2 = min(old_size[1] - 1, y1 + 3)# 计算水平方向的插值tx = x / scale_x - x1horizontal_values = [cubic(tx + 1 - i) for i in range(4)]pixel_horizontal = np.sum([image.getpixel((x_idx, y)) * horizontal_values[x_idx - x1] for x_idx in range(x1, x2 + 1)], axis=0)# 计算垂直方向的插值ty = y / scale_y - y1vertical_values = [cubic(ty + 1 - j) for j in range(4)]pixel_final = np.sum([pixel_horizontal * vertical_values[y_idx - y1] for y_idx in range(y1, y2 + 1)], axis=0)# 在新图像中设置像素值new_image.putpixel((x, y), tuple(map(int, pixel_final)))return new_image# 示例:加载图像并进行双三次插值
input_image_path = "path/to/your/image.jpg"
output_size = (400, 300)# 打开原始图像
original_image = Image.open(input_image_path)# 进行双三次插值
result_image = bicubic_interpolation(original_image, output_size)# 显示原始图像和插值后的图像
original_image.show(title="Original Image")
result_image.show(title="Bicubic Interpolation Result")
这个示例同样使用了Pillow库。确保你已经安装了这个库。替换 input_image_path 为你实际的图像路径。这段代码演示了双三次插值的基本原理和如何在Python中实现。
拉格朗日插值
- 使用拉格朗日多项式对已知像素值进行插值,根据目标位置与已知像素位置的相对关系计算目标位置的像素值。
- 精度较高,但计算复杂度较高。
拉格朗日插值是一种通过使用拉格朗日多项式来估计目标位置的插值方法。它在已知数据点上构建一个多项式,然后使用该多项式来估计目标位置的值。以下是拉格朗日插值的详细解释和Python实现示例:
- 目标位置确定: 对于目标位置
(x, y),找到其周围已知数据点的坐标(x1, y1), (x2, y2), ..., (xn, yn)。 - 拉格朗日多项式:
- 构建拉格朗日插值多项式:$P(x) = \sum_{i=1}^{n} y_i \prod_{j=1, j \neq i}^{n} \frac{x - x_j}{x_i - x_j} $
- 其中, n n n是已知数据点的数量, x i x_i xi和 y i y_i yi 是第 i i i 个数据点的坐标。
- 插值计算:
- 使用目标位置的 x x x 坐标代入拉格朗日插值多项式,计算得到目标位置的 y y y 坐标。
Python实现:
import numpy as npdef lagrange_interpolation(x, y, target_x):# 输入:x, y - 已知数据点的 x 和 y 坐标,target_x - 目标位置的 x 坐标# 输出:目标位置的 y 坐标(拉格朗日插值结果)n = len(x)result_y = 0.0for i in range(n):term = y[i]for j in range(n):if j != i:term *= (target_x - x[j]) / (x[i] - x[j])result_y += termreturn result_y# 示例:已知数据点进行拉格朗日插值
known_x = [1, 2, 3, 4, 5]
known_y = [2, 1, 3, 5, 4]
target_x = 2.5# 进行拉格朗日插值
result_y = lagrange_interpolation(known_x, known_y, target_x)print(f"对于 x={target_x},使用拉格朗日插值得到的 y={result_y}")
这个示例演示了如何使用拉格朗日插值进行一维数据点的插值。在实际应用中,拉格朗日插值在一些特定场景下可能不如其他插值方法精确,因为随着数据点数量的增加,插值多项式的次数会变得很高,从而引入了一些数值稳定性和计算复杂度的问题。
样条插值算法
- 利用样条函数对图像进行插值,通常使用三次样条插值。
- 提供光滑的插值结果,避免了锯齿状伪影。
选择适当的插值算法通常取决于具体的应用场景和对图像质量的要求。在实际应用中,双线性插值和双三次插值是比较常用的方法。
样条插值是一种使用分段低次多项式连接已知数据点的方法,以获得更平滑的插值结果。在样条插值中,通常使用三次样条函数(cubic splines)。下面是样条插值的详细解释和Python实现示例:
目标位置确定: 对于目标位置 (x, y),找到其周围已知数据点的坐标 (x_0, y_0), (x_1, y_1), ..., (x_n, y_n)。
- 三次样条插值:
- 在每相邻两个已知数据点之间使用三次多项式进行插值。
- 每个区间的三次多项式形式为: S i ( x ) = a i ( x − x i ) 3 + b i ( x − x i ) 2 + c i ( x − x i ) + d i S_i(x) = a_i(x - x_i)^3 + b_i(x - x_i)^2 + c_i(x - x_i) + d_i Si(x)=ai(x−xi)3+bi(x−xi)2+ci(x−xi)+di
- 其中, a i a_i ai, b i b_i bi, c i c_i ci, d i d_i di 是待定系数, x i x_i xi 是该区间的左端点。
- 插值条件:
- 三次样条插值通常要求插值函数在每个已知数据点处的一、二阶导数连续。
- 这产生了一系列的方程,通过求解这些方程获得待定系数。
Python实现:
import numpy as np
from scipy.interpolate import CubicSpline
import matplotlib.pyplot as pltdef cubic_spline_interpolation(x, y):# 输入:x, y - 已知数据点的 x 和 y 坐标# 输出:CubicSpline 插值对象# 使用 scipy 库的 CubicSpline 函数进行三次样条插值spline = CubicSpline(x, y, bc_type='natural') # 'natural' 表示自然边界条件return spline# 示例:已知数据点进行样条插值
known_x = np.array([1, 2, 3, 4, 5])
known_y = np.array([2, 1, 3, 5, 4])# 进行样条插值
spline_interpolation = cubic_spline_interpolation(known_x, known_y)# 绘制插值结果
x_values = np.linspace(min(known_x), max(known_x), 100)
y_values = spline_interpolation(x_values)plt.scatter(known_x, known_y, color='red', label='Known Data Points')
plt.plot(x_values, y_values, label='Cubic Spline Interpolation')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
在这个示例中,使用了SciPy库中的CubicSpline函数进行三次样条插值。函数的bc_type='natural'参数表示使用自然边界条件,确保插值函数的二阶导数在端点处为零。替换 known_x 和 known_y 为你实际的数据点,运行代码即可得到样条插值的结果。
相关文章:
数字图像处理:图像内插
图像内插 内插通常在图像放大、缩小旋转和几何校正等任务中使用。内插是用已知数据来估计未知位置的值的过程下面用—个简单的例子开始这—主题的探讨。假设大小为500500像素的—幅图像要放大1.5倍即放大到750750像素。一种简单的放大方法是,创建—个大小为750750像…...
Cantor表(刷题)(C语言)
个人博客主页:https://blog.csdn.net/2301_79293429?typeblog 专栏:https://blog.csdn.net/2301_79293429/category_12545690.html 题目描述 现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的&…...
linux install nvm
官网地址:https://github.com/nvm-sh/nvm 1、wget https://codeload.github.com/nvm-sh/nvm/tar.gz/refs/tags/v0.39.7 tar -zxvf v0.39.7 2、vim ~/.bashrc $HOMEroot export NVM_DIR"$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \…...
HTML 炫酷进度条
下面是代码 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>Light Loader - CodePen</title><style> html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr…...
Windows10上使Git Bash支持rsync命令操作步骤
rsync命令是linux上常用的工具之一,用于远程以及本地系统中拷贝/同步文件和文件夹。 Windows Git Bash默认并不支持rsync,如下图所示: 使Git Bash支持rsync命令操作步骤: 1.从https://repo.msys2.org/msys/x86_64/ 下…...
rust for循环里的所有权 - into_iter / iter / iter_mut
文章目录 1 遍历对象实质为 .into_iter() 生成的迭代器2 避免转移 .iter() / .iter_mut()3 for循环里自变量为什么不用加mut // for循环语法糖 for loop_variable in iterator {code() } // 解糖 {let result match IntoIterator::into_iter(iterator) {mut iter > loop {m…...
GitHub README-Template.md - README.md 模板
GitHub README-Template.md - README.md 模板 1. README-Template.md 预览模式2. README-Template.md 编辑模式References A template to make good README.md. https://gist.github.com/PurpleBooth/109311bb0361f32d87a2 1. README-Template.md 预览模式 2. README-Templat…...
【文本到上下文 #6】Word2Vec、GloVe 和 FastText
一、说明 欢迎来到“文本到上下文”博客的第 6 个系列。到目前为止,我们已经探索了自然语言处理的基础知识、应用和挑战。我们深入研究了标记化、文本清理、停用词、词干提取、词形还原、词性标记和命名实体识别。我们的探索包括文本表示技术,如词袋、TF…...
yolov5 opencv dnn部署自己的模型
yolov5 opencv dnn部署自己的模型 github开源代码地址使用github源码结合自己导出的onnx模型推理自己的视频推理条件c部署c 推理结果 github开源代码地址 yolov5官网还提供的dnn、tensorrt推理链接本人使用的opencv c github代码,代码作者非本人,也是上面作者推荐的…...
Cortex-M4处理器 电源管理
Cortex-M4处理器的休眠模式可以降低功耗。 模式可以是以下一种或两种: 休眠模式停止处理器时钟深度睡眠模式停止系统时钟,关闭锁相环和闪存。 如果设备实现了两种提供不同级别省电的睡眠模式,那么SCR的SLEEPDEEP位将选择使用哪种睡眠模式。…...
Linux 驱动开发基础知识——编写LED驱动程序(三)
个人名片: 🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:V…...
YOLOv8 视频识别
YOLOv8 是一种目标检测算法,用于识别视频中的物体。要控制视频识别中的帧,可以通过以下方式来实现: 设置帧率:可以通过设置视频的帧率来控制视频的播放速度,从而影响视频识别的速度。 跳帧处理:可以通过跳…...
elementplus Dialog 对话框设置距离页面顶部的距离
默认为 15vh,当弹窗过于高的时候,这个距离其实是不合适的 <el-dialogv-model"dialogVisible"title"Tips"width"30%":before-close"handleClose"top"6vh"><span>This is a message</s…...
便捷接口调测:API 开发工具大比拼 | 开源专题 No.62
hoppscotch/hoppscotch Stars: 56.1k License: MIT Hoppscotch 是一个开源的 API 开发生态系统,主要功能包括发送请求和获取实时响应。该项目具有以下核心优势: 轻量级:采用简约的 UI 设计。快速:实时发送请求并获得响应。支持多…...
openssl3.2/test/certs - 008 - root-nonca trust variants: +serverAuth +anyEKU
文章目录 openssl3.2/test/certs - 008 - root-nonca trust variants: serverAuth anyEKU概述笔记END openssl3.2/test/certs - 008 - root-nonca trust variants: serverAuth anyEKU 概述 openssl3.2 - 官方demo学习 - test - certs 笔记 // \file my_openssl_win_log_doc…...
cg插画设计行业怎么样,如何学习插画设计
插画设计行业是一个充满创意和艺术性的行业,随着数字化时代的不断发展,cg插画的应用范围越来越广泛,市场需求也在逐年增长。以下是一些关于acg插画设计行业的现状和发展趋势: 市场需求不断增长:随着广告、媒体、影视、…...
1.25学习总结
今天学习了二叉树,了解了二叉树的创建和遍历的过程 今天所了解的遍历过程主要分为三种,前序中序和后序,都是DFS的想法 前序遍历:先输出在遍历左节点和右节点(输出->左->右) 中序遍历:先…...
C语言每日一题(48)回文链表
力扣 234 回文链表 题目描述 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2࿱…...
提高代码效率的5个Python内存优化技巧
大家好,当项目变得越来越大时,有效地管理计算资源是一个不可避免的需求。Python与C或c等低级语言相比,似乎不够节省内存。 但是其实有许多方法可以显著优化Python程序的内存使用,这些方法可能在实际应用中并没有人注意࿰…...
基于一款热门大屏可视化设计器使用教程
乐吾乐大屏可视化设计器是一个用于创建和定制大屏幕数据可视化展示的工具,支持零代码实现物联网、工业智能制造等领域的可视化大屏、触摸屏端UI以及工控可视化的解决方案。同时也是一个Web组态工具,支持2D、3D等多种形式,用于构建具有实时数据…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
