OpenCV 学习:最近邻插值与双线性插值

一、最近邻插值(The nearest interpolation)

  1. 原理: 最近邻插值是最简单的一种插值方法,不需要计算,在待求象素的四邻像素中,将距离待求象素最近的邻像素灰度赋给待求像素。设i+u, j+v (i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v) 如下图所示:
  2. 代码:
def nearest(newx,newy,img_path):
    img = cv2.imread(img_path)
    height, width, channels = img.shape
    newimg = np.zeros([newx, newy, channels], img.dtype)
    for i in range(newx):
        for j in range(newy):
            tmpx = int(i/(newx/height))
            tmpy = int(j/(newy/width))
            newimg[i, j] = img[tmpx, tmpy]
    return newimg
  1. 实测: 拿lenna试试水 原图: 插值的结果:

二、 双线性插值(Bilinear Interpolation)

  1. 线性插值: 已知坐标 ( x 0 , y 0 ) 与 ( x 1 , y 1 ) ,要得到两点 区间内某一点(x,y)在直线上的值。 y − y 0 y 1 − y 0 = x − x 0 x 1 − x 0 frac{y-y_0}{y_1-y_0}=frac{x-x_0}{x_1-x_0} y1−y0y−y0=x1−x0x−x0 y − y 0 x − x 0 = y 1 − y 0 x 1 − x 0 frac{y-y_0}{x-x_0}=frac{y_1-y_0}{x_1-x_0} x−x0y−y0=x1−x0y1−y0 y = x 1 − x x 1 − x 0 y 0 + x − x 0 x 1 − x 0 y 1 y=frac{x_1-x}{x_1-x_0}y_0+frac{x-x_0}{x_1-x_0}y_1 y=x1−x0x1−xy0+x1−x0x−x0y1
  2. 双线性插值原理: f ( i + u ,    j + v )    =    ( 1 − u )    ∗    ( 1 − v )    ∗    f ( i ,    j )    +    ( 1 − u )    ∗    v    ∗    f ( i ,    j + 1 )    +    u    ∗    ( 1 − v )    ∗    f ( i + 1 ,    j )    +    u    ∗    v    ∗    f ( i + 1 ,    j + 1 ) f(i+u,;j+v);=;(1-u);ast;(1-v);ast;f(i,;j);+;(1-u);ast;v;ast;f(i,;j+1);+;u;ast;(1-v);ast;f(i+1,;j);+;u;ast;v;ast;f(i+1,;j+1) f(i+u,j+v)=(1−u)∗(1−v)∗f(i,j)+(1−u)∗v∗f(i,j+1)+u∗(1−v)∗f(i+1,j)+u∗v∗f(i+1,j+1)
  3. 代码
def bilinear(img, out_dim):
    src_h, src_w, channel = img.shape
    # 目标图像尺寸
    dst_h, dst_w = out_dim[0], out_dim[1]
    #以dtype=np.uint8,创造一个目标图像的三维矩阵shape且值全部为0
    dst_img = np.zeros((dst_h, dst_w, 3), dtype=np.uint8)
    # 计算原图与目标图像的缩放比
    scale_x, scale_y = float(src_w) / dst_w, float(src_h) / dst_h
    # 对目标图像的三个通道进行操作
    for i in range(3):
        # 遍历每个通道上的二维矩阵
        for dst_y in range(dst_h):
            for dst_x in range(dst_w):
                # 使源图像与目标图像中心重合
                src_x = (dst_x + 0.5) * scale_x - 0.5
                src_y = (dst_y + 0.5) * scale_y - 0.5
                # np.floor 向下取整
                src_x0 = int(np.floor(src_x))
                src_x1 = min(src_x0 + 1, src_w - 1)
                src_y0 = int(np.floor(src_y))
                src_y1 = min(src_y0 + 1, src_h - 1)
                # 计算插值
                temp1 = (src_x1 - src_x) * img[src_y0, src_x0, i] + (src_x - src_x0) * img[src_y0, src_x1, i]
                temp2 = (src_x1 - src_x) * img[src_y1, src_x0, i] + (src_x - src_x0) * img[src_y1, src_x1, i]
                # 目标图像位置像素点赋值
                dst_img[dst_y, dst_x, i] = int((src_y1 - src_y) * temp1 + (src_y - src_y0) * temp2)
    return dst_img
经验分享 程序员 微信小程序 职场和发展