Vector4 Transform(const Matrix4 &m, const Vector4 &v) { // ************************************************************ // The formula to transform the vector/point is as follows: // ------------------------------------------------------------ // p' = xX' + yY' + zZ' + T // OR // p'.x = (x * X'.x) + (x * Y'.x) + (x * Z'.x) + T.x // p'.y = (y * X'.y) + (y * Y'.y) + (y * Z'.y) + T.y // p'.z = (z * X'.z) + (z * Y'.z) + (z * Z'.z) + T.z // ------------------------------------------------------------ // Where: // p' is the transformed point/vector. // x is the x component/scalar of the vector. // X' is the x axis component of the Matrix4. // y is the y component/scalar of the vector. // Y' is the y axis component of the Matrix4. // z is the z component/scalar of the vector. // Z' is the z axis component of the Matrix4. // T is the translation component of the Matrix4 (W axis). // ************************************************************ Vector4 result; Vector4 xAx(0,0,0,0); Vector4 yAx(0,0,0,0); Vector4 zAx(0,0,0,0); Vector4 wAx(0,0,0,0); // xX' component of formula xAx.x = v.x * m.xX; xAx.y = v.x * m.xY; xAx.z = v.x * m.xZ; xAx.w = v.x * m.xW; // yY' component of formula yAx.x = v.y * m.yX; yAx.y = v.y * m.yY; yAx.z = v.y * m.yZ; yAx.w = v.y * m.yW; // zZ' component of formula zAx.x = v.z * m.zX; zAx.y = v.z * m.zY; zAx.z = v.z * m.zZ; zAx.w = v.z * m.zW; // wAx.x = v.w * m.wX; wAx.y = v.w * m.wY; wAx.z = v.w * m.wZ; wAx.w = v.w * m.wW; result.x = xAx.x + yAx.x + zAx.x + wAx.x; result.y = xAx.y + yAx.y + zAx.y + wAx.y; result.z = xAx.z + yAx.z + zAx.z + wAx.z; result.w = v.w; return result; }
void ClassicDescSearch( // search along whisker for best profile match double& x, // io: (in: old posn of landmark, out: new posn) double& y, // io: const Image& img, // in: the image scaled to this pyramid level const Shape& inshape, // in: current posn of landmarks (for whisker directions) int ipoint, // in: index of the current landmark const MAT& meanprof, // in: mean of the training profiles for this point const MAT& covi) // in: inverse of the covar of the training profiles { const int proflen = NSIZE(meanprof); CV_Assert(proflen % 2 == 1); // proflen must be odd in this implementation // fullprof is the 1D profile along the whisker including the extra // elements to allow search +-CLASSIC_MAX_OFFSET pixels away from // the current position of the landmark. // We precalculate the fullprof for efficiency in the for loop below. const int fullproflen = proflen + 2 * CLASSIC_MAX_OFFSET; CV_Assert(fullproflen % 2 == 1); // fullprof length must be odd const VEC fullprof(FullProf(img, inshape, ipoint, fullproflen)); // move along the whisker looking for the best match int bestoffset = 0; double mindist = FLT_MAX; for (int offset = -CLASSIC_MAX_OFFSET; offset <= CLASSIC_MAX_OFFSET; offset += CLASSIC_SEARCH_RESOL) { // Get the profile distance. That is, get the image profile at the given // offset along the whisker, and return the Mahalanobis distance between // it and the model mean profile. Low distance means good fit. const VEC prof(SubProf(offset, proflen, fullprof)); // The following code is equivalent to // dist = (prof - meanprof).t() * covi * (prof - meanprof) // but is optimized for speed. prof -= meanprof; // for efficiency, use "-=" not "=" with "-" const double dist = xAx(prof, covi); if (dist < mindist) { mindist = dist; bestoffset = offset; } } // change x,y to the best position along the whisker double xstep, ystep; WhiskerStep(xstep, ystep, inshape, ipoint); x = inshape(ipoint, IX) + (bestoffset * xstep); y = inshape(ipoint, IY) + (bestoffset * ystep); }
Vector3 Transform(const Matrix4 &m, const Vector3 &v) { // ************************************************************ // The formula to transform the vector/point is as follows: // ------------------------------------------------------------ // p' = xX' + yY' + zZ' + T // OR // p'.x = (x * X'.x) + (x * Y'.x) + (x * Z'.x) + T.x // p'.y = (y * X'.y) + (y * Y'.y) + (y * Z'.y) + T.y // p'.z = (z * X'.z) + (z * Y'.z) + (z * Z'.z) + T.z // ------------------------------------------------------------ // Where: // p' is the transformed point/vector. // x is the x component/scalar of the vector. // X' is the x axis component of the Matrix4. // y is the y component/scalar of the vector. // Y' is the y axis component of the Matrix4. // z is the z component/scalar of the vector. // Z' is the z axis component of the Matrix4. // T is the translation component of the Matrix4 (W axis). // ************************************************************ Vector3 result; Vector3 xAx(0,0,0); Vector3 yAx(0,0,0); Vector3 zAx(0,0,0); // xX' component of formula xAx.x = v.x * m.xX; xAx.y = v.x * m.xY; xAx.z = v.x * m.xZ; // yY' component of formula yAx.x = v.y * m.yX; yAx.y = v.y * m.yY; yAx.z = v.y * m.yZ; // zZ' component of formula zAx.x = v.z * m.zX; zAx.y = v.z * m.zY; zAx.z = v.z * m.zZ; // Using the above equation, we now add the components (including translation components). // This isnt a true transform as I'm cheating by simply adding on the translation component. result.x = xAx.x + yAx.x + zAx.x + m.wX; result.y = xAx.y + yAx.y + zAx.y + m.wY; result.z = xAx.z + yAx.z + zAx.z + m.wZ; return result; }