双三次插值缩放代码:
缩放算法:
import numpy as np
import cv2
def SinXDivX(x):
a=-1
if x<0:
x=-x
if x<=1:
ans = 1-2*x**2+x**3
elif x<=2:
ans = 4-8*x+5*x**2-x**3
else:
ans=0
return ans
def pixel(img,y,x):
if y<0:
y=0
if y>=img.shape[0]:
y=img.shape[0]-1
if x<0:
x=0
if x>=img.shape[1]:
x=img.shape[1]-1
return img[y][x]
def ReColor(color):
if color<0:
return 0
elif color>255:
return 255
return color
def Bicubic(Src,y,x):
y0,x0=int(y),int(x)
fv,fu=y-y0,x-x0
afv,afu=[],[]
for delta in range(-1,3):
afv.append(SinXDivX(delta+fv))
afu.append(SinXDivX(delta+fu))
sz=len(Src[0][0])
arr=[0.]*sz
sRow=np.array(arr)
for i in range(4):
sCol=np.array(arr)
for j in range(4):
sCol+=afu[j]*pixel(Src,i-1+y0,j-1+x0)
sRow+=afv[i]*sCol
for i in range(sz):
sRow[i]=ReColor( int(sRow[i]+0.5) )
return sRow
def solve(Src,Dst):
s_height,s_width,=Src.shape[0],Src.shape[1]
d_height,d_width=Dst.shape[0],Dst.shape[1]
if s_width==0 or s_height==0 or d_width==0 or d_height==0 :
return
for y in range(d_height):
src_y= (y+0.5)/d_height*s_height-0.5
for x in range(d_width):
src_x= (x+0.5)/d_width*s_width-0.5
Dst[y][x]=Bicubic(Src,src_y,src_x)
使用:
img=cv2.imread('pictures\\timg.jpg')
Dst=np.zeros((484,706,3))
solve(img,Dst)
cv2.imwrite('pictures\\timg2.jpg',Dst)
这样的缩放很慢
对于成倍数的放大,可以使用矩阵乘法:
这样使用nump运算特别快。
对于一个 64×64 64 × 64 大小的图片A缩放到 128×128 128 × 128 ,对于每一通道:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪1100⋮000011⋮00⋯⋯⋯⋯⋮⋯⋯0000⋮11⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪×A×⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪10⋮010⋮001⋮001⋮0⋯⋯⋮⋯00⋮100⋮1⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪
{
1
0
⋯
0
1
0
⋯
0
0
1
⋯
0
0
1
⋯
0
⋮
⋮
⋮
⋮
0
0
⋯
1
0
0
⋯
1
}
×
A
×
{
1
1
0
0
⋯
0
0
0
0
1
1
⋯
0
0
⋮
⋮
⋮
⋮
⋮
⋮
⋮
0
0
0
0
⋯
1
1
}
其中左边矩阵 L L 的大小为 ,右边矩阵 R R 的大小为
R=[[0 for i in range(128)]for i in range(64)]
for i in range(64):
R[i][i<<1]=R[i][i<<1|1]=1
L=[[0 for i in range(64)]for i in range(128)]
for i in range(64):
L[i<<1][i]=L[i<<1|1][i]=1