下面是正常实现双线性插值的代码
from PIL import Image
import numpy as np
import math
img_array = np.array(Image.open('NNI0.1.jpg'))
print(img_array.shape)
oringin_height,oringin_width = img_array.shape[:2]
scale = 4
new_height = int(oringin_height*scale)
new_width = int(oringin_width*scale)
new_img_array = np.zeros((new_height,new_width,img_array.shape[2]),dtype=img_array.dtype)
for h in range(new_height):
for w in range(new_width):
map_h0 = math.floor(h/scale)
map_h1 = min(oringin_height-1,map_h0 + 1)
map_w0 = math.floor(w/scale)
map_w1 = min(oringin_width-1,map_w0 + 1)
delta_w = w / scale - map_w0
delta_h = h / scale - map_h0
top = delta_w * img_array[map_h0, map_w1] + (1 - delta_w) * img_array[map_h0, map_w0]
bottom = delta_w * img_array[map_h1, map_w1] + (1 - delta_w) * img_array[map_h1, map_w0]
new_img_array[h, w] = delta_h * bottom + (1 - delta_h) * top
new_img = Image.fromarray(new_img_array)
new_img.show()
最初根据原理进行推导时没有使用权重表达式来写,双线性插值的权重表达式为
上述公式对应的代码是:
delta_w = w / scale - map_w0
delta_h = h / scale - map_h0
top = delta_w * img_array[map_h0, map_w1] + (1 - delta_w) * img_array[map_h0, map_w0]
bottom = delta_w * img_array[map_h1, map_w1] + (1 - delta_w) * img_array[map_h1, map_w0]
new_img_array[h, w] = delta_h * bottom + (1 - delta_h) * top
而是直接使用最原始公式来写
对应的代码是:
delta_w = w / scale - map_w0
delta_h = h / scale - map_h0
top = img_array[map_h0,map_w0]+((img_array[map_h0,map_w1]-img_array[map_h0,map_w0])*(delta_w))
bottom = img_array[map_h1,map_w0]+((img_array[map_h1,map_w1]-img_array[map_h1,map_w0])*(delta_w))
new_img_array[h,w] = bottom +((top-bottom)*(1-(delta_h)))
对图像产生了不同的处理效果,如下图所示
图1.正常双线性插值图像 图2.产生计算误差的图像
gpt解释说:
误差可能是来源:
1.累加误差:浮点运算中的乘法和加法运算顺序,有时会导致小数误差在图像处理过程中累积,产生比加权求和更多的数值不准确之处。
2.乘法与加法的顺序产生误差:在浮点数运算中,乘法与加法的顺序也会导致误差不同,先乘后加更稳妥