类似于iphone相册的水平矫正
双线性插值
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
def BiLinear_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
print(img)
img=np.pad(img,((0,1),(0,1),(0,0)),'constant')
print(img)
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH):
for j in range(dstW):
scrx=(i+1)*(scrH/dstH)-1
scry=(j+1)*(scrW/dstW)-1
x=math.floor(scrx)
y=math.floor(scry)
u=scrx-x
v=scry-y
retimg[i,j]=(1-u)*(1-v)*img[x,y]+u*(1-v)*img[x+1,y]+(1-u)*v*img[x,y+1]+u*v*img[x+1,y+1]
return retimg
im_path='1.jpg'
image=np.array(Image.open(im_path))
#image2=BiLinear_interpolation(image,1,300) 调整图像大小
image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')
image2.save('out.png')
利用双线性插值进行形变
本想resize本质是插值方法,应该效率高一些,但是没有好好梳理代码,做了很多重复的插值(一张图像所有像素列都进行了插值,可我只需要其中第 i 列),以后有时间再去调整吧。效率太慢,弃用!
from tkinter import N, W, Y
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
#双线性插值
def BiLinear_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
# img[1],代表第一行 存在第0行
# img[x,y],x代表行。y代表列
img=np.pad(img,((0,1),(0,1),(0,0)),'constant') # 最后一行,最后一列填充
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
#for k in range(img.shape[0]):
for i in range(dstH):
for j in range(dstW):
scrx=(i+1)*(scrH/dstH)-1
scry=(j+1)*(scrW/dstW)-1
x=math.floor(scrx)
y=math.floor(scry)
u=scrx-x
v=scry-y
retimg[i,j]=(1-u)*(1-v)*img[x,y]+u*(1-v)*img[x+1,y]+(1-u)*v*img[x,y+1]+u*v*img[x+1,y+1]
return retimg
#构成梯形缩放
def Ladder_shaped(image,y):
H=image.shape[0]
WW=image.shape[1]
# print(H)
# print(W)
P=np.zeros((y,WW,3,),dtype=np.uint8)
# print(P)
for x in range(WW):
h=(x*(y-H)/WW)+H
# print(h)
# print(int(h))
image2=BiLinear_interpolation(image,int(h),WW)
for k in range(int(h)):
P[k,x]=image2[k,x]
print(x)
print(k)
# print(image2[x,k])
# print(P)
return P
im_path='2.jpg'
image=np.array(Image.open(im_path))
#image2=BiLinear_interpolation(image,1,300)
# image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2)
# image2=Image.fromarray(image2.astype('uint8')).convert('RGB')
# image2.save('out.png')
image3=Ladder_shaped(image,4000)
image3=Image.fromarray(image3.astype('uint8')).convert('RGB')
image3.save('test.png')
最后还是用resize吧
from tkinter import N, W, Y
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
#构成梯形缩放
def Ladder_shaped(img,image,y):
H=image.shape[0]
WW=image.shape[1]
# print(H)
# print(W)
P=np.zeros((y,WW,3,),dtype=np.uint8)
# print(P)
for x in range(WW):
h=(x*(y-H)/WW)+H
# print(h)WW
# print(int(h))
image2 = img.resize((WW, int(h)),Image.ANTIALIAS)
image2 = np.array(image2)
for k in range(int(h)):
P[k,x]=image2[k,x]
print(x)
print(k)
# print(image2[x,k])
# print(P)
return P
im_path='3.jpg'
img=Image.open(im_path)
image=np.array(Image.open(im_path))
image3=Ladder_shaped(img,image,2000)
image3=Image.fromarray(image3.astype('uint8')).convert('RGB')
image3.save('testresize7.png')