3D图像线性插值算法实现
- 三线性插值原理
三线性插值原理与双线性插值原理类似,双线性插值是根据周围四个点计算得到新的插值点,三线性插值是对一个立方体中周围8个顶点进行计算。
1)首先在x轴上进行插值,根据以下公式分别求出4个边上的点C00,C01,C10,C11
2)在y轴上进行插值,根据一下公式得到C0和C1点
3)最后在z轴上进行插值
其中xd, yd,zd是指偏移量,与x,y,z较小的坐标有关。xd = x - |xd|
实际上三线性插值等同于两个双线性插值与线性插值的组合。当前这样计算起来很麻烦,所以使用另一个方案进行编写插值算法。
- 替代算法
求解方程线性找到系数
直接看结果吧,反正我也推不出来
- 算法实现
import numpy as np
import math
def Interpolation3D(src_img, dst_size):
#srcImage原3d图像,dst_size插值后图像的大小
srcZ, srcY, srcX = src_img.shape #原图图像大小
dst_img = np.zeros(shape = dst_size, dtype = np.int16) #插值后的图像
new_Z, new_Y, new_X = dst_img.shape #
print("插值后图像的大小", dst_img.shape)
factor_z = srcZ / new_Z
factor_y = srcY / new_Y
factor_x = srcX / new_X
for z in range(new_Z):
for y in range(new_Y):
for x in range(new_X):
src_z = z * factor_z
src_y = y * factor_y
src_x = x * factor_x
src_z_int = math.floor(z * factor_z)
src_y_int = math.floor(y * factor_y)
src_x_int = math.floor(x * factor_x)
w = src_z - src_z_int
u = src_y - src_y_int
v = src_x - src_x_int
# 判断是否查出边界
if src_x_int + 1 == dimX or src_y_int + 1 == dimY or src_z_int + 1 == dimZ:
dst_img[z, y , x] = src_img[src_z_int, src_y_int, src_x_int]
else:
C000 = src_img[src_z_int, src_y_int, src_x_int]
C001 = src_img[src_z_int, src_y_int, src_x_int + 1]
C011 = src_img[src_z_int, src_y_int + 1, src_x_int + 1]
C010 = src_img[src_z_int, src_y_int + 1, src_x_int]
C100 = src_img[src_z_int + 1, src_y_int, src_x_int]
C101 = src_img[src_z_int + 1, src_y_int, src_x_int + 1]
C111 = src_img[src_z_int + 1, src_y_int + 1, src_x_int + 1]
C110 = src_img[src_z_int + 1, src_y_int + 1, src_x_int]
dst_img[z ,y ,x] = C000 * (1 - v)* (1 - u) * (1 - w) + \
C100 * v * (1 - u) * (1 - w) + \
C010 * (1- v) * u * (1 - w) + \
C001 * (1 - v) * (1 - u) * w + \
C101 * v * (1 - u) * w + \
C011 * (1 - v) * u * w + \
C110 * v * u * (1 - w) + \
C111 * v * u * w
return dst_img
完整代码请查看https://download.csdn.net/download/weixin_42795611/13766968