task01 Opencv框架与图像插值算法

本文深入探讨了图像处理中的三种关键插值算法——最近邻插值、双线性插值和三次样条插值,重点讲解了它们在OpenCV框架下的应用。通过实例演示,展示了如何使用cv2.resize()函数调整图像大小,并比较了不同插值方法的效果。
摘要由CSDN通过智能技术生成

1.1简介

  在图像处理中,平移变换、旋转变换、缩放变换是一些常用操作。这些几何变换几乎不改变图像的像素值,只是在图像平面上进行像素的重新排列。

在一副输入图像[u,v]中,灰度值仅在整数位置上有定义。

然而,在输出图像[x,y]的灰度值一般由处在非整数坐标上的(u,v)值来决定

这就需要插值算法进行处理,常见的插值算法有近邻插值双线性插值三次样条插值

1.2学习目标

  • 了解插值算法与常见几何变换之间的关系
  • 理解插值算法的原理
  • 掌握OpenCV框架下的插值算法API的使用

1.3内容介绍

1、插值算法原理介绍

  • 最近邻插值算法
  • 双线性插值算法

2、OpenCV代码实践

  • cv.resize()各项参数及含义

3、动手实现

1.4 算法理论介绍

1.4.1最近邻插值

最近邻插值,是指将目标图像中的店,对应到源图像中后,找到最相邻的整数点,作为插值后的输出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1c5iKvJm-1587567253422)(img/1.png)]

如上图所示,目标图像中的某点投影到原图像中的位置为点P, f ( P ) = f ( Q 11 ) f(P) = f(Q_{11}) f(P)=f(Q11)

例子:

如下图所示,将一幅3x3的图像放大到4x4,用 f ( x , y ) f(x,y) f(x,y)表示目标图像,有以下公式

f ( d s t X , d s t Y ) = h ( d s t X s r c W i d t h d s t W i d t h , d s t Y s r c H e i g h t d s t H e i g h t ) \begin{array}{c} f(dst{X}, dst{Y}) = h(\frac{dst{X}src{Width}} {dst{Width}}, \frac{dst{Y}src{Height}} {dst{Height}}) \end{array} f(dstX,dstY)=h(dstWidthdstXsrcWidth,dstHeightdstYsrcHeight)

f ( 0 , 0 ) = h ( 0 , 0 )   f ( 0 , 1 ) = h ( 0 , 0.75 ) = h ( 0 , 1 )   f ( 0 , 2 ) = h ( 0 , 1.50 ) = h ( 0 , 2 )   f ( 0 , 3 ) = h ( 0 , 2.25 ) = h ( 0 , 2 )   . . .   \begin{array}{c} f(0,0)=h(0,0) \ f(0,1)=h(0,0.75)=h(0,1) \ f(0,2)=h(0,1.50)=h(0,2) \ f(0,3)=h(0,2.25)=h(0,2) \ ...\ \end{array} f(0,0)=h(0,0) f(0,1)=h(0,0.75)=h(0,1) f(0,2)=h(0,1.50)=h(0,2) f(0,3)=h(0,2.25)=h(0,2) ... 

缺点

该方法在放大处理时,在图像中会出现明显的块状效应

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-83DnbQBY-1587567253432)(img/2.png)]

1.4.2 双线性插值

线性插值多项式:

f ( x ) = a 1 x + a 0 f(x)=a{1} x+a{0} f(x)=a1x+a0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HBsvl64X-1587567253434)(img/3.png)]

y = y 0 + ( x − x 0 ) y 1 − y 0 x 1 − x 0 = y 0 + ( x − x 0 ) y 1 − ( x − x 0 ) y 0 x 1 − x 0 y=y{0}+\left(x-x{0}\right) \frac{y{1}-y{0}}{x{1}-x{0}}=y{0}+\frac{\left(x-x{0}\right) y_{1}-\left(x-x{0}\right) y{0}}{x{1}-x{0}} y=y0+(xx0)x1x0y1y0=y0+x1x0(xx0)y1(xx0)y0

双线性插值就是线性插值在二维时的推广,在两个方向上做三次线性插值,具体操作如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqsgw19H-1587567253436)(img/4.png)]

f ( x , y ) f(x,y) f(xy)为两个变量的函数,其在单位正方形顶点的值已知。假设我们希望通过插值得到正方形内任意点的函数值。则可由双线性方程: f ( x , y ) = a x + b y + c x y + d f(x, y)=a x+b y+c x y+d f(x,y)=ax+by+cxy+d

来定义的一个双曲抛物面与四个已知点拟合。

首先对上端的两个顶点进行线性插值得:

f ( x , 0 ) = f ( 0 , 0 ) + x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] f(x, 0)=f(0,0)+x[f(1,0)-f(0,0)] f(x,0)=f(0,0)+x[f(1,0)f(0,0)]

类似地,再对底端的两个顶点进行线性插值有: f ( x , 1 ) = f ( 0 , 1 ) + x [ f ( 1 , 1 ) − f ( 0 , 1 ) ] f(x, 1)=f(0,1)+x[f(1,1)-f(0,1)] f(x,1)=f(0,1)+x[f(1,1)f(0,1)]

最后,做垂直方向的线性插值,以确定:

f ( x , y ) = f ( x , 0 ) + y [ f ( x , 1 ) − f ( x , 0 ) ] f(x, y)=f(x, 0)+y[f(x, 1)-f(x, 0)] f(x,y)=f(x,0)+y[f(x,1)f(x,0)]

整理得:

f ( x , y ) = [ f ( 1 , 0 ) − f ( 0 , 0 ) ] x + [ f ( 0 , 1 ) − f ( 0 , 0 ) ] y   + [ f ( 1 , 1 ) + f ( 0 , 0 ) − f ( 0 , 1 ) − f ( 1 , 0 ) ] x y + f ( 0 , 0 ) \begin{array}{l} f(x, y)=[f(1,0)-f(0,0)] x+[f(0,1)-f(0,0)] y \ +[f(1,1)+f(0,0)-f(0,1)-f(1,0)] x y+f(0,0) \end{array} f(x,y)=[f(1,0)f(0,0)]x+[f(0,1)f(0,0)]y +[f(1,1)+f(0,0)f(0,1)f(1,0)]xy+f(0,0)

1.4.3 映射方法

向前映射法

可以将几何运算想象成一次一个象素地转移到输出图象中。如果一个输入象素被映射到四个输出象素之间的位置,则其灰度值就按插值算法在4个输出象素之间进行分配。称为向前映射法,或象素移交影射。

注:从原图象坐标计算出目标图象坐标镜像、平移变换使用这种计算方法

向后映射法

向后映射法(或象素填充算法)是输出象素一次一个地映射回到输入象素中,以便确定其灰度级。如果一个输出象素被映射到4个输入象素之间,则其灰度值插值决定,向后空间变换是向前变换的逆。

注:从结果图象的坐标计算原图象的坐标

旋转、拉伸、放缩可以使用
解决了漏点的问题,出现了马赛克

python实践

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

函数原型:

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

参数:

参数描述
src【必需】原图像
dsize【必需】输出图像所需大小
fx【可选】沿水平轴的比例因子
fy【可选】沿垂直轴的比例因子
interpolation【可选】插值方式

插值方式:

cv.INTER_NEAREST最近邻插值
cv.INTER_LINEAR双线性插值
cv.INTER_CUBIC基于4x4像素邻域的3次插值法
cv.INTER_AREA基于局部像素的重采样

通常,缩小使用cv.INTER_AREA,放缩使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,所有的放缩都使用cv.INTER_LINEAR。

代码实践:


import cv2

img = cv2.imread('img/meizi.jpeg')
print('Original Dimensions : ',img.shape)

scale_percent = 30       # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
# resize image
resized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)

fx = 1.5
fy = 1.5

resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_NEAREST)

resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_LINEAR)
print('Resized Dimensions : ',resized.shape)

cv2.imshow("Resized image", resized)
cv2.imshow("INTER_NEAREST image", resized1)
cv2.imshow("INTER_LINEAR image", resized2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Original Dimensions :  (1200, 801, 3)
Resized Dimensions :  (360, 240, 3)

原图像:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MLhPQmUs-1587567253438)(img/meizi.jpeg)]

缩小[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OnroI9dL-1587567253440)(img/5.png)]

近邻插值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PhdBNgvY-1587567253440)(img/7.png)]

线性插值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i6gqoqu8-1587567253441)(img/6.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值