环境
jupyter notebook、python3.8、vscode、win11
基础知识
常见图形缩放方法
空间域缩放方法
- 最近邻插值法
- 双线性插值法
- 立方插值法
常见空间域缩放方法的比较:
方法 | 优点 | 缺点 |
---|---|---|
最近邻插值 | 简单快速 | 容易产生锯齿 |
双线性插值 | 平滑图像 | 可能导致细节模糊 |
立方插值 | 效果更好 | 计算量较大 |
频域方法
- 傅里叶插值
- Lanczos 插值
这里只讲最近邻和双线性
公式
最近邻
双线性
代码
最近邻
'''
方法1:最近邻方法
参数:img图像,scale扩大比例
坐标轴上各点 xi-1,xi,xi+1 ... 两两对半等分间隔,
从而非边界的各坐标点都有一个等宽的邻域,
并根据每个坐标点的值构成一个类似分段函数的函数约束,
从而使各插值坐标点的值等同于所在邻域原坐标点的值。
例如,插值点 x 坐落于 坐标点 xi 的邻域,那么其值 f(x) = f(xi)
'''
def my_resize_nearest(img,scale):
height,width,_=img.shape # 获取图像的高和宽
new_height,new_width=int(height*scale),int(width*scale) # 按扩大比例增大高和宽
new_img=np.zeros((new_height,new_width,3),np.uint8) # 以新的高和宽创建RGB(3)的全零数组,uint8最大值是255
# 3表示图像有3个通道(RGB),np.uint8是指定数组的数据类型为无符号8位整数。
for i in range(new_height):
for j in range(new_width):
# 遍历放大后每个像素位置
x=int(i/scale)
y=int(j/scale)
new_img[i,j]=img[x,y]
return new_img # 返回扩大后的图像
双线性
'''
方法2:双线性插值法
参数:img图像,scale扩大比例
由推导得,双线性插值的结果为:
f(x,y) = f(x0,y0)*[(y1-y )(x1-x )] / [(y1-y0)(x1-x0)] +
f(x1,y0)*[(y1-y )(x1-x0)] / [(y1-y0)(x1-x0)] +
f(x0,y1)*[(y1-y0)(x1-x )] / [(y1-y0)(x1-x0)] +
[(y -y0)(x -x0)] / [(y1-y0)(x1-x0)]
'''
def my_resize_bilinear(img,scale):
height,width,_=img.shape # 获取图像的高和宽
new_height,new_width=int(height*scale),int(width*scale) # 按扩大比例增大高和宽
new_img=np.zeros((new_height,new_width,3),np.uint8) # 以新的高和宽创建RGB(3)的全零数组,uint8最大值是255
# 3表示图像有3个通道(RGB),np.uint8是指定数组的数据类型为无符号8位整数。
for i in range(new_height):
for j in range(new_width):
# 遍历放大后每个像素位置
# 除以scale,计算当前像素位置在原始图像中的位置(以浮点数表示)
x=i/scale
y=j/scale
# 将x和y向下取整,得到原始图像中与当前位置最近的左上角像素位置。
x0=int(x) # x0=x向下取整
y0=int(y)
# 计算原始图像中与当前位置最近的右下角像素位置。
# min函数确保不越界。
x1=min(x0+1,height-1)
y1=min(y0+1,width-1)
# 计算当前像素相对于左上角像素位置的偏移量。
dx=x-x0 # 1-dx = 1 - x + x0 = x1 - x
dy=y-y0 # 1-dy = 1 - y + y0 = y1 - y
# 使用双线性插值计算当前像素灰度值。
new_img[i,j]=img[x0,y0]*(1-dx)*(1-dy)+img[x1,y0]*dx*(1-dy)+img[x0,y1]*(1-dx)*dy
return new_img # 返回新图像