在不使用cv2等库的情况下利用numpy实现双线性插值缩放图像

起因

我看到了一个别人的作业,他们老师让不使用cv2等图像处理库缩放图像

算法介绍

如果你仔细看过一些库里缩放图像的方法参数会发现有很多可选项,其中一般默认是使用双线性插值。具体步骤:

  • 计算目标图坐标对应原图中哪些坐标来填充
  • 根据双线性插值的公式写出代码

其中缩放函数使用numpy来加快速度,使用for循环缩放图像到1024*1024我的cpu运行了36s,使用numpy运行了0.38秒快了近100倍

代码

重点在于写一个函数 def resize(src, width,height):,参数是目标图像的宽高

import cv2 import numpy as np import time  def resize(src, width,height):     dst_w =  width     dst_h = height     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) 

下面可能比较难理解,np_src_x代表目标图像的x坐标,src_x也是代表目标图像的x坐标只是它有3个维度,是为了之后的索引做准备。从src_x_dst开始是计算目标图坐标需要哪些原始图坐标来填充。

    np_src_x = np.arange(0, dst.shape[1])     np_src_y = np.arange(0, dst.shape[0]).reshape((dst.shape[0], 1))     src_x = (np_src_x + np.zeros(dst.shape[:2]))[:, :, np.newaxis] + np.zeros(dst.shape)     src_y = (np_src_y + np.zeros(dst.shape[:2]))[:, :, np.newaxis] + np.zeros(dst.shape)     # 计算目标图坐标对应的原始图坐标     src_x_dst = src_x * scale_x     src_y_dst = src_y * scale_y     srcX0 = np.floor(src_x_dst).astype(int)     srcY0 = np.floor(src_y_dst).astype(int)     srcX1 = np.minimum(srcX0 + 1, src_w - 1)     srcY1 = np.minimum(srcY0 + 1, src_h - 1) 

three_axis也是为之后的索引做准备,对了,这个函数只能处理有RGB或BGR这种有3个通道的图形,其实改进应该也不难有想法的同学可以试一下。后面的value0就是具体的公式计算了

    three_axis = np.zeros(dst.shape, dtype=int)     three_axis[:, :, 1] = 1     three_axis[:, :, 2] = 2     # 根据公式计算值     value0 = (srcX1 - src_x_dst) * src[srcY0, srcX0, three_axis] + (src_x_dst - srcX0) * src[srcY0, srcX1, three_axis]     value1 = (srcX1 - src_x_dst) * src[srcY1, srcX0, three_axis] + (src_x_dst - srcX0) * src[srcY1, srcX1, three_axis]     dst = ((srcY1 - src_y_dst) * value0 + (src_y_dst - srcY0) * value1).astype(np.uint8)     return dst 

完整的代码在这里ScaleImage.py

这是效果图:
在不使用cv2等库的情况下利用numpy实现双线性插值缩放图像
...缩放图像看不出来效果

如果写的有哪里不好欢迎在评论区指出

参考

https://blog.csdn.net/wudi_X/article/details/79782832

发表评论

相关文章