图像的双线性插值

效果

bilinear interpolation

理论部分

在进行图片尺寸调整时,目标图像像素是根据所对应的原图像像素值进行取值,而这个取值计算过程是根据对应的原图像像素值的邻近的四个整数像素值进行双线性运算得到。
双线性插值

  • 在x方向做插值,即求出直线R1R2
    x方向
  • 在直线R1R2上求出坐标y(在y方向做插值)
    在这里插入图片描述
  • 整合式子即为
    在这里插入图片描述
  • 可以理解为,先根据x轴方向的比例关系求出R1,R2的像素对象,再由R1,R2像素对象做y轴上的比例运算求出直线R1R2上确定的像素对象点。
  • 也可以先做y方向插值,再做x方向插值
优化:

常规方法,目标图片所对应原图片对应的情况下:
在这里插入图片描述
这时会出现一个问题
当我们把5x5图像调整为3x3的时候,如果以左上角为原点进行计算,则图像会出现失真和丢失像素值的问题(右侧和下侧的像素失真严重)
在这里插入图片描述

最好的方法就是,两个图像的几何中心重合,并且目标图像的每个像素之间都是等间隔的,并且都和两边有一定的边距
在这里插入图片描述

我们设原图像和目标图像都要平移z距离,才能使几何中心重合

  • step1:先列出原图像和目标图像几何中心 如原图片几何中心坐标X=(M-1)/2 , y = (M-1)/2
    在这里插入图片描述

  • step2:使几何中心相同:
    在这里插入图片描述

  • step3:计算得到结果z=1/2,式子为:(Src表示原图片,dst表示目标图片)
    在这里插入图片描述

  • 双线性差值法的计算比最邻近插值法复杂,计算量较大,但没有灰度不连续的缺点,图像看起来更光滑

代码部分

"""
@author: Hanley-Yang

彩色图像的双线性插值
"""

import numpy as np
import cv2

def bilinear_interpolation(img, outDim):
    srcH, srcW, channel = img.shape
    dstH, dstW = outDim[0], outDim[1]
    #如果原图像和输出图像尺寸一致,则直接返回原图像
    if srcH == dstH and srcW == dstW:
        return img.copy()
    dstImg = np.zeros((dstH,dstW,3),dtype=np.uint8)
    scaleX,scaleY = float(srcW) / dstW, float(srcH) / dstH

    for i in range(channel):
        for dstY in range(dstH):
            for dstX in range(dstW):

                #找到输出图片的像素对应的原图像的像素坐标x和y
                #使原图像和输出图像的几何中心对应
                #srcX + 0.5 = (dstX + 0.5) * scale
                srcX = (dstX + 0.5) * scaleX - 0.5
                srcY = (dstY + 0.5) * scaleY - 0.5

                #根据原图像对应的像素坐标进行插值计算
                #X0,X1,Y0,Y1,坐标两两组合对应着最邻近的四个像素值
                srcX0 = int(np.floor(srcX)) #np.floor向下取整
                srcX1 = min(srcX0 + 1,srcW - 1) #srcW-1保证不越界
                srcY0 = int(np.floor(srcY))
                srcY1 = min(srcY0 + 1,srcH - 1)

                #计算插值,求对应原图像像素所在的x的直线,再算出直线x上的(x,y)像素对象
                temp0 = (srcX1 - srcX) * img[srcY0,srcX0,i] + (srcX-srcX0)*img[srcY0,srcX1,i]
                temp1 = (srcX1 - srcX) * img[srcY1,srcX0,i] + (srcX-srcX0)*img[srcY1,srcX1,i]
                dstImg[dstY,dstX,i] = int((srcY1-srcY) * temp0 + (srcY - srcY0) * temp1)

    return dstImg

if __name__ == '__main__':
    img = cv2.imread('Euphonium.png')
    dst = bilinear_interpolation(img,(1080,1920))

    # 保存处理后的图片到当前目录
    cv2.imwrite("bilinear interpolation.png",dst)
    cv2.imshow('bilinear interpolation',dst)

    cv2.waitKey()
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hanley_Yeung

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

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

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

打赏作者

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

抵扣说明:

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

余额充值