我是靠谱客的博主 知性芝麻,最近开发中收集的这篇文章主要介绍双线性插值代码讲解(bilinear_interpolation),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

    这几天再看STN网络,即空间变换网络,里面设计到双线性插值。算法虽老,但是并没有去看过,只是简单使用opencv调用过。闲来无事,就使用numpy库实现下整个流程。我认为只有代码才能让我清楚了解里面的每一步,现在对整个代码进行注释分析,方便大家理解双线性插值算法。大家可以查看这篇文章:https://blog.csdn.net/sinat_33718563/article/details/78825971。图像空间坐标变化公式如下:

    a表示图像坐标选择缩放等等仿射参数,t参数表示图像偏移信息量。有了这个(2,3)的仿射矩阵,就可以得到图像的空间变化坐标信息。

    双线性插值,就是已知Q12,22,21,11的坐标的像素值,去求p点的像素值。其中公式如下:

    因为我们是在挑选边长为1的正方形的四个角的像素值,所以(x2-x1)(y2-y1)的值为1,故公式可以简化。具体代码可以看下面的注释,如有不太明白,请留言反馈。

#coding:utf-8
import numpy as np
import cv2
#######该函数建立目标图像的像素网格,网格大小为图像高×宽,取值范围为-1,1.返回值为形状为(3,h*w)的numpy矩阵
#######[0,:]为x轴网格点   [1,:]为y轴网格点    [2,:]为1  为了进行矩阵相乘,相当与偏置
def regular_grids(img_h,img_w):
    x_linspace = np.linspace(-1,1,img_w)
    y_linspace = np.linspace(-1,1,img_h)
    x_coord,y_coord = np.meshgrid(x_linspace,y_linspace)
    x_coord = x_coord.flatten()
    y_coord = y_coord.flatten()
    ones = np.ones_like(x_coord)
    x_y_grid = np.concatenate([x_coord,y_coord,ones],axis=0)
    return np.reshape(x_y_grid,(3,img_h*img_w))
########输入参数:原图,变化后的坐标(x,y),输出图片的尺寸
def interpolation(img,sample_grid,output_size):

    height,width,num_channels = img.shape
    x = sample_grid[0,:].astype(np.float32) ####sample_grid分别保存了输出图片的网格dot仿射矩阵后的新坐标(x,y)
    y = sample_grid[1,:].astype(np.float32)
    x = 0.5 *(x+1.0)*float(width)  ####网格初始取值范围(-1,1)  +1乘以w除以0.5 变化到对应原始图片坐标
    y = 0.5 *(y+1.0)*float(height)
    x_0 = x.astype(np.int32)   ####向下取整   x_0,x_1,y_0,y_1分别代表左上和右下坐标点
    x_1 = x_0+1               #####加1
    y_0 = y.astype(np.int32)
    y_1 = y_0+1
    max_x = width-1
    max_y = height-1
    ##########进行剪裁,防止(x,y)索引超过原始图片的宽高
    x_0 = np.clip(x_0,0,max_x)
    x_1 = np.clip(x_1,0,max_x)
    y_0 = np.clip(y_0,0,max_y)
    y_1 = np.clip(y_1,0,max_y)
    #########建立索引矩阵,用于挑选原始图像中的像素值 大小为输出图像的宽×高
    base = np.zeros(shape=(output_size[0],output_size[1]),dtype='int32').flatten()

    base_y0 = base+(y_0*width) ######找到y_0,y_1在原始矩阵中的索引   因为y代表图像第y行 所以需要乘以原始图片的宽,
    base_y1 = base+(y_1*width)
    #######加上x轴坐标,找到原始图片的具体像素值索引位置
    indices_a = base_y0+x_0  ###左上像素索引位置
    indices_b = base_y1+x_0  ###左下像素索引位置
    indices_c = base_y0+x_1  ###右上
    indices_d = base_y1+x_1  ###右下
    ########挑选出对应索引位置的像素信息值
    img_flatten = np.reshape(img,newshape=(-1,num_channels))
    pixel_values_a = img_flatten[indices_a,:]
    pixel_values_b = img_flatten[indices_b,:]
    pixel_values_c = img_flatten[indices_c,:]
    pixel_values_d = img_flatten[indices_d,:]
    #####转换为float型进行计算
    x_0 = x_0.astype(np.float32)
    x_1 = x_1.astype(np.float32)
    y_0 = y_0.astype(np.float32)
    y_1 = y_1.astype(np.float32)
    #####计算各个区域的值,area_a+area_b+area_c+area_d 的值非0即1
    area_a = np.expand_dims(((x_1 - x) * (y_1 - y)), 1)  ###单位面积1的方格中,右下部分面积
    area_b = np.expand_dims(((x_1 - x) * (y - y_0)), 1)  ####右上面积
    area_c = np.expand_dims(((x - x_0) * (y_1 - y)), 1)  ####左下面积
    area_d = np.expand_dims(((x - x_0) * (y - y_0)), 1)  ####左上面积
    values_a = area_a * pixel_values_a  ### 右下面积乘以左上像素值
    values_b = area_b * pixel_values_b  ### 右上面积乘以左下像素值
    values_c = area_c * pixel_values_c  ### 左下面积乘以右上像素值
    values_d = area_d * pixel_values_d  ### 左上面积乘以右下像素值
    ###相加就是实际插入像素值
    return values_a + values_b + values_c + values_d
def transform(img,affine_matrix,output_size):
    num_channels = img.shape[2]
    ###affine_matrix.shape = (2,3)
    regular_grid = regular_grids(*output_size)
    sample_grid = np.dot(affine_matrix,regular_grid)
    final_img = interpolation(img,sample_grid,output_size)
    final_img = final_img.astype(np.uint8)
    final_img = np.reshape(final_img,(output_size[0],output_size[1],num_channels))
    return final_img
if __name__ == '__main__':
    affine_matrix = np.array([[1.5,0,0],[0,1.5,0]])
    img = cv2.imread('./test.jpg',1)
    final =transform(img,affine_matrix,output_size=(500,500))
    # cv2.imshow('img',final)
    # cv2.waitKey()

test图片,该图片是用于字符定位的素材,平常也做一些该方面的实验。

 

最后

以上就是知性芝麻为你收集整理的双线性插值代码讲解(bilinear_interpolation)的全部内容,希望文章能够帮你解决双线性插值代码讲解(bilinear_interpolation)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部