OpenCV插值算法原理

插值算法

在对图像经过仿射变换(拉伸,旋转)后,图像的形状和位置发生了变化,那么变化过后的图像,每一个像素点的像素值该是多少呢??
一般是通过仿射变换的逆变换计算出原来对应的像素值,例如 f i n p u t ( 1 , 1 ) = 100 f_{input}(1,1)=100 finput(1,1)=100,现在把图像放大两倍那么输出图像 f o u p u t ( 2 , 2 ) = f i n p u t ( 1 , 1 ) = 100 f_{ouput}(2,2) = f_{input}(1,1)=100 fouput(2,2)=finput(1,1)=100
f o ( x ∗ , y ∗ ) = i n v e r s e ( f i n p u t ( x , y ) ) f_o(x^*,y^*) = inverse(f_{input}(x,y)) fo(x,y)=inverse(finput(x,y))
但是还有个问题。
f o u t p u t ( 3 , 3 ) f_{output}(3,3) foutput(3,3)是多少??,输入图像可以没有 f i n p u t ( 1.5 , 1.5 ) f_{input}(1.5,1.5) finput(1.5,1.5)这个像素点,这时候就要用到插值算法了。

近邻插值法

这个方法的精度不是很高,应该没有在使用了。但便于理解,

原理

通过输出图像计算出它在原图上的坐标点==(整数)==,如果计算的结果是整数,那直接使用。反之就要看它周围那个点离它最近,就使用最近点的像素值。
假若有一张图像矩阵如下:只有两行三列

array([[40, 41, 42],
       [43, 44, 45]])

现在我要把它放大两倍,结果应该是什么样呢,下面是一种可能的答案

array([[40, 40, 41, 41, 42, 42],
       [40, 40, 41, 41, 42, 42],
       [43, 43, 44, 44, 45, 45],
       [43, 43, 44, 44, 45, 45]])

这只是一种可能答案,因为(1.5, 1.5)这个点到它离周围距离一样,选谁都可以了,这里就图方便选择了左上角。

CODE

# Nereset Neighbor interpolation
def nn_interpolation(img: np.ndarray, ax=1, ay=1): 
    # ax ay表示放大率
    H,W,C = img.shape
    
    aH = int(ay * H)
    aW = int(ax * W) 
    
    # 此处的坐标系是(0,0)在左上角
    # 先计算出输出图像的坐标
    y = np.arange(aH).repeat(aW).reshape(aH,-1)
    x = np.tile(np.arange(aW),(aH,1))
    
    # 再计算出对应输入图像上的坐标
    y = np.round(y//ay).astype(np.int)
    x = np.round(x//ax).astype(np.int) 
    # 给输出图像赋值
    out = img[y,x]
    out = out.astype(np.uint8)
    return out
plt.imshow(nn_interpolation(lena1, ax=2, ay=1))

在这里插入图片描述

双线性插值

单线性插值

设有函数 f ( x ) f(x) f(x),在二维直角坐标系中给定两个点 ( x 0 , f ( x 0 ) ) , ( x 1 , f ( x 1 ) ) (x_0, f(x_0)), (x_1, f(x_1)) (x0,f(x0)),(x

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值