求各位大人帮忙
我在网上找到一个算法,就是将一个四边形中的点映射到另一个四边形中的算法
但是其中有一段我不太明白,请各位看看
代码如下:

解决方案 »

  1.   

    float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3; float *mat;
    float dx1 = x1 - x2,  dy1 = y1 - y2;
    float dx2 = x3 - x2,  dy2 = y3 - y2;
    float sx = x0 - x1 + x2 - x3;
    float sy = y0 - y1 + y2 - y3;
    float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);
    float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);
    float a = x1 - x0 + g * x1;
    float b = x3 - x0 + h * x3;
    float c = x0;
    float d = y1 - y0 + g * y1;
    float e = y3 - y0 + h * y3;
    float f = y0;

    mat[ 0] = a; mat[ 1] = d; mat[ 2] = 0; mat[ 3] = g;
    mat[ 4] = b; mat[ 5] = e; mat[ 6] = 0; mat[ 7] = h;
    mat[ 8] = 0; mat[ 9] = 0; mat[10] = 1; mat[11] = 0;
    mat[12] = c; mat[13] = f; mat[14] = 0; mat[15] = 1;
      

  2.   

    其中(x0,y0),(x1,y1),(x2,y2),(x3,y3)为四边形的四个顶点
    最后得到的mat[16]为一个4X4的矩阵
    我想知道这段代码是依据什么原理将四个点转换为矩阵的
      

  3.   

    4*4的矩阵可以描述三维空间中点的变换。
    变换公式形如:[x y z 1] M = [x' y' z' 1];
    M = [m00, m01, m02, m03; m10, m11, m12, m13; m20, m21, m22, m23; m30, m31, m32, m33];
    其中的3*3的矩阵[m00, m01, m02; m10, m11, m12; m30, m31, m32];将产生比例、对称、错切、旋转等基本变换;
    其中的1*3矩阵[m30, m31, m32]将产生平移变换;
    其中的3*1矩阵[m03, m13, m23]T 将产生透视变换;
    最后[m33]将产生全比例变换效果。返回来看楼主代码中定义的变换矩阵:mat[ 0] = a; mat[ 1] = d; mat[ 2] = 0; mat[ 3] = g;
    mat[ 4] = b; mat[ 5] = e; mat[ 6] = 0; mat[ 7] = h;
    mat[ 8] = 0; mat[ 9] = 0; mat[10] = 1; mat[11] = 0;
    mat[12] = c; mat[13] = f; mat[14] = 0; mat[15] = 1;3*3矩阵为[a, d, 0; b , e, 0; 0, 0, 1];注意到第3行为[0,0,1]、且第3列为[0,0,1],即这个变化描述的是一个2维旋转变换。
    1*3矩阵为[c, f, 0],这表示在二维上存在平移变换。
    3*1矩阵为[g, h, 0],这表示在二维上存在透视变换。
    最后全比例变换参数为1,这说明没有发生全比例变换。从二维上坐标点映射的角度看,将一个四边形映射到另一个四边形,其变换不外乎旋转、平移、透视变换。而从mat矩阵中也正说明了这一点。
      

  4.   

    感谢beyond071(法比加斯) 的回答,但是我想知道的是我怎么得到那个矩阵的
    即为什么要通过以下这段代码得到mat矩阵
    float dx1 = x1 - x2, dy1 = y1 - y2;
    float dx2 = x3 - x2, dy2 = y3 - y2;
    float sx = x0 - x1 + x2 - x3;
    float sy = y0 - y1 + y2 - y3;
    float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);
    float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);
    float a = x1 - x0 + g * x1;
    float b = x3 - x0 + h * x3;
    float c = x0;
    float d = y1 - y0 + g * y1;
    float e = y3 - y0 + h * y3;
    float f = y0;
      

  5.   

    这个代码我是从一本书上找的,有好几个函数,有点长 你看一下
    void ConverterRegion::setIdentity(float* fpointSrcX,float* fpointSrcY,CPoint* fpointDes)
    {
    setSource(fpointSrcX[0],fpointSrcY[0],fpointSrcX[1],fpointSrcY[1],
    fpointSrcX[2],fpointSrcY[2],fpointSrcX[3],fpointSrcY[3]);
    setDestination((float)fpointDes[0].x,(float)fpointDes[0].y,(float)fpointDes[1].x,(float)fpointDes[1].y,
    (float)fpointDes[2].x,(float)fpointDes[2].y,(float)fpointDes[3].x,(float)fpointDes[3].y);
    computeWarp();
    }void ConverterRegion::setSource(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
    {
    srcX[0] = x0;
    srcY[0] = y0;
    srcX[1] = x1;
    srcY[1] = y1;
    srcX[2] = x2;
    srcY[2] = y2;
    srcX[3] = x3;
    srcY[3] = y3;
    }void ConverterRegion::setDestination(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
    {
    dstX[0] = x0;
    dstY[0] = y0;
    dstX[1] = x1;
    dstY[1] = y1;
    dstX[2] = x2;
    dstY[2] = y2;
    dstX[3] = x3;
    dstY[3] = y3;
    }void ConverterRegion::warp(float fSrcX,float fSrcY,CPoint& pointDes)
    {
    float fDesx = (float) pointDes.x;
    float fDesy = (float) pointDes.y; warp(warpMat, fSrcX,fSrcY,fDesx,fDesy); pointDes.x = (int)fDesx;
    if ( fabs(pointDes.x - fDesx) >= 0.5 )
    pointDes.x++; pointDes.y = (int)fDesy;
    if ( fabs(pointDes.y - fDesy) >= 0.5 )
    pointDes.y++;
    }void ConverterRegion::warp(float fSrcX,float fSrcY,float &fDesx,float &fDesy)
    {
    warp(warpMat, fSrcX,fSrcY,fDesx,fDesy);
    }void ConverterRegion::warp(float *mat, float srcX, float srcY, float &dstX, float &dstY)
    {
    float z = 0;
        result[0] = (float)(srcX * mat[0] + srcY*mat[4] + z*mat[8] + 1*mat[12]);
        result[1] = (float)(srcX * mat[1] + srcY*mat[5] + z*mat[9] + 1*mat[13]);
        result[2] = (float)(srcX * mat[2] + srcY*mat[6] + z*mat[10] + 1*mat[14]);
        result[3] = (float)(srcX * mat[3] + srcY*mat[7] + z*mat[11] + 1*mat[15]);        
        dstX = result[0]/result[3];
    dstY = result[1]/result[3];
    }
    void ConverterRegion::multMats(float *srcMat, float *dstMat, float *resMat)
    {
    // DSTDO/CBB: could be faster, but not called often enough to matter
    for (int r = 0; r < 4; r++) {
    int ri = r * 4;
    for (int c = 0; c < 4; c++) {
    resMat[ri + c] = (srcMat[ri    ] * dstMat[c     ] +
    srcMat[ri + 1] * dstMat[c +  4] +
    srcMat[ri + 2] * dstMat[c +  8] +
    srcMat[ri + 3] * dstMat[c + 12]);
    }
    }
    }void ConverterRegion::computeQuadToSquare(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float *mat)
    {
    computeSquareToQuad(x0,y0,x1,y1,x2,y2,x3,y3, mat);

    // invert through adjoint

    float a = mat[0], d = mat[ 1], /* ignore */ g = mat[ 3];
    float b = mat[4], e = mat[ 5], /* 3rd col*/ h = mat[ 7];
    /* ignore 3rd row */
    float c = mat[12], f = mat[13];

    float A =     e - f * h;
    float B = c * h - b;
    float C = b * f - c * e;
    float D = f * g - d;
    float E =     a - c * g;
    float F = c * d - a * f;
    float G = d * h - e * g;
    float H = b * g - a * h;
    float I = a * e - b * d;

    // Probably unnecessary since 'I' is also scaled by the determinant,
    //   and 'I' scales the homogeneous coordinate, which, in turn,
    //   scales the X,Y coordinates.
    // Determinant  =   a * (e - f * h) + b * (f * g - d) + c * (d * h - e * g);
    float idet = 1.0f / (a * A           + b * D           + c * G);

    mat[ 0] = A * idet; mat[ 1] = D * idet; mat[ 2] = 0; mat[ 3] = G * idet;
    mat[ 4] = B * idet; mat[ 5] = E * idet; mat[ 6] = 0; mat[ 7] = H * idet;
    mat[ 8] = 0       ; mat[ 9] = 0       ; mat[10] = 1; mat[11] = 0       ;
    mat[12] = C * idet; mat[13] = F * idet; mat[14] = 0; mat[15] = I * idet;
    }void ConverterRegion::computeSquareToQuad(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float *mat)
    { float dx1 = x1 - x2,  dy1 = y1 - y2;
    float dx2 = x3 - x2,  dy2 = y3 - y2;
    float sx = x0 - x1 + x2 - x3;
    float sy = y0 - y1 + y2 - y3;
    float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);
    float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);
    float a = x1 - x0 + g * x1;
    float b = x3 - x0 + h * x3;
    float c = x0;
    float d = y1 - y0 + g * y1;
    float e = y3 - y0 + h * y3;
    float f = y0;

    mat[ 0] = a; mat[ 1] = d; mat[ 2] = 0; mat[ 3] = g;
    mat[ 4] = b; mat[ 5] = e; mat[ 6] = 0; mat[ 7] = h;
    mat[ 8] = 0; mat[ 9] = 0; mat[10] = 1; mat[11] = 0;
    mat[12] = c; mat[13] = f; mat[14] = 0; mat[15] = 1;
    }void ConverterRegion::computeWarp()
    {
    computeQuadToSquare( srcX[0],srcY[0],
    srcX[1],srcY[1],
    srcX[2],srcY[2],
    srcX[3],srcY[3],
    srcMat);

    computeSquareToQuad( dstX[0], dstY[0],
    dstX[1], dstY[1],
    dstX[2], dstY[2],
    dstX[3], dstY[3],
    dstMat);

    multMats(srcMat, dstMat, warpMat);
    }
      

  6.   

    回帖没法写公式,推导过程我发在blog上了哈
    http://blog.csdn.net/beyond071/archive/2010/08/25/5837723.aspx