Python实现双线性插值超分辨
Python实现最近邻插值超分辨
Pytohn实现双三次插值超分辨
import numpy as np
import math
import cv2
def double_linear(input_signal, zoom_multiples):
'''
双线性插值
:param input_signal: 输入图像
:param zoom_multiples: 放大倍数
:return: 双线性插值后的图像
'''
input_signal_cp = np.copy(input_signal) # 输入图像的副本
input_row, input_col = input_signal_cp.shape # 输入图像的尺寸(行、列)
# 输出图像的尺寸
output_row = int(input_row * zoom_multiples)
output_col = int(input_col * zoom_multiples)
output_signal = np.zeros((output_row, output_col)) # 输出图片
for i in range(output_row):
for j in range(output_col):
# 输出图片中坐标 (i,j)对应至输入图片中的最近的四个点点(x1,y1)(x2, y2),(x3, y3),(x4,y4)的均值
temp_x = i / output_row * input_row
temp_y = j / output_col * input_col
x1 = int(temp_x)
y1 = int(temp_y)
x2 = x1
y2 = y1 + 1
x3 = x1 + 1
y3 = y1
x4 = x1 + 1
y4 = y1 + 1
u = temp_x - x1
v = temp_y - y1
# 防止越界
if x4 >= input_row:
x4 = input_row - 1
x2 = x4
x1 = x4 - 1
x3 = x4 - 1
if y4 >= input_col:
y4 = input_col - 1
y3 = y4
y1 = y4 - 1
y2 = y4 - 1
# 插值
output_signal[i, j] = (1-u)*(1-v)*int(input_signal_cp[x1, y1]) + (1-u)*v*int(input_signal_cp[x2, y2]) + u*(1-v)*int(input_signal_cp[x3, y3]) + u*v*int(input_signal_cp[x4, y4])
return output_signal
# Read image
img = cv2.imread("source.jpg",0).astype(np.float)
out = double_linear(img,2).astype(np.uint8)
# Save result
cv2.imshow("result", out)
cv2.imwrite("out.jpg", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
实验结果图
彩色图
不同的方式打开的图片颜色不同,什么问题?
利用 img = Image.open(ImgPath) 打开的图片是PIL类型的,它自带resize函数。由于pytorch的顺序是(batch,c,h,w),所以需要进行PIL类型到numpy类型转换,tensorflow,numpy的顺序是(batch,h,w,c)。
from PIL import Image
import matplotlib.pyplot as plt
import cv2
import numpy as np
import math
def BiLinear_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
img=np.pad(img,((0,1),(0,1),(0,0)),'constant')#np.padding。ndarray = numpy.pad(array, pad_width, mode, **kwargs)
"""
array为要填补的数组
pad_width是在各维度的各个方向上想要填补的长度,如((1,2),(2,2)),表示在第一个维度上水平方向上padding=1,垂直方向上padding=2,
在第二个维度上水平方向上padding=2,垂直方向上padding=2。如果直接输入一个整数,则说明各个维度和各个方向所填补的长度都一样。
mode为填补类型,即怎样去填补,有“constant”,“edge”等模式,如果为constant模式,就得指定填补的值,如果不指定,则默认填充0。
"""
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)#Math.floor() 返回小于或等于一个给定数字的最大整数。
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='source2.jpg'
image=np.array(Image.open(im_path))
"""
利用 img = Image.open(ImgPath) 打开的图片是PIL类型的,它自带resize函数。
由于pytorch的顺序是(batch,c,h,w),所以需要进行PIL类型到numpy类型转换,tensorflow,numpy的顺序是(batch,h,w,c)
"""
# img = cv2.imread("source2.jpg",1)
# cv2.imshow("img",img)
cv2.imshow("image",image)
cv2.waitKey(0)
image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2)#参数1表示读入图像,参数2和参数3表示放大倍数是2倍
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')#转换为RGB图像。
# cv2.imshow("image2",image2)
# cv2.waitKey(0)
image2.save('out2.png')
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
# 最近邻插值算法
# dstH为新图的高;dstW为新图的宽
def NN_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH-1):
for j in range(dstW-1):
scrx=round(i*(scrH/dstH))#round就是四舍五入取整数
scry=round(j*(scrW/dstW))
retimg[i,j]=img[scrx,scry]
return retimg
im_path='source2.jpg'
image=np.array(Image.open(im_path))
image1=NN_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image1=Image.fromarray(image1.astype('uint8')).convert('RGB')
image1.save('NearInt.png')
可以看到最终的结果中含有锯齿状的边缘