Datawhale_计算机视觉基础_图像处理(2)——双线性插值原理及numpy实现

一、双线性插值原理

双线性插值就是线性插值在二维时的推广,在两个方向上做三次线性插值

1.1 在线段 [(0,0), (0,1)]上的插值

f ( x , 0 ) = x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] + f ( 0 , 0 ) − − − ( 1 ) f(x,0)=x[f(1,0) - f(0, 0)] + f(0, 0) ---(1) f(x,0)=x[f(1,0)f(0,0)]+f(0,0)(1)

1.2 在线段 [(0,1), (1,1)]上的插值

f ( x , 1 ) = x [ f ( 1 , 1 ) − f ( 0 , 1 ) ] + f ( 0 , 1 ) − − − ( 2 ) f(x,1)=x[f(1,1) - f(0, 1)] + f(0, 1) ---(2) f(x,1)=x[f(1,1)f(0,1)]+f(0,1)(2)
在这里插入图片描述

1.3 在线段 [(x,0), (x,1)]上的插值

f ( x , y ) = y [ f ( x , 1 ) − f ( x , 0 ) ] + f ( x , 0 ) − − − ( 3 ) f(x,y)=y[f(x,1) - f(x, 0)] + f(x, 0) ---(3) f(x,y)=y[f(x,1)f(x,0)]+f(x,0)(3)

在这里插入图片描述
根据(1)(2)(3) :
f ( x , y ) = y [ x [ f ( 1 , 1 ) − f ( 0 , 1 ) ] + f ( 0 , 1 ) − ( x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] + f ( 0 , 0 ) ] + x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] + f ( 0 , 0 ) f(x,y)=y[ x[f(1,1) - f(0, 1)] + f(0, 1) - (x[f(1,0) - f(0, 0)] + f(0, 0) ]+ x[f(1,0) - f(0, 0)] + f(0, 0) f(x,y)=y[x[f(1,1)f(0,1)]+f(0,1)(x[f(1,0)f(0,0)]+f(0,0)]+x[f(1,0)f(0,0)]+f(0,0)
得出:
f ( x , y ) = [ f ( 1 , 0 ) − f ( 0 , 0 ) ] x + [ f ( 0 , 1 ) − f ( 0 , 0 ) ] y + [ f ( 1 , 1 ) + f ( 0 , 0 ) − f ( 0 , 1 ) − f ( 1 , 0 ) ] x y + f ( 0 , 0 ) f(x,y)=[f(1,0)-f(0,0)]x+[f(0,1)-f(0,0)]y+ [f(1,1)+f(0,0)-f(0,1)-f(1,0)]xy+f(0,0) f(x,y)=[f(1,0)f(0,0)]x+[f(0,1)f(0,0)]y+[f(1,1)+f(0,0)f(0,1)f(1,0)]xy+f(0,0)

二、numpy实现

主要分为三部分
1-找位置,及位置周围四个像素点
2-双线性插值算法
3-三通道分开处理


def insert_linear_pos(img_dt, resize, x_scale=None, y_scale=None):
    m_, n_ = img_dt.shape
    # 获取新的图像的大小
    if resize is None:
        n_new, m_new  =  np.round(x_scale * n_).astype(int), np.round(y_scale * m_).astype(int)
    else:
        n_new, m_new  = resize

    n_scale, m_scale = n_ / n_new, m_ / m_new # src_with/dst_with, Src_height/dst_heaight
    # 一、获取位置对应的四个点
    # 1-1- 初始化位置
    m_indxs = np.repeat(np.arange(m_new), n_new).reshape(m_new, n_new)
    n_indxs = np.array(list(range(n_new))*m_new).reshape(m_new, n_new)
    # 1-2- 初始化位置
    m_indxs_c = (m_indxs + 0.5 ) * m_scale - 0.5
    n_indxs_c = (n_indxs + 0.5 ) * n_scale - 0.5
    ### 将小于零的数处理成0 
    m_indxs_c[np.where(m_indxs_c < 0)] = 0.0
    n_indxs_c[np.where(n_indxs_c < 0)] = 0.0

    # 1-3 获取正方形顶点坐标
    m_indxs_c_down = m_indxs_c.astype(int)
    n_indxs_c_down = n_indxs_c.astype(int)
    m_indxs_c_up = m_indxs_c_down + 1
    n_indxs_c_up = n_indxs_c_down + 1
    ### 溢出部分修正
    m_max = m_ - 1
    n_max = n_ - 1
    m_indxs_c_up[np.where(m_indxs_c_up > m_max)] = m_max
    n_indxs_c_up[np.where(n_indxs_c_up > n_max)] = n_max

    # 1-4 获取正方形四个顶点的位置
    pos_0_0 = img_dt[m_indxs_c_down, n_indxs_c_down].astype(int)
    pos_0_1 = img_dt[m_indxs_c_up, n_indxs_c_down].astype(int)
    pos_1_1 = img_dt[m_indxs_c_up, n_indxs_c_up].astype(int)
    pos_1_0 = img_dt[m_indxs_c_down, n_indxs_c_up].astype(int)
    # 1-5 获取浮点位置
    m, n = np.modf(m_indxs_c)[0], np.modf(n_indxs_c)[0]
    return pos_0_0, pos_0_1, pos_1_1, pos_1_0, m, n


def linear_insert_1color(img_dt, resize, fx=None, fy=None):
    pos_0_0, pos_0_1, pos_1_1, pos_1_0, m, n = insert_linear_pos(img_dt=img_dt, resize=resize, x_scale=fx, y_scale=fy)
    a = (pos_1_0 - pos_0_0)
    b = (pos_0_1 - pos_0_0)
    c = pos_1_1 + pos_0_0 - pos_1_0 - pos_0_1
    return np.round(a * n + b * m + c * n * m + pos_0_0).astype(int)


def linear_insert(img_dt, resize, fx=None, fy=None):
    # 三个通道分开处理再合并
    if len(img_dt.shape) == 3:
        out_img0 = linear_insert_1color(img_dt[:,:,0], resize=resize, fx=fx, fy=fy)
        out_img1 = linear_insert_1color(img_dt[:,:,1], resize=resize, fx=fx, fy=fy)
        out_img2 = linear_insert_1color(img_dt[:,:,2], resize=resize, fx=fx, fy=fy)
        out_img_all = np.c_[out_img0[:,:,np.newaxis], out_img1[:,:,np.newaxis], out_img2[:,:,np.newaxis]]
    else:
        out_img_all = linear_insert_1color(img_dt, resize=resize, fx=fx, fy=fy)
    return out_img_all.astype(np.uint8)

三、实现比对

out_img_all = linear_insert(img, resize=None, fx=1.5, fy=1.5)
resized1_5_img_linear = cv2.resize(img, dsize=None, fx=1.5, fy=1.5, interpolation=cv2.INTER_LINEAR)

cv2.imshow('Origin', img)
cv2.imshow('linear_insert*1.5', out_img_all)
cv2.imshow('Origin-[INTER_LINEAR] * 1.5', resized1_5_img_linear)
cv2.waitKey(0)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scc_hy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值