Пример #1
0
RecError        RecSecListRelFromAbs(RecSectionList *secList)
{
  RecSection	*sec;
  HGUDlpListItem *item;
  WlzAffineTransform *tr0 = NULL,
  		*tr1,
		*tr2;
  RecError	recErr = REC_ERR_NONE;
  WlzErrorNum	wlzErr = WLZ_ERR_NONE;

  if(secList == NULL)
  {
    recErr = REC_ERR_FUNC;
  }
  else if(secList->attributes.trMode == REC_TRMODE_ABS)
  {
    item = HGUDlpListHead(secList->list);
    do
    {
      sec = (RecSection *)HGUDlpListEntryGet(secList->list, item);
      if(sec && strcmp(sec->imageFile, "empty"))
      {
        if(tr0)
	{
	  tr1 = WlzAffineTransformInverse(tr0, &wlzErr);
	  if(wlzErr == WLZ_ERR_NONE)
	  {
	    (void )WlzFreeAffineTransform(tr0);
	    tr0 = WlzAssignAffineTransform(sec->transform, NULL);
	    tr2 = WlzAffineTransformProduct(tr0, tr1, &wlzErr);
	  }
	  if(wlzErr == WLZ_ERR_NONE)
	  {
	    (void )WlzTransformNearIdentity2D(tr2, 1.0e-6);
	    (void )WlzFreeAffineTransform(sec->transform);
	    sec->transform = WlzAssignAffineTransform(tr2, NULL);
	  }
	}
	else
	{
	  tr0 = WlzAssignAffineTransform(sec->transform, NULL);
	}
      }
      item = HGUDlpListNext(secList->list, item);
    } while((wlzErr == WLZ_ERR_NONE) && item &&
            (item != HGUDlpListHead(secList->list)));
    if(tr0)
    {
      (void )WlzFreeAffineTransform(tr0);
    }
    secList->attributes.trMode = REC_TRMODE_REL;
    recErr = RecErrorFromWlz(wlzErr);
  }
  return(recErr);
}
Пример #2
0
RecError	RecSecListAbsFromRel(RecSectionList *secList)
{
  RecSection	*sec;
  HGUDlpListItem *item;
  WlzAffineTransform *tr0 = NULL,
  		*tr1;
  RecError	recErr = REC_ERR_NONE;
  WlzErrorNum	wlzErr = WLZ_ERR_NONE;

  if(secList == NULL)
  {
    recErr = REC_ERR_FUNC;
  }
  else if(secList->attributes.trMode == REC_TRMODE_REL)
  {
    item = HGUDlpListHead(secList->list);
    do
    {
      sec = (RecSection *)HGUDlpListEntryGet(secList->list, item);
      if(sec && strcmp(sec->imageFile, "empty"))
      {
	if(tr0)
	{
	  tr1 = WlzAffineTransformProduct(sec->transform, tr0, &wlzErr);
	  if(wlzErr == WLZ_ERR_NONE)
	  {
	    (void )WlzFreeAffineTransform(sec->transform);
	    sec->transform = WlzAssignAffineTransform(tr1, NULL);
	  }
	  tr0 = tr1;
	}
	else
	{
	  tr0 = sec->transform;
	}
      }
      item = HGUDlpListNext(secList->list, item);
    } while((wlzErr == WLZ_ERR_NONE) && item &&
            (item != HGUDlpListHead(secList->list)));
    secList->attributes.trMode = REC_TRMODE_ABS;
    recErr = RecErrorFromWlz(wlzErr);
  }
  return(recErr);
}
Пример #3
0
/*!
* \return	Affine transform which brings the two objects into register.
* \ingroup	WlzRegistration
* \brief	Registers the two given 2D domain objects using a
*               frequency domain cross correlation.  An affine transform
*               is computed, which when applied to the source object
*               takes it into register with the target object.
* \param	tObj			The target object. Must have
*                                       been assigned.
* \param	sObj			The source object to be
*                                       registered with target object.
* \param	initTr			Initial affine transform
*                                       to be applied to the source
*                                       object prior to registration.
*                                       Only translations in x and y
*                                       and rotation about the z axis
*                                       are used. May be NULL which is
*                                       equivalent to an identity transform.
* \param	trType			Required transform type.
* \param	maxTran			Maximum translation.
* \param	maxRot			Maximum rotation.
* \param	maxItr			Maximum number of iterations,
*                                       if \f$\leq\f$ 0 then infinite
					iterations are allowed.
* \param	winFn			Window function.
* \param	noise			Use Gaussian noise if non-zero.
* \param	dstConv			Destination ptr for the
*                                       convergence flag (non zero
*                                       on convergence), may be NULL.
* \param	dstCCor			Destination ptr for the cross
*                                       correlation value, may be NULL.
* \param	dstErr			Destination error pointer,
*                                       may be NULL.
*/
static WlzAffineTransform *WlzRegCCorObjs2D1(WlzObject *tObj, WlzObject *sObj,
					     WlzAffineTransform *initTr,
					     WlzTransformType trType,
					     WlzDVertex2 maxTran,
					     double maxRot, int maxItr,
					     WlzWindowFnType winFn, int noise,
					     int *dstConv, double *dstCCor, 
					     WlzErrorNum *dstErr)
{
  int		itr,
		conv;
  WlzAffineTransform *tTr0 = NULL,
  		*tTr1 = NULL,
		*curTr = NULL,
		*regTr = NULL;
  double	rot,
		lastRot,
  		cCor;
  WlzDVertex2	tran;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const double	tranTol = 0.5;

  /* Register for translation. */
  tran = WlzRegCCorObjs2DTran(tObj, sObj, initTr, maxTran, winFn, noise,
  			      &cCor, &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
    					 tran.vtX, tran.vtY, 0.0,
					 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0,
					 &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    curTr = WlzAffineTransformProduct(initTr, tTr0, &errNum);
    (void )WlzFreeAffineTransform(tTr0); tTr0 = NULL;
  }
  if(trType == WLZ_TRANSFORM_2D_TRANS)
  {
    conv = 1;
  }
  else /* trType == WLZ_TRANSFORM_2D_REG */
  {
    /* Iterate until translation is less tahn tollerance value or
     * number of itterations exceeds the maximum. */
    itr = 0;
    rot = 0.0;
    lastRot = 1.0;
    /* The convergence test must only test the translation and not the
     * rotation too, as the rotation has already been applied when
     * finding the translation. */
    while((errNum == WLZ_ERR_NONE) &&
	  ((conv = (fabs(tran.vtX) <= tranTol) &&
	           (fabs(tran.vtY) <= tranTol)) == 0) &&
	  ((maxItr < 0) || (itr++ < maxItr)))
    {
      /* Register for rotation. */
      lastRot = rot;
      rot = WlzRegCCorObjs2DRot(tObj, sObj, curTr, 
				maxRot, winFn, noise, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					     0.0, 0.0, 0.0,
					     1.0, rot, 0.0, 0.0, 0.0, 0.0, 0,
					     &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	tTr1 = WlzAffineTransformProduct(curTr, tTr0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	(void )WlzFreeAffineTransform(tTr0); tTr0 = NULL;
	(void )WlzFreeAffineTransform(curTr);
	curTr = tTr1; tTr1 = NULL;
      }
      /* Register for translation. */
      if(errNum == WLZ_ERR_NONE)
      {
	tran = WlzRegCCorObjs2DTran(tObj, sObj, curTr, maxTran, winFn, noise,
				    &cCor, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					     tran.vtX, tran.vtY, 0.0,
					     1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0,
					     &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	tTr1 = WlzAffineTransformProduct(curTr, tTr0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	(void )WlzFreeAffineTransform(tTr0); tTr0 = NULL;
	(void )WlzFreeAffineTransform(curTr);
	curTr = tTr1; tTr1 = NULL;
      }
    }
    (void )WlzFreeAffineTransform(tTr0);
    (void )WlzFreeAffineTransform(tTr1);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    regTr = curTr;
    if(dstConv)
    {
      *dstConv = conv;
    }
    if(dstCCor)
    {
      *dstCCor = cCor;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(regTr);
}
Пример #4
0
int main(int	argc,
	 char	**argv)
{
  FILE		*inFile1=NULL, *inFile2=NULL;
  char 		optList[] = "AR123f:F:iIx:y:z:s:a:b:u:v:w:hV";
  int		option;
  int		trans1RelFlg=0, trans2RelFlg=0, trans3DFlg=0, outputRelFlg=0;
  int		invertFlg=0, inverseFlg=0, threeDFlg=0;
  WlzAffineTransform	*cmdLineTrans=NULL;
  double	tx, ty, tz, scale, theta, phi, alpha, psi, xsi;
  int		verboseFlg=0;
  RecSectionList	recSecList1, recSecList2;
  RecSectionList	*secList1=&recSecList1, *secList2=&recSecList2;
  HGUDlpListItem	*listItem, *listItem1;
  RecSection	*sec, *sec1;
  char		*errMsg = NULL;
  RecError	errFlg = REC_ERR_NONE;
  int		numSec1, numSec2;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*transformsObj1, *transformsObj2;
  int		p, i, ip;
  WlzAffineTransform	*newTransform, *tmpTrans, *tmp1Trans, *reconTrans;

  /* default transform */
  tx = 0.0;
  ty = 0.0;
  tx = 0.0;
  scale = 1.0;
  theta = 0.0;
  phi = 0.0;
  alpha = 0.0;
  psi = 0.0;
  xsi = 0.0;

  /* parse the command line */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'A':
      outputRelFlg = 0;
      break;

    case 'R':
      outputRelFlg = 1;
      break;

    case '1':
      trans1RelFlg = 1;
      break;

    case '2':
      trans2RelFlg = 1;
      break;

    case '3':
      trans3DFlg = 1;
      break;

    case 'f':
      if( (optarg != NULL) && (strlen(optarg) > 0) ){
	if( (inFile1 = fopen(optarg, "r")) == NULL ){
	  fprintf(stderr, "%s: failed to open input file %s\n",
		  argv[0], optarg);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'F':
      if( (optarg != NULL) && (strlen(optarg) > 0) ){
	if( (inFile2 = fopen(optarg, "r")) == NULL ){
	  fprintf(stderr, "%s: failed to open input file %s\n",
		  argv[0], optarg);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'i':
      invertFlg = 1;
      break;

    case 'I':
      inverseFlg = 1;
      break;

    case 'a':
      if(sscanf(optarg, "%lg", &theta) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'b':
      if(sscanf(optarg, "%lg", &phi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 's':
      if(sscanf(optarg, "%lg", &scale) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'u':
      if(sscanf(optarg, "%lg", &alpha) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'v':
      if(sscanf(optarg, "%lg", &psi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'w':
      if(sscanf(optarg, "%lg", &xsi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'x':
      if(sscanf(optarg, "%lg", &tx) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

     case 'y':
      if(sscanf(optarg, "%lg", &ty) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'z':
      if(sscanf(optarg, "%lg", &tz) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'V':
      verboseFlg = 1;
      break;

    case 'h':
    default:
      usage(argv[0]);
      return 1;

    }
  }

  /* create the command line transform */
  if( threeDFlg ){
    cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_3D_AFFINE,
					      tx, ty, tz, scale, theta, phi,
					      alpha, psi, xsi,
					      invertFlg, &errNum);
  }
  else {
     cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					      tx, ty, tz, scale, theta, phi,
					      alpha, psi, xsi,
					      invertFlg, &errNum);
  }

  /* check for files on the command line */
  if( (inFile1 == NULL) && (optind < argc) ){
    if( (inFile1 = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    optind++;
  }
  if( (inFile2 == NULL) && (optind < argc) ){
    if( (inFile2 = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    optind++;
  }

  /* now read the transforms, in each case the logic is that
     transform 1 is applied then transform 2 then the command line
     transform. If transform 1 is a reconstruct bib file then the
     output will include the file information. Note in this case
     the output transform will be absolute unless specified on the
     command line */

  /* transform 1 - try to read as a Reconstruct file, on failure
     rewind and read as an MAPaint file */
  if( inFile1 != NULL ){
    errFlg = RecFileSecListRead(secList1, &numSec1, inFile1, &errMsg);
    if( errFlg == REC_ERR_NONE ){
      /* check transform attribute */
      switch( secList1->attributes.trMode ){
      case REC_TRMODE_REL:
	trans1RelFlg = 1;
	break;
      case REC_TRMODE_ABS:
	trans1RelFlg = 0;
	break;
      }
      transformsObj1 = SecListToTransforms(secList1, trans1RelFlg, &errNum);
    }
    else {
      secList1 = NULL;
      rewind(inFile1);
      transformsObj1 = ReadMAPaintRealignTransforms(inFile1, &errNum);
    }
  }
  else {
    fprintf(stderr, "%s: a file for transform 1 must be defined\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  /* transform 2 - try to read as a Reconstruct file, on failure
     rewind and read as an MAPaint file */
  if( inFile2 != NULL ){
    errFlg = RecFileSecListRead(secList2, &numSec2, inFile2, &errMsg);
    if( errFlg == REC_ERR_NONE ){
      /* check transform attribute */
      switch( secList2->attributes.trMode ){
      case REC_TRMODE_REL:
	trans2RelFlg = 1;
	break;
      case REC_TRMODE_ABS:
	trans2RelFlg = 0;
	break;
      }
      transformsObj2 = SecListToTransforms(secList2, trans2RelFlg, &errNum);
    }
    else {
      secList2 = NULL;
      rewind(inFile2);
      transformsObj2 = ReadMAPaintRealignTransforms(inFile2, &errNum);
    }
  }
  else {
    transformsObj2 = NULL;
  }

  /* form the plane by plane product of the transforms,
     note the output will be of the planes in transform 1 */
  for(p=transformsObj1->domain.p->plane1, i=0;
      p <= transformsObj1->domain.p->lastpl; p++, i++){

    /* get the existing transform */
    if( transformsObj1->domain.p->domains[i].t ){
      newTransform =
	WlzAssignAffineTransform(transformsObj1->domain.p->domains[i].t,
				 NULL);
    }
    else {
      newTransform = NULL;
    }

    /* check for transform 2 */
    if(newTransform && transformsObj2 &&
       (p >= transformsObj2->domain.p->plane1) &&
       (p <= transformsObj2->domain.p->lastpl) &&
       (transformsObj2->domain.p->
	domains[p-transformsObj2->domain.p->plane1].t)){
      tmpTrans =
	WlzAffineTransformProduct(newTransform,
				  transformsObj2->domain.p->
				  domains[p-transformsObj2->domain.p->plane1].t,
				  NULL);
      WlzFreeAffineTransform(newTransform);
      newTransform = tmpTrans;
    }

    /* apply the command line transform */
    if( newTransform && cmdLineTrans ){
      tmpTrans = WlzAffineTransformProduct(newTransform, cmdLineTrans, NULL);
      WlzFreeAffineTransform(newTransform);
      newTransform = tmpTrans;
    }

    /* put it back into transformsObj1 */
    if( transformsObj1->domain.p->domains[i].t ){
      WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
    }
    transformsObj1->domain.p->domains[i].t =
      WlzAssignAffineTransform(newTransform, NULL);
  }

  /* if there is a section list in Reconstruct form
     then take out the reconstruct transform */
  if( secList1 ){
    /* take out the reconstruct transform first */
    reconTrans = WlzAffineTransformFromPrimVal
      (WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0,
       1.0 / secList1->reconstruction.scale.vtX,
       0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL);
    listItem = HGUDlpListHead(secList1->list);
    while( listItem ){
      sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
      if( sec ){
	p = sec->index;
	i = p - transformsObj1->domain.p->plane1;
	if( transformsObj1->domain.p->domains[i].t ){
	  tmpTrans = WlzAffineTransformProduct
	    (transformsObj1->domain.p->domains[i].t, reconTrans, NULL);
	  WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	  transformsObj1->domain.p->domains[i].t =
	    WlzAssignAffineTransform(tmpTrans, NULL);
	}
      }
      listItem = HGUDlpListNext(secList1->list, listItem);
    }

  }

  /* check for relative flag */
  if( outputRelFlg ){
    /* use the section list if available */
    if( secList1 ){

      /* sort out the relative transform */
      listItem = HGUDlpListTail(secList1->list);
      while( listItem != HGUDlpListHead(secList1->list) ){
	sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
	if( sec ){
	  p = sec->index;
	  i = p - transformsObj1->domain.p->plane1;
	  if( strncmp(sec->imageFile, "empty", 5) == 0 ){
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    transformsObj1->domain.p->domains[i].t =
	      WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					 0.0, 0.0, 0.0, 1.0,
					 0.0, 0.0, 0.0, 0.0,
					 0.0, 0, NULL);
	  }
	  else {
	    /* walk backwards to previous non-empty section */
	    listItem1 = HGUDlpListPrev(secList1->list, listItem);
	    while( listItem1 != HGUDlpListHead(secList1->list) ){
	      sec1 = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem1);
	      if( strncmp(sec1->imageFile, "empty", 5) ){
		break;
	      }
	      listItem1 = HGUDlpListPrev(secList1->list, listItem1);
	    }
	    ip = sec1->index - transformsObj1->domain.p->plane1;
	    tmpTrans =
	      WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t,
					NULL);
	    tmp1Trans = WlzAffineTransformProduct(
	      transformsObj1->domain.p->domains[i].t,
	      tmpTrans, NULL);
	    checkTrans(tmp1Trans);
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    WlzFreeAffineTransform(tmpTrans);
	    transformsObj1->domain.p->domains[i].t = tmp1Trans;
	  }
	}
	listItem = HGUDlpListPrev(secList1->list, listItem);
      }
    }
    else {
      i = transformsObj1->domain.p->lastpl - transformsObj1->domain.p->plane1;
      ip = i;
      for(p = transformsObj1->domain.p->lastpl;
	  p >= transformsObj1->domain.p->plane1; p--, i--){
	if( i > ip ){
	  continue;
	}
	ip--;
	if(transformsObj1->domain.p->domains[i].t){
	  /* jump over any NULL transforms */
	  while((ip >= 0) &&
		(transformsObj1->domain.p->domains[ip].t == NULL)){
	      ip--;
	  }

	  /* push the transform down the line */
	  if(ip >= 0){
	    tmpTrans =
	      WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t,
					NULL);
	    tmp1Trans =
	      WlzAffineTransformProduct(transformsObj1->domain.p->domains[i].t,
					tmpTrans,
					NULL);
	    checkTrans(tmp1Trans);
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    WlzFreeAffineTransform(tmpTrans);
	    transformsObj1->domain.p->domains[i].t =
	      WlzAssignAffineTransform(tmp1Trans, NULL);
	  }
	}
      }
    }
  }

  /* if there is a section list one then output in Reconstruct
     bibfile format else MAPaint style */
  if( secList1 ){
    /* set the relative/absolute attribute */
    if( outputRelFlg ){
      secList1->attributes.trMode = REC_TRMODE_REL;
    }
    else {
      secList1->attributes.trMode = REC_TRMODE_ABS;
    }

    /* put back the transforms */
    listItem = HGUDlpListHead(secList1->list);
    while( listItem ){
      sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
      p = sec->index;
      i = p - transformsObj1->domain.p->plane1;

      /* check for NULL transform */
      if( transformsObj1->domain.p->domains[i].t == NULL ){
	transformsObj1->domain.p->domains[i].t =
	  WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
				     0.0, 0.0, 0.0, 1.0,
				     0.0, 0.0, 0.0, 0.0,
				     0.0, 0, NULL);
      }

      sec->transform = 
	transformsObj1->domain.p->domains[i].t;
      
      listItem = HGUDlpListNext(secList1->list, listItem);
    }
    RecFileSecListWrite(stdout, secList1, numSec1, &errMsg);
  }
  else {
    WriteMAPaintRealignTransforms(stdout, transformsObj1, outputRelFlg);
  }

  return 0;
}
Пример #5
0
WlzObject *SecListToTransforms(
  RecSectionList	*secList,
  int		relFlg,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  int		i, p, pMin, pMax;
  WlzDomain	domain;
  WlzValues	values;
  RecSection	*sec;
  HGUDlpListItem	*listItem;
  WlzAffineTransform	*recTrans, *tmpTrans;

  /* sort the section list and find the section range */
  RecSecListSort(secList->list, REC_SECMSK_INDEX);

  /* calculate the cumulative transforms */
  listItem = HGUDlpListTail(secList->list);
  if( relFlg ){
    RecSecCumTransfSet(secList->list, listItem);
  }

  /* define the reconstruct transform */
  recTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					   0.0, 0.0, 0.0,
					   secList->reconstruction.scale.vtX,
					   0.0, 0.0, 0.0, 0.0,
					   0.0, 0, NULL);

  /* create the transforms object */
  listItem = HGUDlpListHead(secList->list);
  sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
  pMin = sec->index;
  listItem = HGUDlpListTail(secList->list);
  sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
  pMax = sec->index;
  if( errNum == WLZ_ERR_NONE ){
    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_AFFINE,
				      pMin, pMax, 0, 0, 0, 0,
				      &errNum)) != NULL){
      values.core = NULL;
      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ,
			   domain, values, NULL, NULL, &errNum);
    }
  }

  /* now put in the transforms */
  listItem = HGUDlpListHead(secList->list);
  while( listItem ){
    sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
    p = sec->index;
    i = p - rtnObj->domain.p->plane1;
    if( relFlg ){
      if( sec->cumTransform == NULL ){
	rtnObj->domain.p->domains[i].t =
	  WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
				        0.0, 0.0, 0.0, 1.0,
				        0.0, 0.0, 0.0, 0.0,
				        0.0, 0, NULL);
      }
      else {
	rtnObj->domain.p->domains[i].t =
	  WlzAssignAffineTransform(sec->cumTransform, NULL);
      }
    }
    else {
      rtnObj->domain.p->domains[i].t =
	WlzAssignAffineTransform(sec->transform, NULL);
    }

    /* apply the reconstruct transform */
    tmpTrans = WlzAffineTransformProduct(rtnObj->domain.p->domains[i].t,
					 recTrans, NULL);
    WlzFreeAffineTransform(rtnObj->domain.p->domains[i].t);
    rtnObj->domain.p->domains[i].t = WlzAssignAffineTransform(tmpTrans, NULL);

    listItem = HGUDlpListNext(secList->list, listItem);
  }

  WlzFreeAffineTransform(recTrans);

  if( dstErr ){
    *dstErr = errNum;
  }
  if( (errNum != WLZ_ERR_NONE) && rtnObj ){
    WlzFreeObj(rtnObj);
    rtnObj = NULL;
  }
  return rtnObj;
}
Пример #6
0
/*!
* \return	Grey value work space or NULL on error.
* \ingroup	WlzAccess
* \brief	Creates a grey value work space from the given object.
*		The resulting grey value work space should be freed
*		using WlzGreyValueFreeWSp().
* \param	obj			Given object.
* \param	dstErrNum		Destination error pointer, may be NULL.
*/
WlzGreyValueWSpace *WlzGreyValueMakeWSp(WlzObject *obj,
					WlzErrorNum *dstErrNum)
{
  int		planeIdx, numPlanes;
  WlzDomain	*planeDomains;
  WlzValues	*planeValues;
  WlzObjectType	gTabType0,
	        gTabType1 = WLZ_DUMMY_ENTRY;
  WlzGreyType	gType0 = WLZ_GREY_ERROR,
		gType1 = WLZ_GREY_ERROR;
  WlzPixelV	bkdPix;
  WlzAffineTransform *trans0,
  		*trans1;
  WlzGreyValueWSpace *gVWSp = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  bkdPix.v.ubv = 0;
  bkdPix.type = WLZ_GREY_INT;
  WLZ_DBG((WLZ_DBG_LVL_1),
  	   ("WlzGreyValueMakeWSp FE %p %p\n",
	    obj, dstErrNum));
  if(obj == NULL)
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else
  {
    switch(obj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else if(obj->values.core == NULL)
	{
	  errNum = WLZ_ERR_VALUES_NULL;
	}
	else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1,
					  sizeof(WlzGreyValueWSpace))) == NULL)
	{
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else
	{
	  gVWSp->objType = obj->type;
	  gVWSp->values = obj->values;
	  gVWSp->gType = WlzGreyTableTypeToGreyType(obj->values.core->type,
	  					    &errNum);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    gVWSp->gTabType = WlzGreyTableTypeToTableType(
	    				obj->values.core->type,
					&errNum);
	    gVWSp->gTabType2D = gVWSp->gTabType;
	  }
	  if(errNum == WLZ_ERR_NONE)
	  {
	    switch(gVWSp->gTabType2D)
	    {
	      case WLZ_GREY_TAB_RAGR:
	        gVWSp->values2D = obj->values;
		bkdPix = gVWSp->values2D.v->bckgrnd;
		break;
	      case WLZ_GREY_TAB_RECT:
	        gVWSp->values2D = obj->values;
		bkdPix = gVWSp->values2D.r->bckgrnd;
		break;
	      case WLZ_GREY_TAB_INTL:
	        gVWSp->values2D = obj->values;
		bkdPix = gVWSp->values2D.i->bckgrnd;
		break;
	      case WLZ_GREY_TAB_TILED:
	        gVWSp->values2D = obj->values;
		bkdPix = gVWSp->values2D.t->bckgrnd;
		break;
	      default:
		errNum = WLZ_ERR_VALUES_TYPE;
		break;
	    }
	  }
	  if(errNum == WLZ_ERR_NONE)
	  {
	    switch(gVWSp->gType)
	    {
	      case WLZ_GREY_LONG:
	      case WLZ_GREY_INT:
	      case WLZ_GREY_SHORT:
	      case WLZ_GREY_UBYTE:
	      case WLZ_GREY_FLOAT:
	      case WLZ_GREY_DOUBLE:
	      case WLZ_GREY_RGBA:
		break;
	      default:
		errNum = WLZ_ERR_GREY_TYPE;
		break;
	    }
	  }
	  if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE))
	  {
	    errNum = WLZ_ERR_VALUES_DATA;
	  }
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  gVWSp->gBkd = bkdPix.v;
	  gVWSp->domain = obj->domain;
	  gVWSp->iDom2D = obj->domain.i;
	  if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) &&
	     (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT))
	  {
	    errNum = WLZ_ERR_DOMAIN_TYPE;
	  }
	}
	break;
      case WLZ_3D_DOMAINOBJ:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else if(obj->values.core == NULL)
	{
	  errNum = WLZ_ERR_VALUES_NULL;
	}
	else if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN)
	{
	  errNum = WLZ_ERR_DOMAIN_TYPE;
	}
	else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1,
					  sizeof(WlzGreyValueWSpace))) == NULL)
	{
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else
	{
	  gVWSp->objType = obj->type;
	  gVWSp->domain = obj->domain;
	  gVWSp->values = obj->values;
	  if(WlzGreyTableIsTiled(obj->values.core->type) == WLZ_GREY_TAB_TILED)
	  {
	    gVWSp->gTabType = WLZ_GREY_TAB_TILED;
	    gVWSp->gTabType2D = WLZ_GREY_TAB_TILED;
	    gVWSp->gType = WlzGreyTableTypeToGreyType(
	        obj->values.core->type, &errNum);
	    gVWSp->plane = obj->domain.p->plane1;
	    gVWSp->iDom2D = (*(obj->domain.p->domains)).i;
	    gVWSp->gBkd = obj->values.t->bckgrnd.v;
	    if(obj->values.t->bckgrnd.type != gVWSp->gType)
	    {
	      errNum = WLZ_ERR_VALUES_DATA;
	    }
	  }
	  else
	  {
	    gVWSp->gTabType = WLZ_VOXELVALUETABLE_GREY;
	    /* Put in a list of grey-table types - purely for efficiency
	       to avoid re-computing the type for each voxel request.
	       When table types are no longer computed this in principle
	       could go */
	    numPlanes = obj->domain.p->lastpl - obj->domain.p->plane1 + 1;
	    if((gVWSp->gTabTypes3D = (WlzObjectType *)
			  AlcCalloc(numPlanes, sizeof(WlzObjectType))) == NULL)
	    {
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      WlzObjectType	*gTabTypes3D;

	      gVWSp->values2D.core = NULL;
	      planeIdx = obj->domain.p->plane1;
	      planeDomains = obj->domain.p->domains;
	      planeValues = obj->values.vox->values;
	      gTabTypes3D = gVWSp->gTabTypes3D;
	      while((planeIdx <= obj->domain.p->lastpl) &&
		    (errNum == WLZ_ERR_NONE))
	      {
		if(((*planeValues).core) &&
		   ((*planeValues).core->type != WLZ_EMPTY_OBJ))
		{
		  gType0 = WlzGreyTableTypeToGreyType(
		      (*planeValues).core->type, &errNum);
		  if(errNum == WLZ_ERR_NONE)
		  {
		    gTabType0 = WlzGreyTableTypeToTableType((*planeValues).
			                                    core->type,
							    &errNum);
		    *gTabTypes3D = gTabType0;
		  }
		  if(errNum == WLZ_ERR_NONE)
		  {
		    if((gType0 != gType1) && (gType1 != WLZ_GREY_ERROR))
		    {
		      errNum = WLZ_ERR_VALUES_DATA;
		    }
		    else
		    {
		      gType1 = gType0;
		      gTabType1 = gTabType0;
		      if(gVWSp->values2D.core == NULL)
		      {
			gVWSp->plane = planeIdx;
			gVWSp->iDom2D = (*planeDomains).i;
			gVWSp->values2D = *planeValues;
		      }
		    }
		  }
		}
		++planeIdx;
		++planeDomains;
		++planeValues;
		++gTabTypes3D;
	      }
	      if((gType1 == WLZ_GREY_ERROR) || (gTabType1 == WLZ_DUMMY_ENTRY))
	      {
		errNum = WLZ_ERR_VALUES_DATA;
	      }
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      gVWSp->gType = gType0;
	      gVWSp->gTabType2D = gVWSp->gTabTypes3D[0];
	      switch(gVWSp->gTabType2D)
	      {
		case WLZ_GREY_TAB_RAGR:
		  bkdPix = gVWSp->values2D.v->bckgrnd;
		  break;
		case WLZ_GREY_TAB_RECT:
		  bkdPix = gVWSp->values2D.r->bckgrnd;
		  break;
		case WLZ_GREY_TAB_INTL:
		  bkdPix = gVWSp->values2D.i->bckgrnd;
		  break;
		case WLZ_GREY_TAB_TILED:
		  bkdPix = gVWSp->values2D.t->bckgrnd;
		  break;
		default:
		  errNum = WLZ_ERR_VALUES_TYPE;
		  break;
	      }
	      if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE))
	      {
		errNum = WLZ_ERR_VALUES_DATA;
	      }
	      else if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) &&
		      (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT))
	      {
		errNum = WLZ_ERR_DOMAIN_TYPE;
	      }
	      else
	      {
		gVWSp->gBkd = bkdPix.v;
	      }
	    }
	  }
	}
	break;
      case WLZ_TRANS_OBJ:
	trans0 = NULL;
	while((errNum == WLZ_ERR_NONE) && (obj->type == WLZ_TRANS_OBJ))
	{
	  if(trans0 == NULL)
	  {
	    trans0 = WlzAffineTransformCopy(obj->domain.t, &errNum);
	  }
	  else
	  {
	    if((trans1 = WlzAffineTransformProduct(trans0, obj->domain.t,
	    				           &errNum)) != NULL)
	    {
	      WlzFreeAffineTransform(trans0);
	      trans0 = trans1;
	      trans1 = NULL;
	    }
	  }
	  if((obj = obj->values.obj) == NULL)
	  {
	    errNum = WLZ_ERR_OBJECT_NULL;
	  }
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  gVWSp = WlzGreyValueMakeWSp(obj, &errNum);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  gVWSp->invTrans = WlzAffineTransformInverse(trans0, &errNum);
	}
	if(trans0)
	{
	  WlzFreeAffineTransform(trans0);
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if((errNum != WLZ_ERR_NONE) && (gVWSp != NULL))
  {
    WlzGreyValueFreeWSp(gVWSp);
    gVWSp = NULL;
  }
  if(dstErrNum)
  {
    *dstErrNum = errNum;
  }
  WLZ_DBG((WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1),
  	  ("WlzGreyValueMakeWSp FX %p\n",
	   gVWSp));
  return(gVWSp);
}
Пример #7
0
/*!
* \return	Non-zero to continue iteration.
* \ingroup	Reconstruct
* \brief	Iterated function which sets the cumulative transform
*               fields of a section list, working from the head of the
*               list towards the tail and stoping when the specified
*               list item has been processed.
* \param	secList			Given section list.
* \param	secItem			Given section item.
* \param	itData			Used to pass item to stop at.
*/
static int	RecSecCumTransfSetItFn(HGUDlpList *secList,
					 HGUDlpListItem *secItem,
					void *itData)
{
  int		iterate = 0;
  HGUDlpListItem *prevItem,
  		*stopItem;
  WlzAffineTransform	*cumTransf = NULL;
  RecSection	*curSec,
  		*prevSec;
  WlzAffineTransformPrim prim;

  REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2),
          ("RecSecCumTransfSetItFn FE 0x%lx 0x%lx 0x%lx\n",
	   (unsigned long )secList, (unsigned long )secItem,
	   (unsigned long )itData));
  if(secList && secItem && itData)
  {
    stopItem = (HGUDlpListItem *)itData;
    curSec = (RecSection *)HGUDlpListEntryGet(secList, secItem);
    if(curSec && curSec->transform)		/* Should always be true */
    {
      if(HGUDlpListItemIsHead(secList, secItem))
      {
	if(curSec->cumTransform == NULL)
	{
	  curSec->cumTransform = curSec->transform;
	  ++(curSec->cumTransform->linkcount);
	}
	cumTransf = curSec->cumTransform;
      }
      else
      {
	if(curSec->cumTransform == NULL)
	{
	  prevItem = HGUDlpListPrev(secList, secItem);
	  prevSec = (RecSection *)HGUDlpListEntryGet(secList, prevItem);
	  if(prevSec && prevSec->cumTransform)      /* Should always be true */
	  {
	    cumTransf = WlzAffineTransformProduct(curSec->transform,
	    					  prevSec->cumTransform,
						  NULL);
	    curSec->cumTransform = cumTransf;
	    ++(curSec->cumTransform->linkcount);
	  }
	}
	else
	{
	  cumTransf = curSec->cumTransform;
	}
      }
      REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2),
	      ("RecSecCumTransfSetItFn 02 0x%lx\n",
	       (unsigned long )cumTransf));
      if(cumTransf)
      {
	(void )WlzAffineTransformPrimGet(cumTransf, &prim);
	REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_3),
		("RecSecCumTransfSetItFn 02 %d %g %g %g %g %g %g %g %g %g %d\n",
		 cumTransf->type,
		 prim.tx,
		 prim.ty,
		 prim.tz,
		 prim.scale,
		 prim.theta,
		 prim.phi,
		 prim.alpha,
		 prim.psi,
		 prim.xsi,
		 prim.invert));
	if(secItem != stopItem)
	{
	  iterate = 1;
	}
      }
    }
  }
  REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2),
          ("RecSecCumTransfSetItFn FX %d\n",
	   iterate));
  return(iterate);
}