python实现图像缩放算法

news2024/11/15 14:07:27

图像缩放算法

      • 1.最近邻插值图像缩放算法详解
        • 算法步骤
        • Python 实现
        • 详细解释
      • 优缺点
      • 2.双线性插值图像缩放算法详解
        • 算法步骤
        • Python 实现
        • 详细解释
      • 优缺点
      • 3.双三次插值图像缩放算法详解
        • 算法步骤
        • Python 实现
        • 详细解释
      • 优缺点

1.最近邻插值图像缩放算法详解

最近邻插值(Nearest Neighbor Interpolation)是一种简单且直观的图像缩放算法。它通过选择离目标像素最近的原始像素的颜色值来确定目标像素的颜色值。尽管这种方法计算速度快,但由于未考虑周围像素的颜色信息,图像在放大时可能会出现明显的锯齿效应。

算法步骤
  1. 计算缩放比例:确定新图像和原始图像的宽高比例。
  2. 遍历新图像像素:逐个计算新图像中每个像素的位置。
  3. 确定最近邻像素:对于新图像中的每个像素,找到对应的原始图像中的最近邻像素。
  4. 赋值:将原始图像中最近邻像素的颜色值赋给新图像中的像素。
Python 实现

以下是最近邻插值图像缩放算法的Python实现代码:

import numpy as np
from PIL import Image

def nearest_neighbor_interpolation(image, new_width, new_height):
    original_width, original_height = image.size  # 获取原始图像的宽度和高度
    new_image = Image.new("RGB", (new_width, new_height))  # 创建一个新的图像对象
    pixel_map = new_image.load()  # 获取新图像的像素映射

    # 遍历新图像的每个像素
    for i in range(new_width):
        for j in range(new_height):
            # 计算在原始图像中对应的像素位置
            x = int(i * original_width / new_width)
            y = int(j * original_height / new_height)
            
            # 获取原始图像中对应像素的颜色值,并赋值给新图像的当前像素
            pixel_map[i, j] = image.getpixel((x, y))

    return new_image

# 示例用法
if __name__ == "__main__":
    image = Image.open('example.jpg')  # 打开原始图像
    new_width, new_height = 800, 600  # 定义新图像的宽度和高度
    new_image = nearest_neighbor_interpolation(image, new_width, new_height)  # 调用最近邻插值函数
    new_image.show()  # 显示新图像
    new_image.save('resized_example.jpg')  # 保存新图像
详细解释
  1. 读取图像和创建新图像

    image = Image.open('example.jpg')
    new_image = Image.new("RGB", (new_width, new_height))
    
  2. 遍历新图像的每个像素

    for i in range(new_width):
        for j in range(new_height):
    
  3. 计算对应的原始图像像素位置

    x = int(i * original_width / new_width)
    y = int(j * original_height / new_height)
    
  4. 获取原始图像像素的颜色并赋值给新图像

    pixel_map[i, j] = image.getpixel((x, y))
    

优缺点

优点

  • 简单快速:算法简单,计算速度快,适合实时处理。
  • 实现容易:代码简单易懂,适合入门学习图像处理。

缺点

  • 锯齿效应:在图像放大时容易出现锯齿效应,图像质量不高。
  • 细节丢失:在图像缩小时可能会丢失一些细节。

尽管最近邻插值在某些应用场景中足够使用,但在需要更高质量图像的场景中,通常会选择更加复杂的插值方法,如双线性插值或双三次插值。

2.双线性插值图像缩放算法详解

双线性插值(Bilinear Interpolation)是一种常用的图像缩放算法。它通过考虑目标像素周围四个像素的颜色值,使用双线性插值公式计算出目标像素的颜色值。相较于最近邻插值,双线性插值能生成更平滑的图像效果。

算法步骤
  1. 计算缩放比例:确定新图像和原始图像的宽高比例。
  2. 遍历新图像像素:逐个计算新图像中每个像素的位置。
  3. 确定邻近像素:找到目标像素在原始图像中的对应位置,确定其周围的四个像素。
  4. 双线性插值计算:使用双线性插值公式计算目标像素的颜色值。
Python 实现

以下是双线性插值图像缩放算法的Python实现代码:

import numpy as np
from PIL import Image

def bilinear_interpolation(image, new_width, new_height):
    original_width, original_height = image.size  # 获取原始图像的宽度和高度
    new_image = Image.new("RGB", (new_width, new_height))  # 创建一个新的图像对象
    pixel_map = new_image.load()  # 获取新图像的像素映射
    
    for i in range(new_width):
        for j in range(new_height):
            # 计算在原始图像中对应的浮点像素位置
            x = i * (original_width - 1) / new_width
            y = j * (original_height - 1) / new_height
            
            # 计算相邻四个像素的位置
            x1 = int(x)
            x2 = min(x1 + 1, original_width - 1)
            y1 = int(y)
            y2 = min(y1 + 1, original_height - 1)
            
            # 计算插值权重
            dx = x - x1
            dy = y - y1
            
            # 获取相邻四个像素的颜色值
            p1 = np.array(image.getpixel((x1, y1)))
            p2 = np.array(image.getpixel((x2, y1)))
            p3 = np.array(image.getpixel((x1, y2)))
            p4 = np.array(image.getpixel((x2, y2)))
            
            # 计算目标像素的颜色值
            pixel_value = (1 - dx) * (1 - dy) * p1 + dx * (1 - dy) * p2 + (1 - dx) * dy * p3 + dx * dy * p4
            pixel_map[i, j] = tuple(pixel_value.astype(int))
    
    return new_image

# 示例用法
if __name__ == "__main__":
    image = Image.open('example.jpg')  # 打开原始图像
    new_width, new_height = 800, 600  # 定义新图像的宽度和高度
    new_image = bilinear_interpolation(image, new_width, new_height)  # 调用双线性插值函数
    new_image.show()  # 显示新图像
    new_image.save('resized_example.jpg')  # 保存新图像
详细解释
  1. 读取图像和创建新图像

    image = Image.open('example.jpg')
    new_image = Image.new("RGB", (new_width, new_height))
    
  2. 遍历新图像的每个像素

    for i in range(new_width):
        for j in range(new_height):
    
  3. 计算对应的原始图像浮点位置

    x = i * (original_width - 1) / new_width
    y = j * (original_height - 1) / new_height
    
  4. 确定相邻四个像素的位置

    x1 = int(x)
    x2 = min(x1 + 1, original_width - 1)
    y1 = int(y)
    y2 = min(y1 + 1, original_height - 1)
    
  5. 计算插值权重

    dx = x - x1
    dy = y - y1
    
  6. 获取相邻四个像素的颜色值

    p1 = np.array(image.getpixel((x1, y1)))
    p2 = np.array(image.getpixel((x2, y1)))
    p3 = np.array(image.getpixel((x1, y2)))
    p4 = np.array(image.getpixel((x2, y2)))
    
  7. 计算目标像素的颜色值

    pixel_value = (1 - dx) * (1 - dy) * p1 + dx * (1 - dy) * p2 + (1 - dx) * dy * p3 + dx * dy * p4
    pixel_map[i, j] = tuple(pixel_value.astype(int))
    

优缺点

优点

  • 平滑效果好:生成的图像更加平滑,减少了锯齿效应。
  • 适用广泛:在各种图像处理应用中广泛使用,平衡了计算复杂度和图像质量。

缺点

  • 计算复杂度较高:相比最近邻插值,计算量更大,处理速度较慢。
  • 细节保留一般:在某些情况下,细节保留效果不如双三次插值。

在这里插入图片描述

双线性插值是图像缩放中常用的方法之一,适合需要平滑效果但计算资源有限的应用场景。

3.双三次插值图像缩放算法详解

双三次插值(Bicubic Interpolation)是一种高级的图像缩放算法。它通过考虑目标像素周围16个像素的颜色值,使用双三次插值公式计算出目标像素的颜色值。相较于双线性插值,双三次插值能生成更平滑、更细腻的图像效果。

算法步骤
  1. 计算缩放比例:确定新图像和原始图像的宽高比例。
  2. 遍历新图像像素:逐个计算新图像中每个像素的位置。
  3. 确定邻近像素:找到目标像素在原始图像中的对应位置,确定其周围的16个像素。
  4. 双三次插值计算:使用双三次插值公式计算目标像素的颜色值。
Python 实现

以下是双三次插值图像缩放算法的Python实现代码:

import numpy as np
from PIL import Image

def cubic_weight(t, a=-0.5):
    """计算三次插值核函数的权重"""
    t = np.abs(t)
    if t <= 1:
        return (a + 2) * t**3 - (a + 3) * t**2 + 1
    elif t <= 2:
        return a * t**3 - 5 * a * t**2 + 8 * a * t - 4 * a
    else:
        return 0

def bicubic_interpolation(image, new_width, new_height):
    original_width, original_height = image.size
    new_image = Image.new("RGB", (new_width, new_height))
    pixel_map = new_image.load()
    image_array = np.array(image)

    for i in range(new_width):
        for j in range(new_height):
            # 计算在原始图像中对应的浮点像素位置
            x = i * (original_width - 1) / new_width
            y = j * (original_height - 1) / new_height
            
            x1 = int(np.floor(x))
            y1 = int(np.floor(y))
            
            # 初始化颜色值
            r, g, b = 0, 0, 0

            # 双三次插值计算
            for m in range(-1, 3):
                for n in range(-1, 3):
                    xm = min(max(x1 + m, 0), original_width - 1)
                    yn = min(max(y1 + n, 0), original_height - 1)
                    weight = cubic_weight(x - xm) * cubic_weight(y - yn)
                    pixel = image_array[yn, xm]
                    r += pixel[0] * weight
                    g += pixel[1] * weight
                    b += pixel[2] * weight

            # 赋值给新图像的像素
            pixel_map[i, j] = (int(r), int(g), int(b))

    return new_image

# 示例用法
if __name__ == "__main__":
    image = Image.open('example.jpg')  # 打开原始图像
    new_width, new_height = 800, 600  # 定义新图像的宽度和高度
    new_image = bicubic_interpolation(image, new_width, new_height)  # 调用双三次插值函数
    new_image.show()  # 显示新图像
    new_image.save('resized_example.jpg')  # 保存新图像
详细解释
  1. 三次插值核函数

    def cubic_weight(t, a=-0.5):
        """计算三次插值核函数的权重"""
        t = np.abs(t)
        if t <= 1:
            return (a + 2) * t**3 - (a + 3) * t**2 + 1
        elif t <= 2:
            return a * t**3 - 5 * a * t**2 + 8 * a * t - 4 * a
        else:
            return 0
    
  2. 读取图像和创建新图像

    image = Image.open('example.jpg')
    new_image = Image.new("RGB", (new_width, new_height))
    
  3. 遍历新图像的每个像素

    for i in range(new_width):
        for j in range(new_height):
    
  4. 计算对应的原始图像浮点位置

    x = i * (original_width - 1) / new_width
    y = j * (original_height - 1) / new_height
    x1 = int(np.floor(x))
    y1 = int(np.floor(y))
    
  5. 双三次插值计算

    # 初始化颜色值
    r, g, b = 0, 0, 0
    
    # 双三次插值计算
    for m in range(-1, 3):
        for n in range(-1, 3):
            xm = min(max(x1 + m, 0), original_width - 1)
            yn = min(max(y1 + n, 0), original_height - 1)
            weight = cubic_weight(x - xm) * cubic_weight(y - yn)
            pixel = image_array[yn, xm]
            r += pixel[0] * weight
            g += pixel[1] * weight
            b += pixel[2] * weight
    
  6. 赋值给新图像的像素

    pixel_map[i, j] = (int(r), int(g), int(b))
    

优缺点

优点

  • 高质量:生成的图像更加平滑,细节更丰富。
  • 适用广泛:在需要高质量图像处理的应用中广泛使用。

缺点

  • 计算复杂度高:相比双线性插值,计算量更大,处理速度较慢。
  • 实现复杂:代码复杂度高,不适合实时处理。

在这里插入图片描述

双三次插值是图像缩放中高质量的方法之一,适合需要高质量图像处理的应用场景。

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

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

相关文章

【网络】计算机网络基础——计算机网络背景和发展、认识网络协议、OSI七层模型、TCP/IP四层模型、网络的传输

文章目录 Linux网络1. 计算机网络背景和发展2. 认识网络协议3. OSI七层模型3.1 物理层3.2 数据链路层3.3 网络层3.4 传输层3.5 会话层3.6 表示层3.7 应用层 4. TCP/IP四层模型5. 网络的传输 Linux网络 1. 计算机网络背景和发展 开始的计算机都是独立模式&#xff08;计算机之间…

与众不同的社交体验:Facebook的新功能与新变化

在快速变化的社交媒体领域&#xff0c;Facebook不断引入创新功能和变化&#xff0c;以满足用户日益增长的需求&#xff0c;并提供与众不同的社交体验。从增强现实到数据隐私&#xff0c;Facebook的新功能和更新正在塑造一个全新的社交平台。本文将深入探讨这些新功能和变化&…

3W单声道关断模式音频功率放大器AD4150B

前言&#xff1a; 国产功放介绍 NS4890C 2.4W 单声道AB类音频放大器 AD4150B 3W单声道关断模式音频功率放大器 参考价格0.3元 产品概述 AD4150B是一款单声道带关断模式&#xff0c;桥式音频功率放大器。在5.5V工作电压时&#xff0c;平均驱动功率为&#xff1a;3W&#xff08…

计算机网络之http和https的区别(外加http详解)

http协议和各种协议之间的关系 1、DNS解析&#xff0c;获取到访问服务器的IP 2、HTTP生成请求报文请求&#xff0c;请求访问页面资源 3、TCP协议将报文切割成一份一份报文段后&#xff0c;以可靠的方式进行传输 4、IP协议边搜索边中转&#xff0c;将这些数据包传输给接受方…

关于c#的简单应用三题

#region 输入一个正整数&#xff0c;求1~这个数的阶乘 public static void Factorial(int a) { int result 1; for (int i 1; i < a; i) { result result * i; } Console.WriteLine(result); } #endregion #region 一个游戏&#…

详解Stable Diffusion 原理图

参考英文文献&#xff1a;The Illustrated Stable Diffusion – Jay Alammar – Visualizing machine learning one concept at a time. 在这个Stable Diffusion模型的架构图中&#xff0c;VAE&#xff08;变分自编码器&#xff09;模型对应的是图中的 E 和 D 部分。 具体来说…

keystone学习小结2

简介 通过源码 官方文档 进行学习 官方文档 架构 identity 提供user和group的鉴权及数据 可以用这些数据处理增删改查的请求 这些服务在某些情况也可以托管在授权的服务中&#xff0c;有认证任务时&#xff0c;授权的服务会执行认证的任务&#xff0c;而不会把这些转发到…

SuperMap GIS基础产品FAQ集锦(20240715)

一、SuperMap iDesktopX 问题1&#xff1a;想问一下&#xff0c;线数据更改粗细和颜色&#xff0c;他只能保存到地图中吗&#xff1f;我希望能修改源数据&#xff0c;但是保存不了&#xff1f; 11.1.1 【问题原因】简单数据集不支持保存风格。 【解决办法】入需保存风格&…

SAP中途增加批次管理提示:库存在工厂级别已经存在。

SAP中途增加批次管理提示&#xff1a;库存在工厂级别已经存在。 在这种情况&#xff0c;将需要启用批次管理功能的物料主数据进行出库&#xff0c;通过移动类型201&#xff08;562&#xff09;进行出库&#xff0c;然后再修改物料主数据&#xff0c;当成功启用物料主数据的批次…

前置-Linux相关知识速记

linux Linux命令大全 [!IMPORTANT] chown-chmod-ls-chgrp-cdpwd-mkdir-rmdir-cp-rm-mv-cat-tac-nl-more-less-head-tail 应用领域 通常服务器使用 LAMP&#xff08;Linux Apache MySQL PHP&#xff09;或 LNMP&#xff08;Linux Nginx MySQL PHP&#xff09;组合。 目前…

700.二叉搜索树的搜索

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,3], val 2 输出&#xff1a;[2,1,3]…

SmartX 超融合 vs vSAN 8:数据库场景下的性能对比

此前&#xff0c;我们以 vSAN 7 为例&#xff0c;对比了 SmartX 与 VMware 超融合在快照、缓存、I/O 路径上的技术差异&#xff0c;及其带来的性能影响。不同于 vSAN 7&#xff0c;vSAN 8 引入了快速存储架构 ESA&#xff08;Express Storage Architecture&#xff09;&#xf…

SpringCloud------Seata(分布式事务)

分布式事务产生原因 CAP定理(一致性、可用性、分区容错性) BASE理论 解决思想 Seata 三个角色

【操作系统】线程池的底层逻辑解析及实现

目录 线程池一、线程池是什么二、底层线程池 ThreadPoolExecutor三、实现线程池四、标准库中的线程池Executors 线程池 一、线程池是什么 在我们频繁的创建线程时或销毁线程时,都会进行系统调度从而占用系统资源,虽然创建线程/销毁线程的开销不是很大,但架不住量多,进而我们该…

photoshop学习笔记——选区

选区工具快捷键&#xff1a;M shift M 切换 矩形/椭圆选区工具 基本用法 选区框选出的地方被激活&#xff08;其后进行的操作&#xff0c;仅在选区中生效&#xff09; 选区工具选择后&#xff08;以矩形选区为例&#xff09; 按下鼠标左键拖动&#xff0c;画出一块矩形区…

TCP连接与释放

目录 引言 一. TCP连接的建立 二.TCP连接的释放 三.TCP连接状态机 引言 传输控制协议(Transmission Control Protocol,TCP)作为互联网上最广泛使用的协议之一,其在网络通信中扮演着关键角色。其中,TCP连接的建立与释放是TCP协议中最为重要的部分之一。本文将对TCP连接的建立…

【笔记:3D航路规划算法】一、RRT

目录 关键概念3D路径规划算法1. A*算法2. RRT1. 初始化&#xff1a;2. 实例化搜索算法&#xff1a;3. 路径生成&#xff1a;4. 绘制图像&#xff1a; 3D路径规划是在三维空间中寻找从起点到终点的最短或最优路径的一种技术。它广泛应用于无人机导航、机器人运动规划、虚拟现实等…

谷粒商城实战笔记-48~49-商品服务-API-三级分类-查询-树形展示三级分类数据-前端优化

文章目录 一&#xff0c;48-商品服务-API-三级分类-查询-树形展示三级分类数据1&#xff0c;创建商品服务命名空间2&#xff0c;商品服务增加配置3&#xff0c;网关增加商品服务的路由配置4&#xff0c;前端树形展示5&#xff0c;测试 二&#xff0c;49-商品服务-API-三级分类-…

未来的智能交通系统:智能合约在交通管理中的应用前景

随着城市化进程的加快和交通问题日益突出&#xff0c;智能交通系统成为了解决城市交通拥堵和安全问题的重要手段。本文将探讨智能合约在未来智能交通系统中的应用前景&#xff0c;分析其在交通管理中的潜力和优势。 什么是智能交通系统&#xff1f; 智能交通系统利用先进的信息…

数据结构经典测题3

1. 设有定义&#xff1a; char *p; &#xff0c;以下选项中不能正确将字符串赋值给字符型指针 p 的语句是【多选】&#xff08; &#xff09; A: pgetchar(); B: scanf("%s",p); C: char s[]"china"; ps; D: *p"china"; 答案为ABD A选项&…