美文网首页
最近邻插值与双线性插值基本原理及Python实现

最近邻插值与双线性插值基本原理及Python实现

作者: iwuqing | 来源:发表于2019-05-27 17:09 被阅读0次

1 最近邻插值

1.1 基本原理

假定

  • 源图像A的尺寸为m \times n
  • 经最近邻插值处理后的图像B的尺寸为a \times b

由此可以得到缩放倍数
K = \frac{a}{m} = \frac{b}{n}

现取B图像中的一点(x_0, y_0),可以知道对应在A图像中的理论计算位置为

(\frac{x_0 \times m}{a}, \frac{y_0 \times n}{b})

而上式得出来的在A中的理论位置数值显然可能为小数,这代表该点在A中无实际对应点,此时对其四舍五入,即是把A图像中距离该理论点最近的一个的点当作它,即为最近邻插值。

1.2 Code

import numpy as np
import math

def nearest_neighbor(input_signal, zoom_multiples):
    '''
    最近邻插值(适用于灰度图)
    :param input_signal: 输入图像
    :param zoom_multiples:  缩放倍数
    :return: 缩放后的图像
    '''
    input_signal_cp = np.copy(input_signal)   # 输入图像的副本

    input_row, input_col = input_signal_cp.shape # 输入图像的尺寸(行、列)

    # 输出图像的尺寸
    output_row = int(input_row * zoom_multiples)
    output_col = int(input_col * zoom_multiples)

    output_signal = np.zeros((output_row, output_col)) # 输出图片

    for i in range(output_row):
        for j in range(output_col):
            # 输出图片中坐标 (i,j)对应至输入图片中的(m,n)
            m = round(i / output_row * input_row)
            n = round(j / output_col * input_col)
            # 防止四舍五入后越界
            if m >= input_row:
                m = input_row - 1
            if n >= input_col:
                n = input_col - 1
            # 插值
            output_signal[i, j] = input_signal_cp[m, n]

    return output_signal

1.3 对比

  • 放大倍数 = 10
原图 使用最近邻插值放大十倍
  • 放大倍数=0.5


    原图
使用最近邻插值缩小一倍

2 双线性插值

2.1 基本原理

实际上,双线性插值的原理同最近邻类似,首先同样的步骤根据放大倍数与缩放前后的图像尺寸找到B图像中(x_0, y_0)对应A图像中(\frac{x_0 \times m}{a}, \frac{y_0 \times n}{b}),然后找到它最近的四个点,根据下列表达式计算该点的值,即完成双线性插值。

y = (1-u)(1-v)A(i,j)+(1-u)vA(i,j+1)+u(1-v)A(i+1, j)+uvA(i+1,j+1)

其中

  • i=[\frac{x_0 \times m}{a}], j =[\frac{y_0 \times n}{b}], []为向下取整
  • u = \frac{x_0 \times m}{a} - i
  • v = \frac{y_0 \times n}{b}- j

相对于最近邻插值简单的四舍五入,双线性插值的处理更为科学,优化了边缘保护。

2.2 Code

import numpy as np
import math

def double_linear(input_signal, zoom_multiples):
    '''
    双线性插值
    :param input_signal: 输入图像
    :param zoom_multiples: 放大倍数
    :return: 双线性插值后的图像
    '''
    input_signal_cp = np.copy(input_signal)   # 输入图像的副本

    input_row, input_col = input_signal_cp.shape # 输入图像的尺寸(行、列)

    # 输出图像的尺寸
    output_row = int(input_row * zoom_multiples)
    output_col = int(input_col * zoom_multiples)

    output_signal = np.zeros((output_row, output_col)) # 输出图片

    for i in range(output_row):
        for j in range(output_col):
            # 输出图片中坐标 (i,j)对应至输入图片中的最近的四个点点(x1,y1)(x2, y2),(x3, y3),(x4,y4)的均值
            temp_x = i / output_row * input_row
            temp_y = j / output_col * input_col

            x1 = int(temp_x)
            y1 = int(temp_y)

            x2 = x1
            y2 = y1 + 1

            x3 = x1 + 1
            y3 = y1

            x4 = x1 + 1
            y4 = y1 + 1

            u = temp_x - x1
            v = temp_y - y1

            # 防止越界
            if x4 >= input_row:
                x4 = input_row - 1
                x2 = x4
                x1 = x4 - 1
                x3 = x4 - 1
            if y4 >= input_col:
                y4 = input_col - 1
                y3 = y4
                y1 = y4 - 1
                y2 = y4 - 1

            # 插值
            output_signal[i, j] = (1-u)*(1-v)*int(input_signal_cp[x1, y1]) + (1-u)*v*int(input_signal_cp[x2, y2]) + u*(1-v)*int(input_signal_cp[x3, y3]) + u*v*int(input_signal_cp[x4, y4])
    return output_signal

2.3 对比

  • 放大倍数 = 0.5


    原图
使用最近邻插值缩小一倍
  • 放大倍数 = 10


    原图
使用最近邻插值放大十倍

3 GitHub

click me!

相关文章

网友评论

      本文标题:最近邻插值与双线性插值基本原理及Python实现

      本文链接:https://www.haomeiwen.com/subject/hjahtctx.html