【OpenCV 】插值的方法原理,图片缩放,矫正,边界填充

de-feedback 2024-09-14 16:31:00 阅读 86

图像旋转 缩放

计算机中的图像是以数组的方式储存,每个位置储存了像素点的像素值。对图像进行旋转缩放,就是对数组进行操作,乘以对应的矩阵,进行空间变换,而矩阵的行列式的值,就是缩放的倍数。

进行缩放旋转操作时,会产生像素点的变化,空间和数量的变化,所以需要对变化的图片进行插值

插值是通过变化后图像的像素点的坐标,通过缩放倍数,找到原图对应的像素点坐标,通过权重得到新的像素值

其中目标像素点与原图像的像素点的对应公式如下所示:

s

r

c

X

=

d

s

t

X

s

r

c

W

i

d

t

h

d

s

t

W

i

d

t

h

s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}}

srcX=dstX∗dstWidthsrcWidth​

s

r

c

Y

=

d

s

t

Y

s

r

c

H

e

i

g

h

t

d

s

t

H

e

i

g

h

t

s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}}

srcY=dstY∗dstHeightsrcHeight​

src是原图,dst是变换后的图像,通过缩放倍数,得到对应原图的x和y的坐标,是个小数。

最近零插值INTER_NEAREST

通过对得到的坐标向下取整,直接获得原图对应位置的像素值

双线性插值INTER_LINEAR

根据得到的小数坐标重新取像素值,权重取决于和周围点的距离,越近权重越高

小数的坐标对应原图周围四个像素点,对两个方向分别根据距离加权求和,之后再对的到的两个值进行加权求和

把p分为到两个点R1 R2 分别通过Q12Q22 和 Q11Q21根据距离获得像素值,再根据距离由R1R2得到p的像素值

在这里插入图片描述

在这里插入图片描述

f

(

R

1

)

x

2

x

x

2

x

1

f

(

Q

11

)

+

x

x

1

x

2

x

1

f

(

Q

21

)

f(R_{1})\approx\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{11})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{21})

f(R1​)≈x2​−x1​x2​−x​f(Q11​)+x2​−x1​x−x1​​f(Q21​)

f

(

R

2

)

x

2

x

x

2

x

1

f

(

Q

12

)

+

x

x

1

x

2

x

1

f

(

Q

22

)

f(R_{2})\approx\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{12})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{22})

f(R2​)≈x2​−x1​x2​−x​f(Q12​)+x2​−x1​x−x1​​f(Q22​)

f

(

P

)

y

2

y

y

2

y

1

f

(

R

1

)

+

y

y

1

y

2

y

1

f

(

R

2

)

f(P)\approx{\frac{y_{2}-y}{y_{2}-y_{1}}}f(R_{1})+{\frac{y-y_{1}}{y_{2}-y_{1}}}f(R_{2})

f(P)≈y2​−y1​y2​−y​f(R1​)+y2​−y1​y−y1​​f(R2​)

v

像素区域插值INTER_AREA

缩小图像,变成均值滤波放大图像

整数倍是最近邻插值否则就是双线性插值

双三次插值INTER_CUBIC

使用原图中的16像素点进行加权求像素值

像素点的权重通过公式分别求出水平方向和垂直方向的权重,再相乘

BiCubic函数

在这里插入图片描述

a为-0.5或-0.75

Lanczos插值INTER_LANCZOS4

和双三次插值相似,但是使用了64个像素点

使用新的权重公式

在这里插入图片描述

a = 2是适用于缩小,a=3适用放大

<code>import cv2

import numpy

nut = cv2.imread('./media/nut.png')

w = nut.shape[0]

h = nut.shape[1]

mat = cv2.getRotationMatrix2D((0,0),0,2)

nut1 = cv2.warpAffine(nut,mat,(h*2,w*2),flags=cv2.INTER_LINEAR)

nut2 = cv2.warpAffine(nut,mat,(h*2,w*2),flags=cv2.INTER_CUBIC)

nut3 = cv2.warpAffine(nut,mat,(h*2,w*2),flags=cv2.INTER_LANCZOS4)

nut4 = cv2.warpAffine(nut,mat,(h*2,w*2),flags=cv2.INTER_NEAREST)

cv2.imshow('nut1',nut1)

cv2.imshow('nut2',nut2)

cv2.imshow('nut3',nut3)

cv2.imshow('nut4',nut4)

cv2.imshow('nut',nut)

cv2.waitKey(0)

在这里插入图片描述

边界填充

<code>import cv2

import numpy as np

# 边界复制 BORDER_REPLICATE 把边界的像素值作为边缘的填充

# 边界反射 BORDER_REFLECT 以边界为对称线反转过去作为边缘填充

# 边界反射101 BORDER_REFLECT_101 边界放射不同之处在于 不把边界作为对称的部分

# 边界常数 BORDER_CONSTANT 指定常数 以常数填充

# 边界包裹 BORDER_WRAP 平铺

img = cv2.imread('./media/nut.png')

shape = img.shape

m = cv2.getRotationMatrix2D((shape[0]//2,shape[1]//2),45,0.25)

img2 = cv2.warpAffine(img,m,(shape[1],shape[0]),flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_REPLICATE)

img3 = cv2.warpAffine(img,m,(shape[1],shape[0]),cv2.INTER_AREA,borderMode=cv2.BORDER_REFLECT)

img4 = cv2.warpAffine(img,m,(shape[1],shape[0]),cv2.INTER_CUBIC,borderMode=cv2.BORDER_REFLECT_101)

img5 = cv2.warpAffine(img,m,(shape[1],shape[0]),cv2.INTER_LANCZOS4,borderMode=cv2.BORDER_CONSTANT,borderValue=127)

img6 = cv2.warpAffine(img,m,(shape[1],shape[0]),cv2.INTER_LANCZOS4,borderMode=cv2.BORDER_WRAP)

cv2.imshow('img',img)

cv2.imshow('img2',img2)

cv2.imshow('img3',img3)

cv2.imshow('img4',img4)

cv2.imshow('img5',img5)

cv2.imshow('img6',img6)

cv2.waitKey(0)

在这里插入图片描述

图片翻转

<code>import cv2

import numpy as np

img = cv2.imread('./media/nut.png')

img1 = img[::-1] # 垂直翻转

img2 = cv2.flip(img,0) # 0 垂直翻转

img3 = cv2.flip(img,1) # 大于0 水平翻转

img4 = cv2.flip(img,-1) # 小于0 水平垂直翻转

cv2.imshow('img',img)

cv2.imshow('img1',img1)

cv2.imshow('img2',img2)

cv2.imshow('img3',img3)

cv2.imshow('img4',img4)

cv2.waitKey(0)

在这里插入图片描述

图片缩放

<code>import cv2

import numpy as np

img1 = cv2.imread('./media/shapan.jpg')

img2 = cv2.resize(img1,dsize=None,fx=0.25,fy=0.25,interpolation=cv2.INTER_LINEAR)

# x方向缩放 y方向缩放 插值方式

cv2.imshow('img1',img1)

cv2.imshow('img2',img2)

# cv2.imwrite('./media/shapan.jpg',img2)

cv2.waitKey(0)

图片矫正

import cv2

import numpy as np

img = cv2.imread('./media/liner_road.png')

w,h,_ = img.shape

potion = [

[415,50],

[506,50],

[60,560],

[872,560]

]

new_p = np.float32([

[0,0],

[h,0],

[0,w],

[h,w]

])

p = np.float32(potion)

# cv2.line(img,p[0].astype(np.int64).tolist(),p[1].astype(np.int64).tolist(),(0,0,255),2,cv2.LINE_AA)

# cv2.line(img,p[1].astype(np.int64).tolist(),p[3].astype(np.int64).tolist(),(0,0,255),2,cv2.LINE_AA)

# cv2.line(img,p[3].astype(np.int64).tolist(),p[2].astype(np.int64).tolist(),(0,0,255),2,cv2.LINE_AA)

# cv2.line(img,p[2].astype(np.int64).tolist(),p[0].astype(np.int64).tolist(),(0,0,255),2,cv2.LINE_AA)

mat = cv2.getPerspectiveTransform(p,new_p)

img2 = cv2.warpPerspective(img,mat,(h,w))

cv2.imshow('img',img)

cv2.imshow('img2',img2)

cv2.waitKey(0)

在这里插入图片描述

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。