【CV学习笔记】图像预处理warpaffine

1、前言

在学习图像预处理的时候发现,之前用的图像预处理方法一般为 resize和letter box,这两种方法比较低效,后来在手写AI中接触到了warpaffine,只需要一步就能够对图像进行预处理,同时还能很方便的进行cuda加速,于是便记录下来。

欢迎正在学习或者想学的CV的同学进群一起讨论与学习,v:Rex1586662742,q群:468713665

2、学习内容

2.1、旋转变换

在图像处理过程中,图像主要有平移、缩放、旋转、放射、透视等变换,所有矩阵皆可用矩阵进行表示。首先通过下图来推导变换矩阵。

在这里插入图片描述

其中opencv中图像原点在左上方,点 p 绕原点O旋转角度 β \beta βp’ ,同时顺时针旋转变换之后的的角度为

$ \alpha - \beta$ ,同时由图中的三角函数关系可以得到如下公式:

x ′ = c o s ( α − β ) × m x' = cos(\alpha-\beta)×m x=cos(αβ)×m

y ′ = s i n ( α − β ) × m y' = sin(\alpha-\beta)×m y=sin(αβ)×m

m = x / cos ⁡ α = y / s i n β m = x/\cos\alpha = y/sin\beta m=x/cosα=y/sinβ

$cos(\alpha-\beta) = cos\alpha cos\beta + sin\alpha sin\beta $

s i n ( α − β ) = s i n α c o s β − c o s α s i n β sin(\alpha-\beta) = sin\alpha cos\beta - cos\alpha sin\beta sin(αβ)=sinαcosβcosαsinβ

化简以后得到:

在这里插入图片描述

2.2、缩放变换

缩放变换实际上就是在x,y的基础上乘以一个倍数scale

在这里插入图片描述

2.3、平移变换

平移变换实际上就是在x,y的基础上减去一个偏移量dx,dy

在这里插入图片描述

2.4、齐次坐标

为了便于矩阵计算,利用齐次坐标来表示点的变换,其中平移变换矩阵可表示为:

在这里插入图片描述

2.5、缩放+旋转+平移变换

三种变换可以写在一个矩阵当中,可以一次计算到位

在这里插入图片描述

对于图像的预处理,通常需要对图片进行不失真的缩放,用变换矩阵可表示为

在这里插入图片描述

先通过缩放,再移动到目标图的中间位置如果图像的H>W,则需要进行如下缩放

在这里插入图片描述

反之

在这里插入图片描述

以其中的一张图片为例,先将原图等比缩放到与目标图宽度一致

在这里插入图片描述

现在定义目标图的左上角在opencv坐标系的原点,现在需要原图移动到目标位置可以分为两个步骤,将原图的中心点移动到坐标系原点,对应于公式中的 -scale×Ow/2,-scale×Oh/2

在这里插入图片描述

再将图片移动到目标图的中心位置,对应于公式中的 + Dw/2, + Dh/2.

在这里插入图片描述

其过程可表示为 p ′ = M p p' =Mp p=Mp

2.6、逆变换

当图片进行仿射变换后需要恢复到原图或者模型推理得到结果之后需要恢复到原图尺寸时,可以利用逆变换能很方便的得到。

旋转矩阵R是正交的,得到R-1 = RT 于是求逆变换只需要对变换矩阵求逆即可,当然可以通过计算的方法得到

k = s c a l e k = scale k=scale

b 1 = − s c a l e × O w / 2 + D w / 2 b1 = -scale×Ow/2 + Dw/2 b1=scale×Ow/2+Dw/2

b 2 = − s c a l e × O h / 2 + D h / 2 b2 = -scale×Oh/2 + Dh/2 b2=scale×Oh/2+Dh/2

x ′ = k x + b 1 x' = kx + b1 x=kx+b1

y ′ = k y + b 2 y'= ky + b2 y=ky+b2

x = ( x ′ − b 1 ) / k = x ′ / k + ( − b 1 ) / k x = (x'-b1)/k = x'/k + (-b1)/k x=(xb1)/k=x/k+(b1)/k

y = ( y ′ − b 2 ) / k = y ′ / k + ( − b 2 ) / k y = (y'-b2)/k = y'/k + (-b2)/k y=(yb2)/k=y/k+(b2)/k

由此可以的到逆变换矩阵M-1

在这里插入图片描述

3、效果测试

import cv2
import matplotlib.pyplot as plt

def inv_mat(M):
    k = M[0,0],
    b1 = M[0,2]
    b2 = M[1,2],
    return np.array([[1/k,0,-b1/k],
                    [0,1/k,-b2/k]])

def transform(image,dst_size):
    oh,ow = image.shape[:2]
    dh,dw = dst_size
    scale = min(dw/ow,dh/oh)
    
    M = np.array([
        [scale,0,-scale * ow * 0.5 + dw * 0.5],
        [0,scale,-scale * oh * 0.5 + dh * 0.5]
    ])
    return cv2.warpAffine(image,M,dst_size),M,inv_mat(M)

img = cv2.imread("/home/rex/Desktop/rex_extra/notebook/warpaffine/keji2.jpeg")
img_d,M,inv= transform(img,(640,640))
plt.subplot(1,2,1)
plt.title("WarpAffine")
plt.imshow(img_d[...,::-1])

img_s = cv2.warpAffine(img_d,inv,img.shape[:2][::-1])
plt.subplot(1,2,2)
plt.title("or")
plt.imshow(img_s[...,::-1])

在这里插入图片描述

4、总结

本次学习内容介绍了高效的图像预处理方式,接下来将会对warpaffine进行cuda加速,进一步提高预处理的速度

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rex久居

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值