/*! * \return Coordinates of center of mass. * \brief Calculates the centre of mass of a transformed object. * \param srcObj Given object. * \param trans Given transform. * \param binObjFlag Binary object flag. * \param dstMass Destination pointer for mass, * may be NULL. * \param dstErr Destination pointer for error, * may be NULL. */ static WlzDVertex2 WlzCentreOfMassTrans2D(WlzObject *srcObj, WlzAffineTransform *trans, int binObjFlag, double *dstMass, WlzErrorNum *dstErr) { double mass; WlzDVertex2 cMass; WlzErrorNum errNum = WLZ_ERR_NONE; cMass = WlzCentreOfMass2D(srcObj, binObjFlag, &mass, &errNum); if(errNum == WLZ_ERR_NONE) { cMass = WlzAffineTransformVertexD2(trans, cMass, &errNum); } if((errNum == WLZ_ERR_NONE) && dstMass) { *dstMass = mass; } if(dstErr) { *dstErr = errNum; } return(cMass); }
/*! * \return void * \ingroup WlzAccess * \brief Gets a single grey value/pointer for the given point * from the object with which the given work space was * initialised. When the object has a non-scalar value * table then only the first value will be returned, * however when the value is not background all values * can be accessed via the grey pointer. * * \param gVWSp Grey value work space. * \param plane Plane (z) coordinate of point. * \param line Line (y) coordinate of point. * \param kol Column (x) coordinate of point. */ void WlzGreyValueGet(WlzGreyValueWSpace *gVWSp, double plane, double line, double kol) { if(gVWSp) { switch(gVWSp->objType) { case WLZ_2D_DOMAINOBJ: if(gVWSp->invTrans) { WlzDVertex2 vtx2; vtx2.vtX = kol; vtx2.vtY = line; vtx2 = WlzAffineTransformVertexD2(gVWSp->invTrans, vtx2, NULL); kol = vtx2.vtX; line = vtx2.vtY; } WlzGreyValueGet2D1(gVWSp, WLZ_NINT(line), WLZ_NINT(kol)); break; case WLZ_3D_DOMAINOBJ: if(gVWSp->invTrans) { WlzDVertex3 vtx3; vtx3.vtX = kol; vtx3.vtY = line; vtx3.vtZ = plane; vtx3 = WlzAffineTransformVertexD3(gVWSp->invTrans, vtx3, NULL); kol = vtx3.vtX; line = vtx3.vtY; plane = vtx3.vtZ; } if(gVWSp->gTabType == (WlzObjectType )WLZ_GREY_TAB_TILED) { WlzGreyValueGet3DTiled(gVWSp, WLZ_NINT(plane), WLZ_NINT(line), WLZ_NINT(kol)); } else { WlzGreyValueGet3D1(gVWSp, WLZ_NINT(plane), WLZ_NINT(line), WLZ_NINT(kol)); } break; default: break; } } }
/*! * \return New BasisFn transform. * \ingroup WlzTransform * \brief Computes a basis function transform for the given object and a * set of control points using both an affine and a basis * function transform. * \param obj Given object. * \param basisFnType Required basis function type. * \param polyOrder Order of polynomial, only used for * WLZ_FN_BASIS_2DPOLY. * \param nSPts Number of source control points. * \param sPts Source control points. * \param nDPts Number of destination control points. * \param dPts Destination control points. * \param dstErr Destination error pointer, may be * NULL. */ static WlzBasisFnTransform *WlzAffineBasisFnTransformFromCPtsT(WlzObject *obj, WlzFnType basisFnType, int polyOrder, int nSPts, WlzDVertex2 *sPts, int nDPts, WlzDVertex2 *dPts, WlzErrorNum *dstErr) { int idx; WlzDVertex2 *dPtsT = NULL; WlzAffineTransform *aTr = NULL, *aTrI = NULL; WlzBasisFnTransform *bTr = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; if(obj == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } else if((nDPts <= 0) || (nDPts != nSPts)) { errNum = WLZ_ERR_PARAM_DATA; } else if((dPts == NULL) || (sPts == NULL)) { errNum = WLZ_ERR_PARAM_NULL; } /* Compute least squares affine transform from the tie points. */ if(errNum == WLZ_ERR_NONE) { aTr = WlzAffineTransformLSq2D(nSPts, sPts, nSPts, dPts, 0, NULL, WLZ_TRANSFORM_2D_AFFINE, &errNum); } if(errNum == WLZ_ERR_NONE) { if(nSPts >= 4) { /* Create a new array of destination vertices which have the original * destination transformed by the inverse affine transform. */ if((dPtsT = (WlzDVertex2 *)AlcMalloc(sizeof(WlzDVertex2) * nSPts)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { aTrI = WlzAffineTransformInverse(aTr, &errNum); } if(errNum == WLZ_ERR_NONE) { for(idx = 0; idx < nDPts; ++idx) { dPtsT[idx] = WlzAffineTransformVertexD2(aTrI, dPts[idx], NULL); } bTr = WlzBasisFnTrFromCPts2D(basisFnType, polyOrder, nSPts, sPts, nSPts, dPtsT, NULL, &errNum); } } } AlcFree(dPtsT); (void )WlzFreeAffineTransform(aTr); (void )WlzFreeAffineTransform(aTrI); if(errNum != WLZ_ERR_NONE) { (void )WlzBasisFnFreeTransform(bTr); } if(dstErr) { *dstErr = errNum; } return(bTr); }
/*! * \return void * \ingroup WlzAccess * \brief Gets four or eight grey value/pointers for the given * point from the 2D or 3D values and domain in the work * space. * \param gVWSp Grey value work space. * \param plane Plane coordinate of point. * \param line Line coordinate of point. * \param kol Column coordinate of point. */ static void WlzGreyValueGetTransCon(WlzGreyValueWSpace *gVWSp, int plane, int line, int kol) { int idN, idX, idY, idZ; WlzDVertex2 vtx2; WlzDVertex3 vtx3; WlzGreyP gPtr[8]; WlzGreyV gVal[8]; switch(gVWSp->objType) { case WLZ_2D_DOMAINOBJ: idN = 0; for(idY = 0; idY < 2; ++idY) { for(idX = 0; idX < 2; ++idX) { vtx2.vtX = kol + idX; vtx2.vtY = line + idY; vtx2 = WlzAffineTransformVertexD2(gVWSp->invTrans, vtx2, NULL); WlzGreyValueGet2D1(gVWSp, (int )(vtx2.vtY), (int )(vtx2.vtX)); gPtr[idN] = gVWSp->gPtr[0]; gVal[idN] = gVWSp->gVal[0]; ++idN; } } for(idN = 0; idN < 4; ++idN) { gVWSp->gPtr[idN] = gPtr[idN]; gVWSp->gVal[idN] = gVal[idN]; } break; case WLZ_3D_DOMAINOBJ: idN = 0; for(idZ = 0; idZ < 2; ++idZ) { for(idY = 0; idY < 2; ++idY) { for(idX = 0; idX < 2; ++idX) { vtx3.vtX = kol + idX; vtx3.vtY = line + idY; vtx3.vtZ = plane + idZ; vtx3 = WlzAffineTransformVertexD3(gVWSp->invTrans, vtx3, NULL); if(gVWSp->gTabType == (WlzObjectType )WLZ_GREY_TAB_TILED) { WlzGreyValueGet3DTiled(gVWSp, (int )(vtx3.vtZ), (int )(vtx3.vtY), (int )(vtx3.vtX)); } else { WlzGreyValueGet3D1(gVWSp, (int )(vtx3.vtZ), (int )(vtx3.vtY), (int )(vtx3.vtX)); } gPtr[idN] = gVWSp->gPtr[0]; gVal[idN] = gVWSp->gVal[0]; ++idN; } } } for(idN = 0; idN < 8; ++idN) { gVWSp->gPtr[idN] = gPtr[idN]; gVWSp->gVal[idN] = gVal[idN]; } break; default: break; } }
/*! * - Function: outputTheWarpedWlz * - Returns: WlzVetex * - Purpose: Track vertex through neighbour layer. * - Parameters: * * -# vsp: input WlzVertex. * -# vtp: input WlzVertex. * -# wlzViewStri: WlzThreeDViewStruct for layer i; * -# wlzViewStrip1: WlzThreeDViewStruct for the next layer i+-1; * -# UpOrDown: > 0 Up; <= 0 down; * - Author: J. Rao, R. Baldock */ static WlzErrorNum outputTheWarpedWlz( WlzVertex vsp, WlzVertex vtp, WlzVertex vfp, WlzDVertex2 *vtxVec1, char *souce2DWlzStr, char *out2DWlzStr ) { WlzAffineTransform *trans=NULL; WlzTransformType tType = WLZ_TRANSFORM_2D_AFFINE; WlzDVertex2 *vtxVec0; WlzDVertex2 sv, tv; WlzObject *sObj=NULL, *tObj=NULL; FILE *inFile; WlzErrorNum errNum = WLZ_ERR_NONE; WlzInterpolationType interp = WLZ_INTERPOLATION_LINEAR; /* Use the nearest neighbour */ /*------- allocate memory --------*/ if ( ((vtxVec0 = (WlzDVertex2 *)AlcCalloc(sizeof(WlzDVertex2), 3)) == NULL) ) { errNum = WLZ_ERR_MEM_ALLOC; } if( errNum == WLZ_ERR_NONE ) { (vtxVec0)->vtX = vsp.d3.vtX; (vtxVec0)->vtY = vsp.d3.vtY; (vtxVec0 + 1)->vtX = vtp.d3.vtX; (vtxVec0 + 1)->vtY = vtp.d3.vtY; (vtxVec0 + 2)->vtX = vfp.d3.vtX; (vtxVec0 + 2)->vtY = vfp.d3.vtY; trans = WlzAffineTransformLSq2D(3, vtxVec1, 3, vtxVec0, 0, NULL, tType, &errNum); /* trans = WlzAffineTransformLSq2D(3, vtxVec0, 3, vtxVec1, 0, NULL, tType, &errNum); */ } if( errNum == WLZ_ERR_NONE ) { /* check whether it is right or not */ sv.vtX = (vtxVec0)->vtX; sv.vtY = (vtxVec0)->vtY; printf("compare\n"); printf("first one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1)->vtX, (vtxVec1)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); sv.vtX = (vtxVec0 + 1)->vtX; sv.vtY = (vtxVec0 + 1)->vtY; printf("second one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1 + 1)->vtX, (vtxVec1 + 1)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); sv.vtX = (vtxVec0 + 2)->vtX; sv.vtY = (vtxVec0 + 2)->vtY; printf("third one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1 + 2)->vtX, (vtxVec1 + 2)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); } if( errNum == WLZ_ERR_NONE ) { /* read Woolz object */ if((inFile = fopen(souce2DWlzStr, "r")) == NULL ) { printf("cannot open the input woolz file.\n"); exit(1); } if( !( sObj = WlzReadObj(inFile, &errNum) ) ) { printf("input Woolz Object Error.\n"); fclose(inFile); exit(1); } fclose(inFile); inFile = NULL; } if( errNum == WLZ_ERR_NONE ) { tObj = WlzAffineTransformObj(sObj, trans, interp, &errNum ); } if( errNum == WLZ_ERR_NONE ) { /* write Woolz object */ if((inFile = fopen(out2DWlzStr, "w")) == NULL ) { printf("cannot open the output woolz file.\n"); exit(1); } errNum = WlzWriteObj(inFile, tObj); if( errNum != WLZ_ERR_NONE ) { printf("input Woolz Object Error.\n"); fclose(inFile); exit(1); } fclose(inFile); inFile = NULL; } WlzFreeObj(sObj); WlzFreeObj(tObj); AlcFree(vtxVec0 ); AlcFree(trans); return errNum; }