前言
参考这篇论文:《Deep Learning for Image Super-resolution:A Survey》
简单来说,插值指利用已知的点来“猜”未知的点,图像领域插值常用在修改图像尺寸的过程,由旧的图像矩阵中的点计算新图像矩阵中的点并插入,不同的计算过程就是不同的插值算法。
插值算法有很多种,这里列出关联比较密切的三种:
- 最近邻法(Nearest Interpolation):计算速度最快,但是效果最差。
- 双线性插值(Bilinear Interpolation):双线性插值是用原图像中4(2*2)个点计算新图像中1个点,效果略逊于双三次插值,速度比双三次插值快,属于一种平衡美,在很多框架中属于默认算法。
- 双三次插值(Bicubic interpolation):双三次插值是用原图像中16(4*4)个点计算新图像中1个点,效果比较好,但是计算代价过大。
最近邻插值法
(1)理论
最近邻插值法nearest_neighbor是最简单的灰度值插值。也称作零阶插值,就是令变换后像素的灰度值等于距它最近的输入像素的灰度值。
最近邻插值法坐标变换计算公式:
srcX=dstX*(srcWidth/dstWidth)
srcY=dstY*(srcHeight/dstHeight)
上式中,dstX与dstY为目标图像的某个像素的横纵坐标,dstWidth与dstHeight为目标图像的长与宽;srcWidth与srcHeight为原图像的宽度与高度。srcX,srcY为目标图像在该点(dstX,dstY)对应的原图像的坐标。与opencv一样,以左上角为(0,0)坐标。
右图为经过放大后的目标图像,?处的坐标为(3,2),根据公式计算得到
srcX=3*(2/4)=1.5,srcY=2*(2/4)=1;
故?处的像素应该为原图像中的(1.5,1)像素的值,但是像素坐标没有小数,一般采用四舍五入取最邻,所以最终的结果为(2,1),对应原图像的橙色。
(2)python实现
'''@author: songcongcong'''
import numpy as np
import cv2
# 最近邻插值
def nearest_neighbour(src, dst_shape):
# 获取原图维度
src_height, src_width = src.shape[0], src.shape[1]
# 计算新图维度
dst_height, dst_width, channels = dst_shape[0], dst_shape[1], dst_shape[2]
dst = np.zeros(shape = (dst_height, dst_width, channels), dtype=np.uint8)
for dst_x in range(dst_height):
for dst_y in range(dst_width):
# 寻找源图像对应坐标
src_x = dst_x * (src_width/dst_width)
src_y = dst_y * (src_height/dst_height)
# 四舍五入会超出索引,这里采用向下取整,也就是原本1.5->2, 现在是1.5->1
src_x = int(src_x)
src_y = int(src_y)
# 插值
ddst[dst_x, dst_y,:] = src[src_x, src_y, :]
return dst
src = cv2.imread('me.jpg')
dst = nearest_neighbour(src, dst_shape=(720, 540, 3))
# 显示 </