6

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

 1 year ago
source link: https://www.cnblogs.com/zaoan660/p/17059858.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在不使用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

这是效果图:

image

...缩放图像看不出来效果

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK