精华内容
下载资源
问答
  • 基于移动最小二乘逐点逼近思想,移动权被引入到最小二乘支持向量机的误差变量中,得到新算法的模型.此外,证明了用移动最小二乘支持向量机作函数估计与在特征空间中用移动最小二乘法得到的解是一致的,揭示了移动最小...
  • 移动最小二乘法拟合数据软件-移动最小二乘拟合软件说明.pdf 本帖最后由 jacket2015 于 2015-2-17 23:09 编辑 移动最小二乘拟合软件(附加任意已知函数最小二乘拟合以及神经网络拟合) 功能描述: 1、 本软件...
  • 基于曲率的适应性移动最小二乘曲面重构,黄运保,李海艳,本文提出了一种基于点云数据主曲率计算的适应性移动最小二乘曲面重构方法。此方法在基于积分不变量的球体和球面邻域主分量分析基
  • 移动最小二乘Problem statement: 问题陈述: Given a string S, write a program to check if it is possible to construct the given string S by performing any of the below operations any number of times. ...

    移动最小二乘

    Problem statement:

    问题陈述:

    Given a string S, write a program to check if it is possible to construct the given string S by performing any of the below operations any number of times. In each step, you can:

    给定字符串S ,编写一个程序以检查是否可以通过多次执行以下任何操作来构造给定的字符串S。 在每个步骤中,您可以:

    1. Add any character at the end of the string.

      在字符串末尾添加任何字符。

    2. Append the existing string to the string itself.

      将现有字符串追加到字符串本身。

    The above steps can be applied any number of times. We need to print the minimum steps required to form the string.

    以上步骤可以应用多次。 我们需要打印形成字符串所需的最少步骤。

    Input:

    输入:

    Input String

    输入字符串

    Output:

    输出:

    Minimum number of steps required to form that string.

    形成该字符串所需的最少步骤数。

    Constraints:

    限制条件:

    1 <= string length <= 10^5
    
    

    Example:

    例:

    Input:
    aaaaaaaa 
    
    Output:
    4
    
    Explanation:
    Move 1: add 'a' to form "a"
    Move 2: add 'a' to form "aa"
    Move 3: append "aa" to form "aaaa"
    Move 4: append "aaaa" to form "aaaaaaaa"
    
    Input:
    ijhijhi
    
    Output:
    5
    
    Explanation:
    Move 1: add 'i' to form "i"
    Move 2: add 'j' to form "ij"
    Move 3: add 'h' to form "ijh"
    Move 4: append "ijh" to form "ijhijh"
    Move 5: add 'i' to form "ijhijhi"
    
    

    Solution Approach:

    解决方法:

    So, we have two option

    因此,我们有两种选择

    1. Append single character

      附加单个字符

    2. Append the string itself

      附加字符串本身

    So, say the string is

    所以说这个字符串是

    x1x2 ... xn
    
    

    For any sub-problem of size i,

    对于任何大小为i的子问题,

    x1x2 ... xi
    
    

    Two things are possible,

    有两种可能

    1. Appends xi to sub-problem x1x2 ... x(i-1)

      将x i附加到子问题x 1 x 2 ... x (i-1)

    2. Append x1..xj to x1..xj is x(j+1)..xi is similar to x1..xj

      将x 1 ..x j追加到x 1 ..x j是x (j + 1) ..x i类似于x 1 ..x j

    So, we can formulate the problem recursively,

    因此,我们可以递归地提出问题,

    f(i) = minimum steps to form x1x2 ... xi  
    f(i) = f(i-1)+1
    f(i) = f(j)+1 if j=i/2 and the partitioned strings are same 
    
    

    Now find the minimum.

    现在找到最小值。

    The base value of f(i)=i obviously which is maximum value to form the string.

    f(i)= i的基值显然是构成字符串的最大值。

    So, the above recursion can be transformed to DP.

    因此,上述递归可以转换为DP。

    1)  Declare int dp[n+1];
    2)  Assign the base value.    
        for i=0 to n
            dp[i]=i;
    3)  Fill the DP array
        for i=2 to n
            dp[i]=minimum(dp[i-1]+1,dp[i]); // normal insertion, recursion first case
            if i is even
                if s1s(i/2) = s(i/2+1)sn // if appending string is possible
                    dp[i]=minimum(dp[i],dp[i/2]+1);
            end if
        end for
        
    4)  return dp[n];
    
    DP[n] is the final result
    
    

    C++ Implementation:

    C ++实现:

    #include <bits/stdc++.h>
    using namespace std;
    
    int minimumMoves(string s)
    {
        int n = s.length();
    
        int dp[n + 1];
        for (int i = 0; i <= n; i++)
            dp[i] = i;
    
        for (int i = 2; i <= n; i++) {
            dp[i] = std::min(dp[i - 1] + 1, dp[i]);
            if (i % 2 == 0) {
                int flag = 0;
                for (int j = 0; j < i / 2; j++) {
                    if (s[j] != s[j + i / 2]) {
                        flag = 1;
                        break;
                    }
                }
                if (flag == 0)
                    dp[i] = std::min(dp[i], dp[i / 2] + 1);
            }
        }
    
        return dp[n];
    }
    
    int main()
    {
        cout << "Enter input string\n";
        string s;
        cin >> s;
        
        cout << "Minimum steps to form te string: " << minimumMoves(s) << endl;
    
        return 0;
    }
    
    

    Output:

    输出:

    Enter input string
    incinclude
    Minimum steps to form te string: 8
    
    
    

    翻译自: https://www.includehelp.com/icp/minimal-moves-to-form-a-string.aspx

    移动最小二乘

    展开全文
  • 如所发表的,“移动最小二乘”算法的python实现,用于将点集从一个空间转换到另一个空间 。 重新包装。 用法 控制点和关注点以numpy数组形式给出。 from molesq import Transformer tran = Transformer ( my_...
  • DeepMLS:用于3D重建的深层隐式移动最小二乘函数 该存储库包含本文的实现: 用于3D重构的深层隐式移动最小二乘函数 世林刘,,,,。 如果您发现我们的代码或书面文件有用,请考虑引用 @inproceedings { Liu2021...
  • 针对二维搜索方法实现基于分数阶傅里叶变换(FrFT)的线性调频信号(LFM)参数估计中存在的峰值估计偏差问题,提出可利用移动最小二乘(MLS)技术来拟合FrFT模函数峰值检测向量的方法以提高参数估计性能.该算法将复杂的二维...
  • 移动最小二乘 顾名思义就是移动着求最小二乘,把区间分段的求最小二乘,分段越小自然效果越好,分段越大,自然效果越差,就是利用微分的思想。 数学推导 相比于最小二乘,移动最小二乘建立的拟合函数是采用分段拟合...

    移动最小二乘

    顾名思义就是移动着求最小二乘,把区间分段的求最小二乘,分段越小自然效果越好,分段越大,自然效果越差,就是利用微分的思想。

    数学推导

    相比于最小二乘,移动最小二乘建立的拟合函数是采用分段拟合以及平滑化。由一个系数向量和一个基函数p(x)构成。
    我们可以先把一个区间分成若干个局部子区间,每个子区间进行最小二乘的拟合,子区间的函数可以表示为:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    权函数应该是非负的,并且和距离成反比。权函数还应该具有一定的光滑性,因为拟合函数会继承权函数的连续性。如果权函数n阶连续,对应的拟合函数也是n阶连续的。记
    在这里插入图片描述

    总结

    移动最小二乘中,最关键的部分就是权重函数,在一定的区域内权重是有效值,在超出这个区域内为0,也就是说该方法在逐步的分段的求解这个拟合函数,就是任意一个二维的曲线,我们可以认为是由多个折现组成,这也是微分的一种思想。

    代码实现

    在这里插入图片描述
    在这里插入图片描述
    (这里是直接参考别人的函数的)
    生成的随机点,然后加上一定的误差。
    蓝色的线为拟合后的效果,蓝色的线将区间[-1,1]分成了40分,为此我们得到40份的分段函数,由于40段太长。重新调整移动的步长为0.5,这样一来只有6个区间。我们把拟合的函数绘制出来,并且把分段函数打印出来有:
    在这里插入图片描述
    在这里插入图片描述
    至此已完全实现移动最小二乘的曲线拟合,可以看到效果还是蛮好的,当然了,对于步长越短效果会更好,但是对应的运行时间更长了,对应步长越长效果自然较差。对于该方法如果需要改进只能从权函数入手。

    python代码

    # -*- coding: utf-8 -*-
    
    '''
    @Time    : 2019/12/16 17:38
    @Author  : DWY
    @FileName: MLS.py
    @Software: PyCharm Community Edition
     
    '''
    import numpy as np
    import matplotlib.pyplot as plt
    step=0.05
    #权函数
    def w(dis):
        dis = dis / 0.3
        if dis < 0:
            return 0
        elif dis <= 0.5:
            return 2/3 - 4 * dis**2 + 4 * dis**3
        elif dis <= 1:
            return 4/3 - 4 * dis + 4 * dis**2 - 4/3 * dis**3
        else:
            return 0
    
    
    def mls(x_):
        sumxx = sumx = sumxf = sumf = sumw = 0
        for (a, b) in zip(x, y):
            weight = w(abs(x_ - a))
            sumw += weight
            sumx += a * weight
            sumxx += a * a * weight
            sumf += b * weight
            sumxf += a * b * weight
        A = np.array([[sumw, sumx],
                      [sumx, sumxx]])#A
        B = np.array([sumf, sumxf])#B
        ans = np.linalg.solve(A, B)
        print("%f+%f*x,{x|%f<x<%f}"%(ans[0],ans[1],x_,x_+step))
        return ans[0] + ans[1] * x_
    
    #主题部分
    import random
    #生成曲线上的各个点
    x = np.arange(-1,1,0.02)
    y = [((a*a-1)*(a*a-1)*(a*a-1)+0.5)*np.sin(a*2) for a in x]
    
    # 生成的曲线上的各个点偏移一下,并放入到xa,ya中去
    i = 0
    xa = []
    ya = []
    for xx in x:
        yy = y[i]
        d = float(random.randint(60, 140)) / 100
        # ax.plot([xx*d],[yy*d],color='m',linestyle='',marker='.')
        i += 1
        xa.append(xx * d)
        ya.append(yy * d)
    x = xa
    y = ya
    miny = min(xa)
    maxy = max(xa)
    xx = np.arange(miny, maxy+step, step)
    yy = [mls(xi) for xi in xx]
    plt.plot(xx, yy)
    plt.scatter(x, y, c='r')
    plt.show()
    #其他函数部分
    #权函数
    
    
    

    以上代码直接能运行

    展开全文
  • 针对移动最小二乘算法在图像变形过程中,求解的线性方程组系数矩阵会出现不可逆、求解不稳定的问题,通过引入Tikhonov正则化,运用L-曲线法求解正则参数,对系数矩阵施加约束项从而得到精确解,避免病态方程组的形成;...
  • 采用不锈钢扁管加载实验模拟简支梁加载过程,利用三维激光扫描仪获取不锈钢扁管变形前后的点云数据,并假设变形沿着变形后曲面法线方向发生,将变形前的点云数据利用移动最小二乘投影法投影到变形后的曲面上获得变形...
  • 源于清华大学出版社,张雄《无网格法》中的一维移动最小二乘近似的MATLAB程序
  • 基于移动最小二乘的图像变形

    千次阅读 2018-05-17 10:12:29
    原文地址:http://blog.csdn.net/hjimce/article/details/46550001作者:hjimce一、背景意义写这篇博文是应为目前为止我看到了好多领域里的经典paper算法都有涉及到移动最小二乘(MLS)。可见这个算法非常重要,先来...


    原文地址:http://blog.csdn.net/hjimce/article/details/46550001

    作者:hjimce

    一、背景意义

    写这篇博文是应为目前为止我看到了好多领域里的经典paper算法都有涉及到移动最小二乘(MLS)。可见这个算法非常重要,先来看一下它的相关经典应用:

    1、图像变形。在图像处理领域paper:《Image Deformation Using Moving Least Squares》利用移动最小二乘的原理实现了图像的相关变形,而且这篇paper的引用率非常高,可以说是图像变形算法的经典算法,Siggraph上面的paper。


    利用移动最小二乘实现图像变形

    2、点云滤波。利用MLS实现点云滤波,是三维图像学点云处理领域的一大应用,我所知道点云滤波经典算法包括:双边滤波、MLS、WLOP。

    3、Mesh Deformation。用这个算法实现三角网格模型的变形应用也是非常不错的,相关的paper《3D Deformation Using Moving Least Squares

    OK,接着我就以《Image Deformation Using Moving Least Squares》算法为例,进行讲解基于移动最小二乘的图像变形算法实现。

    二、算法实现

    在这里我没有打算将算法原理的推导过程,直接讲算法的实现步骤公式。

    这篇paper根据变换矩阵的不同,可以分为三种变形方法,分别是仿射变换、相似变换、刚性变换。其中刚性变换的效果是最好的,我这边从简单的讲,只讲仿射变换的变形算法实现:

    问题:原图像的各个控制顶点坐标p,原图像上的像素点v的坐标。变形后图像的控制顶点位置q,求v在变形后图像中对应位置f(v)。

    总计算公式为:


    上面中lv(x)和f(v)是同一个函数。因为x就是我们输入的原图像的像素点坐标v。

    因此我们的目标就是要知道p*,q*,变换矩阵M。这样输入一个参数x,我们就可以计算出它在变换后图像中的位置了。

    OK,只要我们知道上面公式中,各个参数的计算方法,我们就可以计算出变形后图像对应的坐标点f(v)了。

    1、权重w的计算方法为:


    也就是计算v到控制顶点pi的距离倒数作为权重,参数a一般取值为1。

    这一步实现代码如下:

    1. //计算各个控制顶点的权重,也就是计算点t到各个顶点的距离1/sqr(d)  
    2. while(iter!=p.end())  
    3. {  
    4.     double temp;  
    5.     if(iter->x!=t.x || iter->y!=t.y)  
    6.         temp=1/((iter->x-t.x)*(iter->x-t.x)+(iter->y-t.y)*(iter->y-t.y));  
    7.     else//如果t为控制顶点,那么需要把该控制顶点的权重设置为无穷大  
    8.         temp=MAXNUM;  
    9.     w.push_back(temp);  
    10.     iter++;  
    11. }  
    2、q*,p*的计算公式如下:

    也就是计算控制顶点pi和qi的加权求和重心位置。

    1. double px=0,py=0,qx=0,qy=0,tw=0;  
    2. while(iterw!=w.end())  
    3. {  
    4. px+=(*iterw)*(iter->x);//所有控制顶点p的加权位置  
    5. py+=(*iterw)*(iter->y);  
    6. qx+=(*iterw)*(iterq->x);//所有控制顶点q的加权位置  
    7. qy+=(*iterw)*(iterq->y);  
    8. tw+=*iterw;//总权重  
    9. iter++;  
    10.    iterw++;  
    11. iterq++;  
    12. }  
    13. pc.x=px/tw;  
    14. pc.y=py/tw;  
    15. qc.x=qx/tw;  
    16. qc.y=qy/tw;  
    3、仿射变换矩阵M的计算公式如下:



    只要把相关的参数都带进去就可以计算了。

    最后贴一些完整的MLS源代码:

    1. //输入原图像的t点,输出变形后图像的映射点f(v)  
    2. MyPoint CMLSDlg::MLS(const MyPoint& t)  
    3. {  
    4.     if(p.empty())//原图像的控制顶点p,与输入点t为同一副图像坐标系下  
    5.         return t;  
    6.     MyPoint fv;  
    7.     double A[2][2],B[2][2],M[2][2];  
    8.     iter=p.begin();  
    9.     w.erase(w.begin(),w.end());  
    10.     //计算各个控制顶点的权重,也就是计算点t到各个顶点的距离1/sqr(d)  
    11.     while(iter!=p.end())  
    12.     {  
    13.         double temp;  
    14.         if(iter->x!=t.x || iter->y!=t.y)  
    15.             temp=1/((iter->x-t.x)*(iter->x-t.x)+(iter->y-t.y)*(iter->y-t.y));  
    16.         else//如果t为控制顶点,那么需要把该控制顶点的权重设置为无穷大  
    17.             temp=MAXNUM;  
    18.         w.push_back(temp);  
    19.         iter++;  
    20.     }  
    21.     vector<double>::iterator iterw=w.begin();  
    22.     vector<MyPoint>::iterator iterq=q.begin();//q为目标图像的控制点的位置,我们的目标是找到t在q中的对应位置  
    23.     iter=p.begin();  
    24.     MyPoint pc,qc;  
    25.     double px=0,py=0,qx=0,qy=0,tw=0;  
    26.     while(iterw!=w.end())  
    27.     {  
    28.     px+=(*iterw)*(iter->x);//所有控制顶点p的加权位置  
    29.     py+=(*iterw)*(iter->y);  
    30.     qx+=(*iterw)*(iterq->x);//所有控制顶点q的加权位置  
    31.     qy+=(*iterw)*(iterq->y);  
    32.     tw+=*iterw;//总权重  
    33.     iter++;  
    34.     iterw++;  
    35.     iterq++;  
    36.     }  
    37.     pc.x=px/tw;  
    38.     pc.y=py/tw;  
    39.     qc.x=qx/tw;  
    40.     qc.y=qy/tw;  
    41.     iter=p.begin();  
    42.     iterw=w.begin();  
    43.     iterq=q.begin();  
    44.     for(int i=0;i<2;i++)  
    45.     for(int j=0;j<2;j++)  
    46.     {  
    47.     A[i][j]=0;  
    48.     B[i][j]=0;  
    49.     M[i][j]=0;  
    50.     }  
    51.     while(iter!=p.end())  
    52.     {  
    53.   
    54.     double P[2]={iter->x-pc.x,iter->y-pc.y};  
    55.     double PT[2][1];  
    56.     PT[0][0]=iter->x-pc.x;  
    57.     PT[1][0]=iter->y-pc.y;  
    58.     double Q[2]={iterq->x-qc.x,iterq->y-qc.y};  
    59.     double T[2][2];  
    60.      
    61.     T[0][0]=PT[0][0]*P[0];  
    62.     T[0][1]=PT[0][0]*P[1];  
    63.     T[1][0]=PT[1][0]*P[0];  
    64.     T[1][1]=PT[1][0]*P[1];  
    65.   
    66.     for(int i=0;i<2;i++)  
    67.     for(int j=0;j<2;j++)  
    68.     {  
    69.     A[i][j]+=(*iterw)*T[i][j];  
    70.     }  
    71.     T[0][0]=PT[0][0]*Q[0];  
    72.     T[0][1]=PT[0][0]*Q[1];  
    73.     T[1][0]=PT[1][0]*Q[0];  
    74.     T[1][1]=PT[1][0]*Q[1];  
    75.       
    76.     for(int i=0;i<2;i++)  
    77.     for(int j=0;j<2;j++)  
    78.     {  
    79.     B[i][j]+=(*iterw)*T[i][j];  
    80.     }  
    81.   
    82.     iter++;  
    83.     iterw++;  
    84.     iterq++;  
    85.     }  
    86.     //cvInvert(A,M);  
    87.     double det=A[0][0]*A[1][1]-A[0][1]*A[1][0];  
    88.     if(det<0.0000001)  
    89.     {  
    90.         fv.x=t.x+qc.x-pc.x;  
    91.         fv.y=t.y+qc.y-pc.y;  
    92.         return fv;  
    93.     }  
    94.     double temp1,temp2,temp3,temp4;  
    95.     temp1=A[1][1]/det;  
    96.     temp2=-A[0][1]/det;  
    97.     temp3=-A[1][0]/det;  
    98.     temp4=A[0][0]/det;  
    99.     A[0][0]=temp1;  
    100.     A[0][1]=temp2;  
    101.     A[1][0]=temp3;  
    102.     A[1][1]=temp4;  
    103.   
    104.   
    105.     M[0][0]=A[0][0]*B[0][0]+A[0][1]*B[1][0];  
    106.     M[0][1]=A[0][0]*B[0][1]+A[0][1]*B[1][1];  
    107.     M[1][0]=A[1][0]*B[0][0]+A[1][1]*B[1][0];  
    108.     M[1][1]=A[1][0]*B[0][1]+A[1][1]*B[1][1];  
    109.   
    110.     double V[2]={t.x-pc.x,t.y-pc.y};  
    111.     double R[2][1];  
    112.     
    113.     R[0][0]=V[0]*M[0][0]+V[1]*M[1][0];//lv(x)总计算公式  
    114.     R[1][0]=V[0]*M[0][1]+V[1]*M[1][1];  
    115.     fv.x=R[0][0]+qc.x;  
    116.     fv.y=R[1][0]+qc.y;  
    117.   
    118.     return fv;  
    119. }  


    调用方法示例:

    1.    int i=0,j=0;  
    2. dImage=cvCreateImage(cvSize(2*pImage->width,2*pImage->height),pImage->depth,pImage->nChannels);//创建新的变形图像  
    3. cvSet(dImage,cvScalar(0));  
    4. MyPoint Orig=MLS(MyPoint(IR_X,IR_Y));  
    5. int Orig_x=(int)(Orig.x)-(int)(pImage->width/2);  
    6. int Orig_y=(int)(Orig.y)-(int)(pImage->height/2);  
    7.   
    8. for(i=0;i<pImage->height;i++)//遍历原图像的每个像素  
    9. {  
    10.     for(j=0;j<pImage->width;j++)  
    11.     {  
    12.         CvScalar color;  
    13.         double x=j+IR_X;  
    14.         double y=i+IR_Y;  
    15.         MyPoint t=MLS(MyPoint(x,y));//MLS计算原图像(x,y)在目标图像的映射位置f(v)  
    16.         int m=(int)(t.x);  
    17.         int n=(int)(t.y);  
    18.         m-=Orig_x;  
    19.            n-=Orig_y;  
    20.         color=cvGet2D(pImage,i,j);//像素获取  
    21.         if(0<=m && dImage->width>m && 0<=n && dImage->height>n)  
    22.         {  
    23.         cvSet2D(dImage,n,m,color);  
    24.         }  
    25.     }  
    26. }  
    图像变形算法,有正向映射和逆向映射,如果按照每个像素点,都通过上面的计算方法求取其对应变换后的像素点位置,那么其实计算量是非常大的,因为一幅图像的像素点,实在是太多了,如果每个像素点,都用上面的函数遍历过一遍,那计算量可想而知。

    因此一般的变形算法是对待图像进行三角剖分:


    然后只根据只对三角网格模型的顶点,根据变形算法,计算出三角网格模型每个顶点的新位置,最后再用三角形仿射变换的方法,计算三角形内每个像素点的值,得到变形后的图像,这样不仅速度快,同事解决了正向映射与逆向映射变形算法存在的不足之处,具体图像变形的正向和逆向映射存在的缺陷,可以自己查看相关的文献。

    另外两种相似变换和刚性变换,可以自己查看M矩阵的计算公式,编写实现相关代码。

    本文地址:http://blog.csdn.net/hjimce/article/details/46550001     作者:hjimce     联系qq:1393852684   更多资源请关注我的博客:http://blog.csdn.net/hjimce                原创文章,转载请保留本行信息*************

    参考文献:

    1、《Image Deformation Using Moving Least Squares》

    2、3D Deformation Using Moving Least Squares

    展开全文
  • 写这篇博文是应为目前为止我看到了好多领域里的经典paper算法都有涉及到移动最小二乘(MLS)。可见这个算法非常重要,先来看一下它的相关经典应用: 1、图像变形。在图像处理领域paper:《Image Deformation Using ...

    基于移动最小二乘的图像变形

    原文地址:http://blog.csdn.net/hjimce/article/details/46550001

    作者:hjimce

    一、背景意义

    写这篇博文是应为目前为止我看到了好多领域里的经典paper算法都有涉及到移动最小二乘(MLS)。可见这个算法非常重要,先来看一下它的相关经典应用:

    1、图像变形。在图像处理领域paper:《Image Deformation Using Moving Least Squares》利用移动最小二乘的原理实现了图像的相关变形,而且这篇paper的引用率非常高,可以说是图像变形算法的经典算法,Siggraph上面的paper。


    利用移动最小二乘实现图像变形

    2、点云滤波。利用MLS实现点云滤波,是三维图像学点云处理领域的一大应用,我所知道点云滤波经典算法包括:双边滤波、MLS、WLOP。

    3、Mesh Deformation。用这个算法实现三角网格模型的变形应用也是非常不错的,相关的paper《3D Deformation Using Moving Least Squares

    OK,接着我就以《Image Deformation Using Moving Least Squares》算法为例,进行讲解基于移动最小二乘的图像变形算法实现。

    二、算法实现

    在这里我没有打算将算法原理的推导过程,直接讲算法的实现步骤公式。

    这篇paper根据变换矩阵的不同,可以分为三种变形方法,分别是仿射变换、相似变换、刚性变换。其中刚性变换的效果是最好的,我这边从简单的讲,只讲仿射变换的变形算法实现:

    问题:原图像的各个控制顶点坐标p,原图像上的像素点v的坐标。变形后图像的控制顶点位置q,求v在变形后图像中对应位置f(v)。

    总计算公式为:


    上面中lv(x)和f(v)是同一个函数。因为x就是我们输入的原图像的像素点坐标v。

    因此我们的目标就是要知道p*,q*,变换矩阵M。这样输入一个参数x,我们就可以计算出它在变换后图像中的位置了。

    OK,只要我们知道上面公式中,各个参数的计算方法,我们就可以计算出变形后图像对应的坐标点f(v)了。

    1、权重w的计算方法为:


    也就是计算v到控制顶点pi的距离倒数作为权重,参数a一般取值为1。

    这一步实现代码如下:

    	//计算各个控制顶点的权重,也就是计算点t到各个顶点的距离1/sqr(d)
    	while(iter!=p.end())
    	{
    		double temp;
    		if(iter->x!=t.x || iter->y!=t.y)
    		    temp=1/((iter->x-t.x)*(iter->x-t.x)+(iter->y-t.y)*(iter->y-t.y));
    		else//如果t为控制顶点,那么需要把该控制顶点的权重设置为无穷大
    			temp=MAXNUM;
    		w.push_back(temp);
    		iter++;
    	}
    2、q*,p*的计算公式如下:

    也就是计算控制顶点pi和qi的加权求和重心位置。

    	double px=0,py=0,qx=0,qy=0,tw=0;
    	while(iterw!=w.end())
    	{
    	px+=(*iterw)*(iter->x);//所有控制顶点p的加权位置
    	py+=(*iterw)*(iter->y);
    	qx+=(*iterw)*(iterq->x);//所有控制顶点q的加权位置
    	qy+=(*iterw)*(iterq->y);
    	tw+=*iterw;//总权重
    	iter++;
        iterw++;
    	iterq++;
    	}
    	pc.x=px/tw;
    	pc.y=py/tw;
    	qc.x=qx/tw;
    	qc.y=qy/tw;
    3、仿射变换矩阵M的计算公式如下:



    只要把相关的参数都带进去就可以计算了。

    最后贴一些完整的MLS源代码:

    //输入原图像的t点,输出变形后图像的映射点f(v)
    MyPoint CMLSDlg::MLS(const MyPoint& t)
    {
    	if(p.empty())//原图像的控制顶点p,与输入点t为同一副图像坐标系下
    		return t;
    	MyPoint fv;
    	double A[2][2],B[2][2],M[2][2];
    	iter=p.begin();
    	w.erase(w.begin(),w.end());
    	//计算各个控制顶点的权重,也就是计算点t到各个顶点的距离1/sqr(d)
    	while(iter!=p.end())
    	{
    		double temp;
    		if(iter->x!=t.x || iter->y!=t.y)
    		    temp=1/((iter->x-t.x)*(iter->x-t.x)+(iter->y-t.y)*(iter->y-t.y));
    		else//如果t为控制顶点,那么需要把该控制顶点的权重设置为无穷大
    			temp=MAXNUM;
    		w.push_back(temp);
    		iter++;
    	}
    	vector<double>::iterator iterw=w.begin();
    	vector<MyPoint>::iterator iterq=q.begin();//q为目标图像的控制点的位置,我们的目标是找到t在q中的对应位置
    	iter=p.begin();
    	MyPoint pc,qc;
    	double px=0,py=0,qx=0,qy=0,tw=0;
    	while(iterw!=w.end())
    	{
    	px+=(*iterw)*(iter->x);//所有控制顶点p的加权位置
    	py+=(*iterw)*(iter->y);
    	qx+=(*iterw)*(iterq->x);//所有控制顶点q的加权位置
    	qy+=(*iterw)*(iterq->y);
    	tw+=*iterw;//总权重
    	iter++;
        iterw++;
    	iterq++;
    	}
    	pc.x=px/tw;
    	pc.y=py/tw;
    	qc.x=qx/tw;
    	qc.y=qy/tw;
    	iter=p.begin();
    	iterw=w.begin();
    	iterq=q.begin();
    	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;
    	}
    	while(iter!=p.end())
    	{
    
    	double P[2]={iter->x-pc.x,iter->y-pc.y};
    	double PT[2][1];
    	PT[0][0]=iter->x-pc.x;
    	PT[1][0]=iter->y-pc.y;
    	double Q[2]={iterq->x-qc.x,iterq->y-qc.y};
    	double T[2][2];
       
        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];
    
    	for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
    	{
    	A[i][j]+=(*iterw)*T[i][j];
    	}
    	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];
        
    	for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
    	{
    	B[i][j]+=(*iterw)*T[i][j];
    	}
    
    	iter++;
        iterw++;
    	iterq++;
    	}
    	//cvInvert(A,M);
        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[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];
    
    	double V[2]={t.x-pc.x,t.y-pc.y};
    	double R[2][1];
      
    	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];
    	fv.x=R[0][0]+qc.x;
    	fv.y=R[1][0]+qc.y;
    
    	return fv;
    }


    调用方法示例:

        int i=0,j=0;
    	dImage=cvCreateImage(cvSize(2*pImage->width,2*pImage->height),pImage->depth,pImage->nChannels);//创建新的变形图像
    	cvSet(dImage,cvScalar(0));
    	MyPoint Orig=MLS(MyPoint(IR_X,IR_Y));
    	int Orig_x=(int)(Orig.x)-(int)(pImage->width/2);
    	int Orig_y=(int)(Orig.y)-(int)(pImage->height/2);
    
    	for(i=0;i<pImage->height;i++)//遍历原图像的每个像素
    	{
    		for(j=0;j<pImage->width;j++)
    		{
    			CvScalar color;
    			double x=j+IR_X;
    			double y=i+IR_Y;
    			MyPoint t=MLS(MyPoint(x,y));//MLS计算原图像(x,y)在目标图像的映射位置f(v)
    			int m=(int)(t.x);
    			int n=(int)(t.y);
    			m-=Orig_x;
                n-=Orig_y;
    			color=cvGet2D(pImage,i,j);//像素获取
    			if(0<=m && dImage->width>m && 0<=n && dImage->height>n)
    			{
    			cvSet2D(dImage,n,m,color);
    			}
    		}
    	}
    图像变形算法,有正向映射和逆向映射,如果按照每个像素点,都通过上面的计算方法求取其对应变换后的像素点位置,那么其实计算量是非常大的,因为一幅图像的像素点,实在是太多了,如果每个像素点,都用上面的函数遍历过一遍,那计算量可想而知。

    因此一般的变形算法是对待图像进行三角剖分:


    然后只根据只对三角网格模型的顶点,根据变形算法,计算出三角网格模型每个顶点的新位置,最后再用三角形仿射变换的方法,计算三角形内每个像素点的值,得到变形后的图像,这样不仅速度快,同事解决了正向映射与逆向映射变形算法存在的不足之处,具体图像变形的正向和逆向映射存在的缺陷,可以自己查看相关的文献。

    另外两种相似变换和刚性变换,可以自己查看M矩阵的计算公式,编写实现相关代码。

    本文地址:http://blog.csdn.net/hjimce/article/details/46550001     作者:hjimce     联系qq:1393852684   更多资源请关注我的博客:http://blog.csdn.net/hjimce                原创文章,转载请保留本行信息*************

    参考文献:

    1、《Image Deformation Using Moving Least Squares》

    2、3D Deformation Using Moving Least Squares

    展开全文
  • 基于移动最小二乘的图像变形技术 / Warp.h: interface for the CWarp class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include ...
  • mls 移动最小二乘

    2013-05-09 13:17:44
    matlab 描述主要给定了定义。然后解决
  • 基于移动最小二乘(MLS)的图像扭曲刚性变形python实现简单介绍一下基于mls的图像变形直接上代码用来做的一个瘦脸前后对比写在后面 简单介绍一下基于mls的图像变形 先假设我们的图片像素为h乘w,这个算法的一个流程...
  •  这次主要介绍一种点云对齐的方法,多视数据最近迭代(ICP)对齐是最常用的点云对齐方法,为了提高对齐的精度及稳定性我们使用一种基于移动最小二乘(MLS)曲面的ICP多视数据对齐方法.该方法无需对数据进行额外的去噪和...
  • MLS(移动最小二乘

    万次阅读 2018-07-25 15:42:20
    1.拟合函数的建立不同。这种方法建立拟合函数不是采用传统的多项式或其他函数,而是通过系数向量和基函数来决定在某个x处的值。 2.引入紧支的概念,认为在x处的值y只受到x附近子域内的节点的影响。...
  • MLS(移动最小二乘)

    2018-12-22 10:05:00
    https://blog.csdn.net/baidu_38127162/article/details/82380914 转载于:https://www.cnblogs.com/jiahenhe2/p/10159944.html
  • MLS 移动最小二乘

    2011-11-20 19:14:00
    1.拟合函数的建立不同。这种方法建立拟合函数不是采用传统的多项式或其他函数,而是通过系数向量和基函数来决定在某个x处的值。 2.引入紧支的概念,认为在x处的值y只受到x附近子域内的节点的影响。...
  • 在最近的项目中经常遇到给出几个点需要拟合出一条...但如果曲线曲面形式未知,可以使用移动最小二乘法或者主曲线方法。 转载:https://blog.csdn.net/liumangmao1314/article/details/54179526 MLS的讲解 移动最...
  • 本文重点 上一篇博客介绍了基本隐式曲面的生成,以及点云对齐的基本操作,但是发现精度达不到理想要求,本文通过优化迭代点和步长设置优化点云对齐到隐式曲面的精度。 一、优化迭代点 接上文图 ...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 142
精华内容 56
关键字:

移动最小二乘