双线性领域插值法

在图像领域,有许多用于处理图像数据的经典算法,比如图像去噪,图像修复,图像灰度化,直方图,梯度图等等,这些算法为深度学习中模型训练起到了不可或缺的作用。

今天我想介绍图像缩放的经典算法之双线性插值法,在之前的博文中,我也写过一篇图像缩放最近邻域插值法。具体链接如下:

最近领域插值法:https://blog.csdn.net/weixin_44402973/article/details/87903984

这些算法,我在阅读论文过程中,经常会碰到,比如:"bilinear interpolation",英文含义是“双线性插值”的意思。好了下面我来具体介绍一下双线性插值法的算法的流程,最后,我会使用python中的cv2来对该算法进行实现。

双线性插值法的思想

缩放之后新图像的(x,y)的像素值对应于原图像(x',y')的像素周围四个点像素和其对应的权重相乘并相加。

双线性领域插值法

为了形象的介绍这个算法,我们设原图像中一个像素位置为(x',y'),其大小为(height,width,channels),height:表示图像的高度,width:表示图像的宽度,channels:表示图像的通道数。设我们要对图像进行扩大一倍即新图片大小为(Height,Width,Channels),其中Height = height * 2,Width = width * 2,Channels = channels。缩放之后对应新图像的位置(x,y)。那么(x,y)处像素值如何求解,原图像每个位置的像素已知。求解过程:

(1). 原图像和新图像的缩放比例:

fh= (height - 1) / (Height - 1),浮点数

fw = (width - 1) / (Width - 1),浮点数

(2). (x,y)对应原图像位置为:

x' = x * fh,y' = y * fw,此处x',y'为浮点数,计算(x',y')周围的四个像素点坐标为:

x1 = int(x' +1), x2 = x1 + 1, y1 = int(y'+1), y2 = y1 + 1

(3). 求四个点到x',y'的距离:

dx1 = x1 - x'

dx2 = 1.0 - d1

dy1 =  y1 - y'

dy2 = 1 - dy1

(4). 利用所求解距离求解四个点的权重:

fs1 = dx1 * dy1,fs2 = dx1 * dy2,fs3 = dx2 * dy1,fs4 = dx2 * dy2

(5). 求解缩放之后(x,y)对应的像素值:

v(x,y) = int(v'(x1,y1) * fs1 + v'(x1,y2) * fs2 + v'(x2,y1) * fs3 + v'(x2,y2) * fs4),v'(x,y):表示原图像(x,y)处的像素值,v(x,y):表示缩放之后要求解(x,y)位置上的像素值。

具体代码实现:

本代码使用本人的一张照片作为测试样例,其分辨率为:436 x 558

# coding:utf-8
import numpy as np
import cv2

img_arr = cv2.imread("me.png")
height,width = img_arr.shape
dst_height = height * 2
dst_width = width * 2
fh = (height-1) / (dst_height-1)
fw = (width-1) / (dst_width-1)
dst = np.zeros((dst_height,dst_width,3),np.uint8)

# 利用双线性插值法对图像进行缩放
for i in range(dst_height-1):
	for j in range(dst_width-1):
		# 求对应原图像的像素点的位置
		source_x = i * fh
		source_y = j * fw
		# 求出(source_x,source_y)周围四个点的坐标
		x1 = int(source_x)
		x2 = x1 + 1
		y1 = int(source_y)
		y2 = y1 + 1
		# 计算四个点到(source_x,source_y)的距离,来计算权重
		fx1 = source_x - x1
		fx2 = 1.0 - fx1
		fy1 = source_y - y1
		fy2 = 1.0 - fy1
		# 计算(source_x,source_y)周围四个坐标的权重
		fs1 = fx1 * fy1
		fs2 = fx1 * fy2
		fs3 = fx2 * fy1
		fs4 = fx2 * fy2
		new_pixel_b = int(fs1 * img_arr[x1][y1][0] + fs2 * img_arr[x1][y2][0] + fs3 * img_arr[x2][y1][0] + fs4 * img_arr[x2][y2][0])
		new_pixel_g = int(fs1 * img_arr[x1][y1][1] + fs2 * img_arr[x1][y2][1] + fs3 * img_arr[x2][y1][1] + fs4 * img_arr[x2][y2][1])
		new_pixel_r = int(fs1 * img_arr[x1][y1][2] + fs2 * img_arr[x1][y2][2] + fs3 * img_arr[x2][y1][2] + fs4 * img_arr[x2][y2][2])
		dst[i][j][0] = 255 if new_pixel_b > 255 else new_pixel_b
		dst[i][j][1] = 255 if new_pixel_g > 255 else new_pixel_g
		dst[i][j][2] = 255 if new_pixel_r > 255 else new_pixel_r

		dst[i][j][0] = 0 if new_pixel_b < 0 else new_pixel_b
		dst[i][j][1] = 0 if new_pixel_g < 0 else new_pixel_g
		dst[i][j][2] = 0 if new_pixel_r < 0 else new_pixel_r

cv2.imwrite("me_new.png",dst)
cv2.imshow("me_source",img_arr)
cv2.imshow("me_new",dst)
cv2.waitKey(0)

缩放之后图片

好了,双线性插值法介绍完了,希望本博文对你有效。如果本篇文章存在问题,请博客留言!Thanks!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值