图像变形 -- 移动最小二乘法(MLS)

根据变换矩阵的不同,可以分为三种变形方法,分别是:仿射变换、相似变换、刚性变换。其中刚性变换的效果是最好的,这边主要讲最简单的仿射变换,其余的只要替换一下变换矩阵即可实现。

一般的坐标变换

坐标变换一般分为:绕中心的旋转变换 + 平移变换。
l v ( v ) = ( v − p ∗ ) M + q ∗ l_v(v) = (v - p_*)M + q_* lv(v)=(vp)M+q

输入 v v v,将其平移到旋转变换中心 p ∗ p_* p,利用矩阵 M M M做旋转和拉伸变换,如何将变换后的坐标平移到变换后目标的中心 q ∗ q_* q

一般的坐标变换只要一个方程,进行线性变换就可以了。

在多个控制点下的仿射变换

很显然,之前的公式并不适用于多个控制点,所以我们要利用最小二乘法了。其中 p p p为变换前的控制点, q q q为变换后的控制点。

输入一个 v v v,他到各个控制点 p i p_i pi的距离不同,我们假设距离越近的控制点对他影响就越大

每个控制点对输入的影响权重如下,其中 α \alpha α一般取1:
w i = 1 ∣ p i − v ∣ 2 α w_i = \frac{1}{|p_i -v|^{2\alpha}} wi=piv2α1

变换中心 p ∗ , q ∗ p_*,q_* pq计算如下:
p ∗ = ∑ ( w i p i ) ∑ w i p_* = \frac{\sum (w_ip_i)}{\sum w_i} p=wi(wipi) q ∗ = ∑ ( w i q i ) ∑ w i q_* = \frac{\sum (w_iq_i)}{\sum w_i} q=wi(wiqi)

式中分母 ∑ w i {\sum w_i} wi是用来归一化权重因子的,以计算最佳形变中心,对于每个点,都有一个新的变换中心,这是由距离不同导致的。

我们要求的是,在该权重分配下,变换矩阵M是什么。

我们假设在M的作用下,对控制点 p i p_i pi进行变换,结果需要为 q i q_i qi,则最小二乘可以写为 ∑ ∣ p ˉ i M − q ˉ i ∣ 2 \sum |\bar p_i M - \bar q_i|^2 pˉiMqˉi2。其中 p ˉ i = p i − p ∗ \bar p_i =p_i - p_* pˉi=pip q ˉ i = q i − q ∗ \bar q_i =q_i - q_* qˉi=qiq

由于根据影响权重的不同,我们要求距离近的控制点影响要大一些,故最终的加权最小二乘表达式如下:

∑ w i ∣ p ˉ i M − q ˉ i ∣ 2 \sum w_i|\bar p_i M - \bar q_i|^2 wipˉiMqˉi2

在线性代数中,我们求解形如 A x = b Ax=b Ax=b的正规方程最小二乘解,可得:
x = ( A T A ) − 1 A T b x = (A^TA)^{-1}A^Tb x=(ATA)1ATb

故有 M = ( ∑ p i T w i p i ) − 1 ∑ w i p i T q i M = (\sum p_i^T w_i p_i)^{-1} \sum w_i p_i^T q_i M=(piTwipi)1wipiTqi

对于加权最小二乘,假设 A x = b Ax=b Ax=b,两边添加权重矩阵则有 W A x = W b WAx=Wb WAx=Wb,同乘 A T A^T AT,则有 A T W A x = A T W b A^TWAx=A^TWb ATWAx=ATWb,两边再同乘 ( A T W A ) − 1 (A^TWA)^{-1} (ATWA)1可得解

则解为 x = ( A T W A ) − 1 A T W b x = (A^TWA)^{-1}A^TWb x=(ATWA)1ATWb,其中 w w w是权重矩阵。

有了旋转矩阵M的表达式后,我们得到变形的表达式:
l v ( v ) = ( v − p ∗ ) M + q ∗ = ( v − p ∗ ) ( ∑ p i T w i p i ) − 1 ∑ w i p i T q i + q ∗ l_v(v) = (v - p_*)M + q_* = (v - p_*)(\sum p_i^T w_i p_i)^{-1} \sum w_i p_i^T q_i + q_* lv(v)=(vp)M+q=(vp)(piTwipi)1wipiTqi+q

CVfpoint MLS(CVfpoint t , CVVECTORS_F32 pList, CVVECTORS_F32 qList)
{
    CVfpoint fv;
    double A[2][2], B[2][2], M[2][2];
    int num = pList->dataNum;
    float *w = CV_malloc0(num * sizeof(float));

    CVfpoint* p = pList->datap;
    CVfpoint* q = qList->datap;
    //计算各个控制顶点的权重,也就是计算点t到各个顶点的距离1/sqr(d)
    for (int i = 0; i < num; i++)
    {
        float temp;
        if (p[i].x != t.x || p[i].y != t.y)
            temp = 1 / ((p[i].x - t.x) * (p[i].x - t.x) + (p[i].y - t.y) * (p[i].y - t.y));
        else//如果t为控制顶点,那么需要把该控制顶点的权重设置为无穷大
            temp = 100000;

        w[i] = temp;
    }
    CVfpoint pc, qc;
    //q为目标图像的控制点的位置,我们的目标是找到t在q中的对应位置
    double px = 0, py = 0, qx = 0, qy = 0, tw = 0;
    for (int i = 0; i < num; i++)
    {
        px += w[i] * p[i].x;//所有控制顶点p的加权位置
        py += w[i] * p[i].y;
        qx += w[i] * q[i].x;//所有控制顶点q的加权位置
        qy += w[i] * q[i].y;
        tw += w[i];//总权重
    }

    pc.x = px / tw;
    pc.y = py / tw;
    qc.x = qx / tw;
    qc.y = qy / tw;
    //初始化
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
        {
            A[i][j] = 0;
            B[i][j] = 0;
            M[i][j] = 0;
        }


    for (int i = 0; i < num; i++)
    {
        double P[2] = { p[i].x - pc.x,p[i].y - pc.y };//P
        double PT[2][1];//P^T
        PT[0][0] = p[i].x - pc.x;
        PT[1][0] = p[i].y - pc.y;

        double Q[2] = { q[i].x - qc.x,q[i].y - qc.y };//Q
        double T[2][2];
        //T = P^T * P : 列乘行=矩阵
        T[0][0] = PT[0][0] * P[0];
        T[0][1] = PT[0][0] * P[1];
        T[1][0] = PT[1][0] * P[0];
        T[1][1] = PT[1][0] * P[1];
        //A = wi * (P^T * P)
        for (int k = 0; k < 2; k++)
            for (int j = 0; j < 2; j++)
            {
                A[k][j] += w[i] * T[k][j];
            }
        // T = P^T * Q
        T[0][0] = PT[0][0] * Q[0];
        T[0][1] = PT[0][0] * Q[1];
        T[1][0] = PT[1][0] * Q[0];
        T[1][1] = PT[1][0] * Q[1];
        //B = wi * (P^T * Q)
        for (int k = 0; k < 2; k++)
            for (int j = 0; j < 2; j++)
            {
                B[k][j] += w[i] * T[k][j];
            }

    }
    CV_free0(w);
    // 求 A^-1
    double det = A[0][0] * A[1][1] - A[0][1] * A[1][0];
    if (det < 0.0000001)
    {
        fv.x = t.x + qc.x - pc.x;
        fv.y = t.y + qc.y - pc.y;
        return fv;
    }
    double temp1, temp2, temp3, temp4;
    temp1 = A[1][1] / det;
    temp2 = -A[0][1] / det;
    temp3 = -A[1][0] / det;
    temp4 = A[0][0] / det;
    A[0][0] = temp1;
    A[0][1] = temp2;
    A[1][0] = temp3;
    A[1][1] = temp4;

    // M =  A^-1 * B
    M[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0];
    M[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1];
    M[1][0] = A[1][0] * B[0][0] + A[1][1] * B[1][0];
    M[1][1] = A[1][0] * B[0][1] + A[1][1] * B[1][1];
    // V = t - p*
    double V[2] = { t.x - pc.x,t.y - pc.y };
    double R[2][1];
    // R = M * V
    R[0][0] = V[0] * M[0][0] + V[1] * M[1][0];//lv(x)总计算公式
    R[1][0] = V[0] * M[0][1] + V[1] * M[1][1];
    // R + q*
    fv.x = R[0][0] + qc.x;
    fv.y = R[1][0] + qc.y;

    // Ax = b  ==>  x = (A^T*A)^-1 * A^T b
    return fv;
}

相似变形

注意:是相似变形,和矩阵相似变换 P − 1 A P = B P^{-1}AP=B P1AP=B不是一个概念。

仿射变形包含了非均匀缩放,因此其变形效果不是很好。相似变形是仿射变形的一个特殊子集,它的变形效果只包含平移、旋转和均匀缩放。对于均匀缩放,即有相同的特征值,即可分解为 M = λ R M = λ R M=λR形式,其中λ为放缩系数,R为旋转矩阵。所以只要限制转换矩阵 M M M,使其满足 M T M = λ 2 R T R = λ 2 I M^TM =λ^2 R^TR=λ^2I MTM=λ2RTR=λ2I即可。旋转矩阵 R R R的形式必然如下:
R = ( c − s s c ) R = \left(\begin{matrix} c & -s \\ s & c \end{matrix} \right) R=(cssc)

要使矩阵 M M M满足上述条件,可令 M = ( M 1 , M 2 ) M=(M_1 , M_2) M=(M1,M2),其中 M 2 = M 1 ⊥ M_2 = M_1^⊥ M2=M1

符号⊥表示垂直的意思,如对于向量 ( x , y ) (x,y) (x,y),其垂直向量 ( x , y ) ⊥ = ( − y , x ) (x,y)^⊥=(−y,x) (x,y)=(y,x),有向量 x ( − y ) + y x = 0 x(-y)+yx=0 x(y)+yx=0。上述 M 2 = M 1 ⊥ M_2 = M_1^⊥ M2=M1表示矩阵 M M M两列是正交的,了解矩阵施密特正交化的应该很容易理解。

加权最小二乘形式如下:

∑ w i ∣ ( p ˉ i − p ˉ i ⊥ ) M − ( q ˉ i − q ˉ i ⊥ ) ∣ 2 \sum w_i| \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) M - \left(\begin{matrix} \bar q_i \\ -\bar q_i^⊥ \end{matrix} \right) |^2 wi(pˉipˉi)M(qˉiqˉi)2

P = ( p ˉ i − p ˉ i ⊥ ) P =\left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) P=(pˉipˉi),它实际上是一个矩阵,其中若令 p ˉ i = ( x i , y i ) \bar p_i=(x_i,y_i) pˉi=(xi,yi)。则令 p ˉ i ⊥ = ( − y i , x i ) \bar p_i^⊥=(-y_i,x_i) pˉi=(yi,xi)
即,有 ( p ˉ i − p ˉ i ⊥ ) = ( x i y i y i − x i ) \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) = \left(\begin{matrix} x_i & y_i \\ y_i & -x_i \end{matrix} \right) (pˉipˉi)=(xiyiyixi),他用来表示 p ˉ i \bar p_i pˉi及其法向向量,在原式中,经过 M M M矩阵的变换,形如下
P M = λ P R = λ ( x i y i y i − x i ) ( c − s s c ) = ( x i c + y i s − x i s + y i c y i c − x i s − y i c − x i c ) PM=λPR =λ\left(\begin{matrix} x_i & y_i \\ y_i & -x_i \end{matrix} \right) \left(\begin{matrix} c & -s \\ s & c \end{matrix} \right) = \left(\begin{matrix} x_ic+y_is & -x_is+y_ic \\ y_ic-x_is & -y_ic-x_ic \end{matrix} \right) PM=λPR=λ(xiyiyixi)(cssc)=(xic+yisyicxisxis+yicyicxic)
我们可以令 P M = Q = ( q ˉ i − q ˉ i ⊥ ) PM=Q=\left(\begin{matrix} \bar q_i \\ -\bar q_i^⊥ \end{matrix} \right) PM=Q=(qˉiqˉi),这样就表示了两个垂直方向都被放缩了相同的倍数,至于为什么垂直要取负号,大概是因为图像坐标和我们习惯的数学坐标(视觉坐标)是相反的。

即为了求解方程组 P M = Q PM=Q PM=Q,类似的有 M = ( P T W P ) − 1 P T W Q M=(P^TWP)^{-1}P^TWQ M=(PTWP)1PTWQ

P T W P = ∑ w i ( p ˉ i T ( − p ˉ i ⊥ ) T ) ( p ˉ i − p ˉ i ⊥ ) = ∑ w i ( p ˉ i T p ˉ i + p i ⊥ ( p ˉ i ⊥ ) T ) P^TWP =\sum w_i \left(\begin{matrix} \bar p_i^T & (-\bar p_i^⊥)^T \end{matrix} \right) \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) =\sum w_i ( \bar p_i^T \bar p_i+p_i^⊥ (\bar p_i^⊥)^T) PTWP=wi(pˉiT(pˉi)T)(pˉipˉi)=wi(pˉiTpˉi+pi(pˉi)T)

p i T p ˉ i = ( x i 2 x i y i y i x i y i 2 ) p_i^T \bar p_i=\left(\begin{matrix} x_i^2 & x_iy_i \\ y_ix_i & y_i^2 \end{matrix} \right) piTpˉi=(xi2yixixiyiyi2) p i ⊥ ( p ˉ i ⊥ ) T = ( y i 2 − y i x i − x i y i x i 2 ) p_i^⊥ (\bar p_i^⊥)^T=\left(\begin{matrix} y_i^2 & -y_ix_i \\ -x_iy_i & x_i^2 \end{matrix} \right) pi(pˉi)T=(yi2xiyiyixixi2)
则有 p ˉ i T p ˉ i + p i ⊥ ( p ˉ i ⊥ ) T = ( y i 2 + x i 2 0 0 x i 2 + y i 2 ) = ( x i 2 + y i 2 ) ( 1 0 0 1 ) \bar p_i^T \bar p_i+p_i^⊥ (\bar p_i^⊥)^T=\left(\begin{matrix} y_i^2+x_i^2 & 0 \\ 0 & x_i^2+y_i^2 \end{matrix} \right)=(x_i^2+y_i^2)\left(\begin{matrix} 1 & 0 \\ 0 & 1 \end{matrix} \right) pˉiTpˉi+pi(pˉi)T=(yi2+xi200xi2+yi2)=(xi2+yi2)(1001)

( P T W P ) − 1 = 1 ∑ w i p ˉ i p ˉ i T ( 1 0 0 1 ) (P^TWP)^{-1}=\frac{1}{\sum w_i \bar p_i \bar p_i^T}\left(\begin{matrix} 1 & 0 \\ 0 & 1 \end{matrix} \right) (PTWP)1=wipˉipˉiT1(1001)

根据该条件得到相似变形的转换矩阵 M M M如下:

M = 1 μ s ∑ w i ( p ˉ i − p ˉ i ⊥ ) ( q ˉ i − q ˉ i ⊥ ) T M = \frac{1}{\mu_s}\sum w_i \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) \left(\begin{matrix} \bar q_i & -\bar q_i^⊥ \end{matrix} \right)^T M=μs1wi(pˉipˉi)(qˉiqˉi)T

其中 μ s = ∑ w i p ˉ i p ˉ i T \mu_s = \sum w_i \bar p_i \bar p_i^T μs=wipˉipˉiT,左边 1 μ s \frac{1}{\mu_s} μs1乘单位矩阵即 ( P T W P ) − 1 (P^TWP)^{-1} (PTWP)1,右边由于 P = ( x i y i y i − x i ) P= \left(\begin{matrix} x_i & y_i \\ y_i & -x_i \end{matrix} \right) P=(xiyiyixi)是一个对称矩阵,故有 P T = P P^T=P PT=P,而 Q Q Q则写成行向量转置的形式

刚性变形

刚性变形,也就是说变形不含任何缩放效果,我们进一步限制转换矩阵 M M M使其满足 M T M = I M^TM = I MTM=I,这样可以得到刚性变形。

在相似变形中,我们求得 M = 1 μ s ∑ w i ( p ˉ i − p ˉ i ⊥ ) ( q ˉ i − q ˉ i ⊥ ) T M = \frac{1}{\mu_s}\sum w_i \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) \left(\begin{matrix} \bar q_i & -\bar q_i^⊥ \end{matrix} \right)^T M=μs1wi(pˉipˉi)(qˉiqˉi)T,我们只要能求出其放缩系数 λ λ λ,将其除以该系数即可得到刚性变形的矩阵了

P T Q = ( p ˉ i − p ˉ i ⊥ ) ( q ˉ i T ( − q ˉ i ⊥ ) T ) = ( p ˉ i q ˉ i T p ˉ i ( − q ˉ i ⊥ ) T − p ˉ i ( q ˉ i ⊥ ) T p ˉ i ( q ˉ i ⊥ ) T ) P^TQ=\left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) \left(\begin{matrix} \bar q_i^T & (-\bar q_i^⊥)^T \end{matrix} \right)= \left(\begin{matrix} \bar p_i\bar q_i^T & \bar p_i(-\bar q_i^⊥)^T \\ -\bar p_i(\bar q_i^⊥)^T & \bar p_i(\bar q_i^⊥)^T \end{matrix} \right) PTQ=(pˉipˉi)(qˉiT(qˉi)T)=(pˉiqˉiTpˉi(qˉi)Tpˉi(qˉi)Tpˉi(qˉi)T)

我们知道,矩阵元素每一列的模长为拉伸系数 μ s λ \mu_sλ μsλ,取第一列可得:
μ s λ = ( p ˉ i q ˉ i T ) 2 + ( p ˉ i ( q ˉ i ⊥ ) T ) 2 \mu_sλ =\sqrt{(\bar p_i\bar q_i^T)^2+(\bar p_i(\bar q_i^⊥)^T)^2} μsλ=(pˉiqˉiT)2+(pˉi(qˉi)T)2

1 λ = μ s ( p ˉ i q ˉ i T ) 2 + ( p ˉ i ( q ˉ i ⊥ ) T ) 2 \frac{1}{λ }=\frac{\mu_s}{\sqrt{(\bar p_i\bar q_i^T)^2+(\bar p_i(\bar q_i^⊥)^T)^2}} λ1=(pˉiqˉiT)2+(pˉi(qˉi)T)2 μs

故可得,刚性变形的 M M M矩阵解如下
M = 1 λ M 相 似 变 形 = 1 ( ∑ w i p ˉ i q ˉ i T ) 2 + ( ∑ w i p ˉ i ( q ˉ i ⊥ ) T ) 2 ∑ w i ( p ˉ i − p ˉ i ⊥ ) ( q ˉ i − q ˉ i ⊥ ) T M=\frac{1}{λ } M_{相似变形} = \frac{1}{\sqrt{(\sum w_i\bar p_i\bar q_i^T)^2+(\sum w_i\bar p_i(\bar q_i^⊥)^T)^2}}\sum w_i \left(\begin{matrix} \bar p_i \\ -\bar p_i^⊥ \end{matrix} \right) \left(\begin{matrix} \bar q_i & -\bar q_i^⊥ \end{matrix} \right)^T M=λ1M=(wipˉiqˉiT)2+(wipˉi(qˉi)T)2 1wi(pˉipˉi)(qˉiqˉi)T

参考资料

注:所有参考资料的公式都有误,我重新推导的才是对的。
最终项目:基于移动最小二乘的图像变形
卡通图像变形算法
图像处理(十九)基于移动最小二乘的图像变形

你可能感兴趣的:(图像处理,最小二乘法,算法)