双线性插值的理解与python实现
2018-04-01 22:41
477 查看
介绍
双线性插值是图像缩放的一种方式,其主要分为两步线性插值,一是在x方向插值,二是用x方向插值结果再在y方向插值,具体步骤如下:1.定位像素点
先找到目标图像像素点(dst_x, dst_y)在源图像上的像素点位置(src_x, src_y)。一般是使用直接缩放:
src_x=dst_x * scale_x (scale_x为源图像与目标图像宽比例)
而我们这里使用几何中心对称:
src_x = (dst_x + 0.5) * scale_x - 0.5
然后找到上下左右最近邻的四个像素点用于计算插值。
2.两步插值
设(x,y)(x,y)为插值点在源图像的坐标,待计算插值为zz首先x方向上插值:相邻两点为(x0,y0)(x0,y0)、(x1,y0)(x1,y0),像素值分别为z0=f(x0,y0)z0=f(x0,y0)、z1=f(x1,y0)z1=f(x1,y0),从而有公式:z−z0x−x0=z1−z0x1−x0z−z0x−x0=z1−z0x1−x0,从而插值z=x1−xx1−x0z0+x−x0x1−x0z1z=x1−xx1−x0z0+x−x0x1−x0z1
然后y方向上插值:以上得到的上方插值zz记为ztopztop,同理可得下方插值为zbotzbot,那么最后插值为:Z=y1−yy1−y0ztop+y−y0y1−y0zbotZ=y1−yy1−y0ztop+y−y0y1−y0zbot
python实现
# coding=utf-8 import cv2 import numpy as np import time def resize(src, new_size): dst_w, dst_h = new_size # 目标图像宽高 src_h, src_w = src.shape[:2] # 源图像宽高 if src_h == dst_h and src_w == dst_w: return src.copy() scale_x = float(src_w) / dst_w # x缩放比例 scale_y = float(src_h) / dst_h # y缩放比例 # 遍历目标图像,插值 dst = np.zeros((dst_h, dst_w, 3), dtype=np.uint8) for n in range(3): # 对channel循环 for dst_y in range(dst_h): # 对height循环 for dst_x in range(dst_w): # 对width循环 # 目标在源上的坐标 src_x = (dst_x + 0.5) * scale_x - 0.5 src_y = (dst_y + 0.5) * scale_y - 0.5 # 计算在源图上四个近邻点的位置 src_x_0 = int(np.floor(src_x)) src_y_0 = int(np.floor(src_y)) src_x_1 = min(src_x_0 + 1, src_w - 1) src_y_1 = min(src_y_0 + 1, src_h - 1) # 双线性插值 value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, n] + (src_x - src_x_0) * src[src_y_0, src_x_1, n] value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, n] + (src_x - src_x_0) * src[src_y_1, src_x_1, n] dst[dst_y, dst_x, n] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1) return dst if __name__ == '__main__': img_in = cv2.imread('./JPEGImages/000001.jpg') start = time.time() img_out = cv2.resize(img_in, (600,600)) print 'cost %f seconds' % (time.time() - start) cv2.imshow('src_image', img_in) cv2.imshow('dst_image', img_out) cv2.waitKey()
总结
由于实现插值是通过遍历像素点,是串行方式且在cpu上运行,因此比较耗时,复杂度和输出图片尺寸有关,实测512*512图像耗时为3s左右,而opencv中的cv2.resize()函数速度很快,具体实现需进一步了解。相关文章推荐
- <python 深入理解>变量交换x,y=y,x实现机制--元组
- 想了解python的urllib2是怎么实现的,可以看pypy版本便于理解
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
- LSTM结构理解与python实现
- 机器学习实战_kNN算法python3.6实现与理解
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
- 深刻理解Python中的元类(metaclass)以及元类实现单例模式
- 机器学习-线性回归算法(python实现)个人理解
- leetcode 2. Add Two Numbers python实现的理解,结点,单链表的应用,大数,进位的问题
- LZW算法的个人理解与简单Python实现
- Python的协程,线程,进程的理解及实现
- 理解python的staticmethod与classmethod实现
- 机器学习之深入理解神经网络理论基础、BP算法及其Python实现
- 机器学习算法笔记系列之深入理解主成分分析PCA-Python实现篇
- 容易理解的python用队列实现广度优先遍历文件
- 决策树理解与python实现
- k最近邻算法(K-Nearest Neighbor)理解与python实现
- 教程 | 理解和实现自然语言处理终极指南(附Python代码)
- 支持向量机SVM通俗理解(python代码实现)