Python图像插值算法详解:最近邻、双线性与双三次法实现
本文详细介绍Python中三种常见的图像插值算法:最近邻、双线性和双三次插值。通过具体代码实例,解析各算法的实现原理、计算过程及适用场景,帮助开发者理解图像缩放时的像素映射机制与视觉效果差异。
Python图像插值算法概述
最近邻插值法:
最近邻插值实现
import cv2
import numpy as np
def function(img):
height,width,channels =img.shape
emptyImage=np.zeros((2048,2048,channels),np.uint8)
sh=2048/height
sw=2048/width
for i in range(2048):
for j in range(2048):
x=int(i/sh)
y=int(j/sw)
emptyImage[i,j]=img[x,y]
return emptyImage
img=cv2.imread("e:\\lena.bmp")
zoom=function(img)
cv2.imshow("nearest neighbor",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)
双线性插值法:
双线性插值实现
import cv2
import numpy as np
import math
def function(img,m,n):
height,width,channels =img.shape
emptyImage=np.zeros((m,n,channels),np.uint8)
value=[0,0,0]
sh=m/height
sw=n/width
for i in range(m):
for j in range(n):
x = i/sh
y = j/sw
p=(i+0.0)/sh-x
q=(j+0.0)/sw-y
x=int(x)-1
y=int(y)-1
for k in range(3):
if x+1<m and y+1<n:
value[k]=int(img[x,y][k]*(1-p)*(1-q)+img[x,y+1][k]*q*(1-p)+img[x+1,y][k]*(1-q)*p+img[x+1,y+1][k]*p*q)
emptyImage[i, j] = (value[0], value[1], value[2])
return emptyImage
img=cv2.imread("e:\\lena.bmp")
zoom=function(img,2048,2048)
cv2.imshow("Bilinear Interpolation",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)
双三次插值法:
双三次插值实现
import cv2
import numpy as np
import math
def S(x):
x = np.abs(x)
if 0 <= x < 1:
return 1 - 2 * x * x + x * x * x
if 1 <= x < 2:
return 4 - 8 * x + 5 * x * x - x * x * x
else:
return 0
def function(img,m,n):
height,width,channels =img.shape
emptyImage=np.zeros((m,n,channels),np.uint8)
sh=m/height
sw=n/width
for i in range(m):
for j in range(n):
x = i/sh
y = j/sw
p=(i+0.0)/sh-x
q=(j+0.0)/sw-y
x=int(x)-2
y=int(y)-2
A = np.array([
[S(1 + p), S(p), S(1 - p), S(2 - p)]
])
if x>=m-3:
m-1
if y>=n-3:
n-1
if x>=1 and x<=(m-3) and y>=1 and y<=(n-3):
B = np.array([
[img[x-1, y-1], img[x-1, y],
img[x-1, y+1],
img[x-1, y+1]],
[img[x, y-1], img[x, y],
img[x, y+1], img[x, y+2]],
[img[x+1, y-1], img[x+1, y],
img[x+1, y+1], img[x+1, y+2]],
[img[x+2, y-1], img[x+2, y],
img[x+2, y+1], img[x+2, y+1]],
])
C = np.array([
[S(1 + q)],
[S(q)],
[S(1 - q)],
[S(2 - q)]
])
blue = np.dot(np.dot(A, B[:, :, 0]), C)[0, 0]
green = np.dot(np.dot(A, B[:, :, 1]), C)[0, 0]
red = np.dot(np.dot(A, B[:, :, 2]), C)[0, 0]
# ajust the value to be in [0,255]
def adjust(value):
if value > 255:
value = 255
elif value < 0:
value = 0
return value
blue = adjust(blue)
green = adjust(green)
red = adjust(red)
emptyImage[i, j] = np.array([blue, green, red], dtype=np.uint8)
return emptyImage
img=cv2.imread("e:\\lena.bmp")
zoom=function(img,1024,1024)
cv2.imshow("cubic",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)
最邻近插值法原理详解
补充知识:最邻近插值法(The nearest interpolation)实现图像缩放
该方法也被称为零阶插值。其核心逻辑是,输出图像中某像素的灰度值直接取自原始图像中距离该映射位置最近的像素点的灰度值。然而,当原始图像包含像素间灰度渐变的细微结构时,这种算法容易在结果图像中产生明显的人工加工痕迹,导致图像边缘出现锯齿。
具体计算步骤如下:假设目标图像的坐标为 M(x,y),通过反向映射法可计算出其在原始图像中对应的浮点坐标 m(i+u,j+v)。其中,i和j为正整数,u和v为大于0且小于1的小数。待求像素的灰度值 f(m) 即由浮点坐标 m 相邻的四个像素点计算得出。
MATLAB最邻近插值示例
function re_im = nearest(im, p, q)
%最邻近插值法,输入目标图像和行缩放、纵缩放倍数
%ziheng 2016.3.27
[m,n] = size(im);
im_R = im(:,:,1);
im_G = im(:,:,2);
im_B = im(:,:,3);
l = round(m*p);
h = round(n*q)/3;
re_R = uint8(zeros(l,h));
re_G = uint8(zeros(l,h));
re_B = uint8(zeros(l,h));
for dstx = 1:l
for dsty = 1:h
srcx = max(1,min(m,round(dstx/p)));
srcy = max(1,min(n/3,round(dsty/q)));
re_R(dstx,dsty) = im_R(srcx,srcy);
re_G(dstx,dsty) = im_G(srcx,srcy);
re_B(dstx,dsty) = im_B(srcx,srcy);
end
end
re_im = cat(3,re_R,re_G,re_B);
figure,imshow(re_im);
以上关于Python图像插值(最近邻、双线性、双三次)的实例分享完毕,希望能为读者提供参考。欢迎大家继续支持本站获取更多技术内容。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













