推荐参考文章: 几种插值算法对比研究
实验用图:
最邻近插值
取像素点邻域的平均值作为插值,会有马赛克效果,但是好写运算小
import numpy as np
import cv2 as cv
img = cv.imread('sample.jpg', cv.IMREAD_GRAYSCALE)
(len_x, len_y) = img.shape
(H, W) = (700, 700) # 设定画布大小
ans = np.zeros((H, W), dtype=np.uint8)
alpha = 30/180*np.pi
(cos, sin) = (np.cos(alpha), np.sin(alpha))
(adjust_x, adjust_y) = (0, 0)
(move_x, move_y) = (250, -75)
for x in range(0,H-1):
for y in range(0, W-1):
# 计算旋转前坐标
(ori_x, ori_y) = (x*cos+y*sin-move_x, y*cos-x*sin-move_y)
if ori_x < 0 or ori_y < 0 or ori_x >= len_x or ori_y >= len_y:
continue
# 判断位置
dst_x = np.int(ori_x) if ori_x - np.int(ori_x) < 0.5 else np.int(ori_x)+1
dst_y = np.int(ori_y) if ori_y - np.int(ori_y) < 0.5 else np.int(ori_y)+1
# 是否越界
if dst_x >= len_x or dst_y >= len_y:
ans[x,y] = 0
else:
ans[x,y] = img[dst_x,dst_y]
cv.imshow('nearest', ans)
cv.waitKey(0)
cv.destroyAllWindows()
实验结果:
双线性插值
import cv2 as cv
import numpy as np
img = cv.imread('sample.jpg', cv.IMREAD_GRAYSCALE)
(len_x, len_y) = img.shape
(H, W) = (700, 700)
res = np.zeros((H, W), dtype=np.uint8)
alpha = 30/180*np.pi
(cos, sin) = (np.cos(alpha), np.sin(alpha))
(adjust_x, adjust_y) = (0, 0)
(move_x, move_y) = (250, -75)
for x in range(0,H-1):
for y in range(0, W-1):
(ori_x, ori_y) = (x*cos+y*sin-move_x, y*cos-x*sin-move_y)
if ori_x < 0 or ori_y < 0 or ori_x >= len_x or ori_y >= len_y:
continue
(Ox, Oy) = (np.int(ori_x), np.int(ori_y))
Q11 = img.item(Ox, Oy)
Q21 = img.item(Ox, Oy+1) if Oy+1 < len_y else 0
Q12 = img.item(Ox+1, Oy) if Ox+1 < len_x else 0
Q22 = img.item(Ox+1, Oy+1) if Ox+1 < len_x and Oy+1 <len_y else 0
coef = np.array([[Q11, Q12], [Q21, Q22]], dtype=np.float64)
pix = np.array([Ox+1-ori_x,ori_x-Ox]) @ coef @ np.array([[Oy+1-ori_y], [ori_y-Oy]])
res[x, y] = np.uint8(pix[0])
cv.imshow('liner', res)
cv.waitKey(0)
cv.destroyAllWindows()
实验结果: