视觉处理之仿射变换

什么是仿射变换

射变换是一种二维图像变换,可以通过旋转、缩放、平移和倾斜等操作改变图像的几何结构,同时保持图像中平行线的平行性。
主要是要涉及到仿射变换的M矩阵的推导,以及M矩阵的逆推导。

变换

关于点的变换,通常存在缩放、旋转、平移。将以上几种操作用矩阵表示的话可以表示成下以下:

旋转

旋转前后直线长度不变,设直线长度为 l l l,因此变换后有以下公式:
{ y 1 = l s i n ( θ + β ) x 1 = l c o s ( θ + β ) \begin{cases}y1=lsin(\theta+\beta) \\x1=lcos(\theta+\beta) \end{cases} {y1=lsin(θ+β)x1=lcos(θ+β)
通过上式可得到:
{ y 1 = y cos ⁡ β + x sin ⁡ β x 1 = x cos ⁡ β − y sin ⁡ β \begin{cases}y1=y\cos\beta+x\sin\beta \\x1=x\cos\beta-y\sin\beta \end{cases} {y1=ycosβ+xsinβx1=xcosβysinβ
用矩阵表达:
[ x 1 y 1 ] = [ cos ⁡ β − sin ⁡ β sin ⁡ β cos ⁡ β ] [ x y ] \begin{bmatrix}x1 \\y1 \end{bmatrix}=\begin{bmatrix}\cos\beta & -\sin\beta \\\sin\beta & \cos\beta \end{bmatrix} \begin{bmatrix}x \\y \end{bmatrix} [x1y1]=[cosβsinβsinβcosβ][xy]
但是由于opencv中图像的原点在左上角,x轴正方向在下,y轴正方向向右。因此旋转矩阵在图像上时是:
[ x 1 y 1 ] = [ cos ⁡ β sin ⁡ β − s i n β cos ⁡ β ] [ x y ] \begin{bmatrix}x1 \\y1 \end{bmatrix}=\begin{bmatrix}\cos\beta & \sin\beta \\-sin\beta & \cos\beta \end{bmatrix} \begin{bmatrix}x \\y \end{bmatrix} [x1y1]=[cosβsinβsinβcosβ][xy]
在这里插入图片描述

缩放

[ x 1 y 1 ] = [ s c a l e 0 0 s c a l e ] [ x y ] \begin{bmatrix}x1 \\y1 \end{bmatrix}=\begin{bmatrix}scale & 0 \\0 &scale\end{bmatrix} \begin{bmatrix}x \\y \end{bmatrix} [x1y1]=[scale00scale][xy]

旋转+缩放

[ x 1 y 1 ] = [ cos ⁡ β × s c a l e sin ⁡ β × s c a l e − s i n β × s c a l e cos ⁡ β × s c a l e ] [ x y ] \begin{bmatrix}x1 \\y1 \end{bmatrix}=\begin{bmatrix}\cos\beta\times scale & \sin\beta\times scale \\-sin\beta\times scale & \cos\beta\times scale \end{bmatrix} \begin{bmatrix}x \\y \end{bmatrix} [x1y1]=[cosβ×scalesinβ×scalesinβ×scalecosβ×scale][xy]

平移

[ x 1 y 1 ] = [ 1 0 0 1 ] [ x y ] + [ o x o y ] \begin{bmatrix}x1 \\y1 \end{bmatrix}=\begin{bmatrix}1 & 0 \\0 &1\end{bmatrix} \begin{bmatrix}x \\y \end{bmatrix}+ \begin{bmatrix}ox\\oy \end{bmatrix} [x1y1]=[1001][xy]+[oxoy]
由上式可以看出,平移是加法运算,如何合并成一个矩阵,答案是齐次矩阵。平移变换可用齐次坐标表示成以下格式:
[ x 1 y 1 1 ] = [ 1 0 o x 0 1 o y 0 0 1 ] [ x y 1 ] \begin{bmatrix}x1 \\y1\\1 \end{bmatrix}=\begin{bmatrix}1 & 0 &ox \\0 & 1&oy \\0&0&1 \end{bmatrix}\begin{bmatrix}x \\y\\1 \end{bmatrix} x1y11 = 100010oxoy1 xy1

旋转+平移+缩放

[ x 1 y 1 1 ] = [ cos ⁡ β × s c a l e sin ⁡ β × s c a l e o x − sin ⁡ β × s c a l e cos ⁡ θ × s c a l e o y 0 0 1 ] [ x y 1 ] \begin{bmatrix}x1 \\y1\\1 \end{bmatrix}=\begin{bmatrix}\cos\beta\times scale & \sin\beta\times scale &ox \\-\sin\beta\times scale & \cos\theta\times scale&oy \\0&0&1 \end{bmatrix}\begin{bmatrix}x \\y\\1 \end{bmatrix} x1y11 = cosβ×scalesinβ×scale0sinβ×scalecosθ×scale0oxoy1 xy1
对于旋转矩阵而言,其逆矩阵就等于其转置,即 R − 1 = R T R^{-1}=R^{T} R1=RT,要想求反变换的话,只用求逆变换。
P ′ = M P P^{'}=MP P=MP
P = M − 1 P ′ P=M^{-1}P^{'} P=M1P
对于目标检测来说,通常需要等比缩放且居中,通常可以拆解为以下三步:
在这里插入图片描述
s c a l e = m i n ( d s t . w i d t h o r i g i n . w i d t h , d s t . h e i g h t o r i g i n . h e i g h t ) scale=min(\frac{dst.width}{origin.width},\frac{dst.height}{origin.height}) scale=min(origin.widthdst.width,origin.heightdst.height)
M = M = [ s c a l e 0 − s c a l e ∗ o r i g i n . w i d t h 2 + d s t . w i d t h 2 0 s c a l e − s c a l e ∗ o r i g i n . h e i g h t 2 + d s t . h e i g h t 2 ] M=M=\begin{bmatrix}scale & 0 &-\frac{scale*origin.width}{2}+\frac{dst.width}{2} \\0 & scale&-\frac{scale*origin.height}{2}+\frac{dst.height}{2} \end{bmatrix} M=M=[scale00scale2scaleorigin.width+2dst.width2scaleorigin.height+2dst.height]
示例:主要用在yolov5的处理中

import numpy as np
import matplotlib.pyplot as plt
import cv2

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

def align(image,dst_image):
    orign_h,orign_w=image.shape[:2]
    dst_h,dst_w=dst_image
    k=min(dst_h/orign_h,dst_w/orign_w)
    M=np.array([
               [k,0,-k*orign_w*0.5+dst_w*0.5],
               [0,k,-k*orign_h*0.5+dst_h*0.5]
                ])

    return cv2.warpAffine(image,M,dst_image) ,inv_align(M)

if __name__=="__main__":
    cat1=cv2.imread("cat1.png")
    dst_image,M=align(cat1,(640,640))
    cv2.imwrite("./dst_image.png",dst_image)
    plt.imshow(dst_image[...,::-1])


  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值