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

最近邻插值与双线性插值

  • 一、最近邻插值(The nearest interpolation)
    • 二、 双线性插值(Bilinear Interpolation)

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

  1. 原理:
    最近邻插值是最简单的一种插值方法,不需要计算,在待求象素的四邻像素中,将距离待求象素最近的邻像素灰度赋给待求像素。设i+u, j+v (i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v) 如下图所示:
    OpenCV 学习:最近邻插值与双线性插值_第1张图片
  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试试水
    原图:
    OpenCV 学习:最近邻插值与双线性插值_第2张图片
    插值的结果:
    OpenCV 学习:最近邻插值与双线性插值_第3张图片

二、 双线性插值(Bilinear Interpolation)

  1. 线性插值:
    已知坐标 ( x 0 , y 0 ) 与 ( x 1 , y 1 ) ,要得到两点 区间内某一点(x,y)在直线上的值。
    OpenCV 学习:最近邻插值与双线性插值_第4张图片
    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} y1y0yy0=x1x0xx0
    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} xx0yy0=x1x0y1y0
    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=x1x0x1xy0+x1x0xx0y1

  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)=(1u)(1v)f(i,j)+(1u)vf(i,j+1)+u(1v)f(i+1,j)+uvf(i+1,j+1)
    OpenCV 学习:最近邻插值与双线性插值_第5张图片

  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

你可能感兴趣的:(OpenCV,计算机视觉)