最临近插值
- 最近邻插值在图像放大时补充的像素取最临近的像素的值。由于方法简单,所以处理速度很快,但是放大图像画质劣化明显。
def nn_interpolate(img, ax=1, ay=1):
H, W, C = img.shape
# zero padding
aH = int(ax * H)
aW = int(ay * W)
out = np.zeros((aH, aW, C), dtype=np.float)
for y in range(aH):
for x in range(aW):
for c in range(C):
out[y, x, c] = img[int(y/ay),int(x/ax),c]//非常简单粗暴的插值法
return out.astype(np.uint8)
双线性插值
- 双线性插值考察4邻域的像素点,并根据距离设置权值。虽然计算量增大使得处理时间变长,但是可以有效抑制画质劣化。
- 放大后图像的座标(x′,y′)除以放大率a,可以得到对应原图像的座标([],[])
- 求原图像的座标([],[])周围4邻域的座标I(x,y),I(x+1,y),I(x,y+1),I(x+1,y+1)
- 分别求这4个点与([],[])的距离,根据距离设置权重:w=
- 根据下式求得放大后图像(x′,y′)处的像素值
- dx= - x 计算距离
- dy= - y 计算距离
-
I'(x',y')=(1-dx)(1-dy)I(x,y)+dx(1-dy)I(x+1,y)+(1-dx)dyI(x,y+1)+dxdyI(x+1,y+1)
- 依据基本直观感觉,权重应与距离成反比。上述公式推导,即若(x,y)点所给权重为t,则(x+1,y)给权重为tdx/(1-dx),同理(x,y+1)所贡献权重为tdy/(1-dy),(x+1,y+1)所给权重为tdxdy/(1-dx)(1-dy),又(1-dx)(1-dy)+dx(1-dy)+dy(1-dx)+dxdy刚好等于1,则解得t=(1-dx)(1-dy),即得上述四邻域权值分别为dxdy,dx(1-dy),dy(1-dx),(1-dx)(1-dy)
def bl_interpolate(img, ax=1,ay=1):
H, W, C = img.shape #首先取得原图像的尺寸大小
# zero padding
aH = int(ay * H) #计算插值后的图像尺寸
aW = int(ax * W) #计算插值后的图像尺寸
out = np.zeros((aH, aW, C), dtype=np.float) #重建图像
for y in range(aH):
for x in range(aW):
for c in range(C):
y1=y/ay #换算后的坐标
x1=x/ax #换算后的坐标
dy=y1-int(y1) #计算dy值
dx=x1-int(x1) #计算dx值
py=int(y1)
px=int(x1)
py1=int(y1)+1
px1=int(x1)+1
py=py if py<H else H-1 #防越界处理
px=px if px<W else W-1 #防越界处理
py1=py1 if py1<H else H-1 #防越界处理
px1 = px1 if px1 < W else W-1 #防越界处理
zuobiao1=img[py,px,c] #获取四邻域坐标值
zuobiao2 = img[py1, px, c] #获取四邻域坐标值
zuobiao3 = img[py, px1, c] #获取四邻域坐标值
zuobiao4 = img[py1, px1, c] #获取四邻域坐标值
out[y, x, c] = int(dx*dy*zuobiao4+dx*(1-dy)*zuobiao3+dy*(1-dx)*zuobiao2+(1-dx)*(1-dy)*zuobiao1) #根据上述推导的公式进行插值
return out.astype(np.uint8)
双三次插值
- 双三次插值是对双线性插值的扩展,即扩充至邻域16个像素值的加权平均
def BICUBIC(image, a=1.5):
H, W, C = image.shape
aH = np.int(H * a)
aW = np.int(W * a)
result = np.zeros((aH, aW, C))
for ah in range(aH):
for aw in range(aW):
#对应的原图像上的像素坐标
h0 = int(np.floor(ah / a))
w0 = int(np.floor(aw / a))
#防止溢出
h1 = np.minimum(h0 + 1, H - 1)
w1 = np.minimum(w0 + 1, W - 1)
h2 = np.minimum(h0 + 2, H - 2)
w2 = np.minimum(w0 + 2, W - 2)
h1m = np.maximum(h0 - 1, 0)
w1m = np.maximum(w0 - 1, 0)
#转为数组形式便于循环计算
h_array = np.array([h1m, h0, h1, h2])
w_array = np.array([w1m, w0, w1, w2])
#计算距离
dh_array = np.abs(h0 - h_array)
dw_array = np.abs(w0 - w_array)
sumh = 0
sumI = 0
for i in range(4):
for j in range(4):
sumh += ht_CALCULATE(dw_array[i], a) * ht_CALCULATE(dh_array[j], a)
sumI += image[h_array[i], w_array[i]] * ht_CALCULATE(dw_array[i], a) * ht_CALCULATE(dh_array[j], a)
result[ah,aw] = sumI / sumh
result = np.clip(result, 0, 255).astype(np.uint8)
return result
#计算权重
def ht_CALCULATE(t,a):
t = np.abs(t)
if t <= 1:
ht = (a+2)*(t ** 3) - (a+3) * (t ** 2) + 1
elif 1 < t <= 2:
ht = a*(t ** 3) - 5*a*(t ** 2) + 8*a * t -4*a
else:
ht = 0
return ht
网友评论