最邻近插值和双线性插值

本文详细介绍图像缩放中的两种插值法:最邻近插值和双线性插值。最邻近插值法简单易实现,但效果较差;双线性插值法通过四个点估计插值,使图像更细腻,但计算量大。文中还提供了Python实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  插值在图像中的应用一般为处理图像的缩放。所谓缩放就是缩小和放大。在所有插值缩放算法中要数最邻近插值最简单最暴力,当然效果也是最不好的。经过该算法进行放大的图片会出现马赛克现象,而进行缩小的图片也会丢失较大的图像信息。下面介绍两种插值法,最邻近插值和双线性插值。

1. 最邻近插值法
  最近临插值算法的原理是在原图像中找到最近临的一个点,然后把这个点的像素值插入到目标图像中,最近临插值算法优点是算法简单,易于实现。
算法公式如下:
       ori_x = dst_x * (ori_width / dst_width)
       ori_y = dst_y * (ori_height / dst_height)
ori_x、ori_y为原图像的横纵点,dst_x、dst_y为缩放后横纵点,ori_witdh/dst_height为缩放比率。对一个图像放大,实际上是先计算原图像中的虚拟位置,比如4x4的图像要缩放到8x8,即在4x4原图像中横坐标4个点生成8个点,虚拟位置可以通过插值求出,出现小数时我们可以用四舍五入或者向下或向上取整的方法来获得对应的原图坐标。正因为这个机制的引入,才导致最后的生成图效果不佳。

2. 双线性插值法
在这里插入图片描述
双线性插值公式为:
   f(i+u,j+v) = (1-u)(1-v)f(i,j)+u(1-v)f(i+1,j)+(1-u)vf(i,j+1)+ uvf(i+1,j+1)
原理同上,不过双线性插值算法是用四个点进行估计插值,图像较最邻近插值更显细腻,但计算量较大。

python实现

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

def resize_nerghbor(src_data, dst_height, dst_width):
      ori_height, ori_width, channel = src_data.shape
      ratio_height = ori_height / dst_height
      ratio_width = ori_width / dst_width
      dst_data = np.zeros((dst_height, dst_width, channel), np.uint8)
      for i in range(channel):
          for y in range(dst_height):
              for x in range(dst_width):
                  x_ori = int(x * ratio_width)
                  y_ori = int(y * ratio_height)          #取整
                  dst_data[y, x, i] = src_data[y_ori, x_ori, i]
      return dst_data


def resize_bilinear(src_data, dst_height, dst_width):
    ori_height, ori_width, channel = src_data.shape
    ratio_height = ori_height / dst_height
    ratio_width = ori_width / dst_width
    dst_data = np.zeros((dst_height, dst_width, channel), np.uint8)
    for i in range(channel):
        for y in range(dst_height):
            for x in range(dst_width):
                x_ori = x * ratio_width
                y_ori = y * ratio_height
                u = x_ori - math.floor(x_ori)
                v = y_ori - math.floor(y_ori)    # 取小数部分
                dst_data[y, x, i] = src_data[math.floor(y_ori), math.floor(x_ori),i]*(1 - u) * (1 - v) + \
                                    src_data[math.floor(y_ori), math.ceil(x_ori),i] * (1 - u) * v + \
                                    src_data[math.ceil(y_ori), math.floor(x_ori),i] * u * (1-v) + \
                                    src_data[math.ceil(y_ori), math.ceil(x_ori),i] * u * v         #取整、按公式进行运算
    return dst_data

m = cv2.imread('xian.jpg')
n = resize_bilinear(m,540,960)
n = cv2.cvtColor(n, cv2.COLOR_BGR2RGB)
plt.imshow(n)
plt.show()
# cv2.imshow('resize_image', n)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

在这里插入图片描述

原图缩小后:
在这里插给发发描述

参考: 1.Matlab——图像缩放(插值法)
    2.使用双线性插值法放大图像(matlab实现)
    3.最临近插值和双线性插值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值