因为插值算法中涉及权重概念,这里顺便对权重进行简要精炼的总结,权重中的权其实就是概率就是占比,权重的目的其实就是得到一个平均值,没啥好神秘的
五种插值算法,目的是用于图像扩大时超分辨率,缩小不失真,常用于放大图片
一、最近邻插值
这种方法失真严重但运算简单,缩小图片可考虑
cv2.resize(img, (0, 0), fx=倍数, fy=倍数, interpolation=cv2.INTER_NEAREST)
二、双线性插值
这种方法最常用, 是resize默认值,首先和最邻近插值算法一样,先获取源图坐标,这个坐标是个小数,最近邻插值算法直接四舍五入,从而得到映射的灰度,而双线性插值不是直接四舍五入,而是根据这个点四周的四个点依据各自的权重得出该点的灰度,计算公式
x0 = x1/scale y0 = y1/scale x = int(x0) y = int(y0) u = x0-x v = y0-y
f(y1,x1) = (1-v)(1-u)f(y,x)+(1-v)uf(y,x+1)+v(1-u)f(y+1,x)+uvf(y+1,x+1)
因为该灰度跟邻近四点有关,所以不会像最近邻插值一样出现锯齿状,所以普遍应用于图像插值.
cv2.resize(img, (0, 0), fx=倍数, fy=倍数, interpolation=cv2.INTER_LINEAR)
三、使用像素关系区域进行重采样
待续
cv2.resize(img, (0, 0), fx=倍数, fy=倍数, interpolation=cv2.INTER_AREA)
四、双三次插值
待续
cv2.resize(img, (0, 0), fx=倍数, fy=倍数, interpolation=cv2.INTER_CUBIC)
五、Lanczos插值
待续
cv2.resize(img, (0, 0), fx=倍数, fy=倍数, interpolation=cv2.INTER_LANCZOS4)
首先完成第一个最近邻插值,这里只针对放大进行说明:关键点——放大图片的像素点是在原图片中进行映射得到,映射公式x0 = x1/倍数,y0 = y1/倍数,先根据放大图片的坐标算出原图片坐标,从而放大图片像素等于原图片该点像素。代码实现如下:
import numpy as np
import cv2
path = 'test.jpg'
image = cv2.imread('test.jpg',0)
def near(image,scale):
hight,width = image.shape
img = np.zeros((hight*scale,width*scale))
for i in range(img.shape[0]-4):
for j in range(img.shape[1]-4):
x = round(i/scale)
y = round(j/scale)
img[i,j] = image[x,y]
return img
img = near(image,4)
cv2.imshow('test',img.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyWindow()
双线性图像插值算法代码如下:
def double_insert(image,scale):
hight,width = image.shape
h = hight*scale
w = width*scale
img = np.zeros((h,w))
for i in range(h-4):
for j in range(w-4):
y = int(i/scale)
x = int(j/scale)
img[i,j] = (y+1-i/scale)*(x+1-j/scale)*image[y,x]+(y+1-i/scale)*(j/scale-x)*image[y,x+1]+(i/scale-y)*(x+1-j/scale)*image[y+1,x]+(i/scale-y)*(j/scale-x)*image[y+1,x+1]
return img