起因
我看到了一個別人的作業,他們老師讓不使用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
這是效果圖:
...縮放影像看不出來效果