数字图像处理:图像内插
图像内插
内插通常在图像放大、缩小`旋转和几何校正等任务中使用。内插是用已知数据来估计未知位置的值的过程°下面用—个简单的例子开始这—主题的探讨。假设大小为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等多种形式,用于构建具有实时数据…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
