Exemplo n.º 1
0
/*!
* \return	Woolz error code.
* \ingroup	WlzValuesUtils
* \brief	Computes the range of values in a RGBA type image.
* 		Currently implemented is modulus range.
* 		Use WlzGreyRange to get the individual colour ranges.
* \param	obj			Given object with RGBA values.
* \param	min			Destination pointer for minimum value.
* \param	max			Destination pointer for maximum value.
*/
WlzErrorNum WlzRGBAModulusRange(
  WlzObject	*obj,
  double	*min,
  double	*max)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  double	val, lmin, lmax;
  int		i, nplanes, initFlg;
  WlzGreyP		g;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzObject		tempobj;
  WlzPlaneDomain	*planedm;
  WlzValues 		*values;
  WlzDomain		*domains;

  /* object checks */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if( obj->domain.core == NULL ){
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if( obj->values.core == NULL){
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else if( (min == NULL) || (max == NULL) ){
    errNum = WLZ_ERR_PARAM_NULL;
  }

  /* object type checks */
  if( errNum == WLZ_ERR_NONE ){
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      WlzInitGreyScan(obj, &iwsp, &gwsp);
      while( (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE ){
	g = gwsp.u_grintptr;
	for(i=0; i<iwsp.colrmn; i++, g.rgbp++){
	  val = WLZ_RGBA_MODULUS(*g.rgbp);
	  if( !initFlg ){
	    lmin = val;
	    lmax = val;
	    initFlg = 1;
	  }
	  else {
	    if( val < lmin ){
	      lmin = val;
	    }
	    if( val > lmax ){
	      lmax = val;
	    }
	  }
	}
      }
      if( errNum == WLZ_ERR_EOO ){
	errNum = WLZ_ERR_NONE;
      }
      *min = lmin;
      *max = lmax;
      break;

    case WLZ_3D_DOMAINOBJ:
      planedm = obj->domain.p;
      switch( planedm->type ){

      case WLZ_PLANEDOMAIN_DOMAIN:
	nplanes = planedm->lastpl - planedm->plane1 + 1;
	domains = planedm->domains;
	if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){
	  return( WLZ_ERR_VOXELVALUES_TYPE );
	}
	values = obj->values.vox->values;
	tempobj.type = WLZ_2D_DOMAINOBJ;
	tempobj.plist = NULL;
	tempobj.assoc = NULL;
	for(i=0; i < nplanes; i++, domains++, values++){
	  if( (*domains).core == NULL || (*values).core == NULL ){
	    continue;
	  }

	  tempobj.domain = *domains;
	  tempobj.values = *values;
	  errNum = WlzRGBAModulusRange(&tempobj, min, max);
	  if( errNum != WLZ_ERR_NONE ){
	    return( errNum );
	  }
	  if( !initFlg ){
	    lmin = *min;
	    lmax = *max;
	    initFlg = 1;
	    continue;
	  }
	  else {
	    if( *min < lmin ){
	      lmin = *min;
	    }
	    if( *max > lmax ){
	      lmax = *max;
	    }
	  }
	}
	break;

      default:
	errNum = WLZ_ERR_PLANEDOMAIN_TYPE;
	break;

      }
      *min = lmin;
      *max = lmax;
      break;

    case WLZ_TRANS_OBJ:
      return( WlzRGBAModulusRange(obj->values.obj, min, max) );

    case WLZ_EMPTY_OBJ:
      *min = 0.0;
      *max = 0.0;
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  return errNum;
}
Exemplo n.º 2
0
/*!
* \return	Coordinates of center of mass.
* \ingroup	WlzFeatures
* \brief	Calculates the centre of mass of a WLZ_2D_DOMAIN_OBJ.
*               If the object has values and the binary object flag is
*               not set then the centre of mass is calculated using
*               the grey level information.
*		\f[
                C_x = \frac{\sum_x{\sum_y{x G(x,y)}}}
		           {\sum_x{\sum_y{G(x,y)}}} ,
                C_y = \frac{\sum_x{\sum_y{y G(x,y)}}}
		           {\sum_x{\sum_y{G(x,y)}}}
		\f]
*               Where \f$(C_x,C_y)\f$ are the coordinates of the centre of
*               mass.
*               If the given object does not have grey values or the
*               binary object flag is set (ie non zero) then every
*               pixel within the objects domain has the same mass.
* \param	srcObj			Given object.
* \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 WlzCentreOfMassDom2D(WlzObject *srcObj, int binObjFlag,
				        double *dstMass,
					WlzErrorNum *dstErr)
{
  int		iCount;
  double        mass = 0.0,
		tmpD;
  WlzIntervalWSpace iWsp;
  WlzGreyWSpace	gWsp;
  WlzGreyP      gPix;
  WlzIVertex2	pos;
  WlzDVertex2	cMass,
  		sum;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  sum.vtX = 0.0;
  sum.vtY = 0.0;
  cMass.vtX = 0.0;
  cMass.vtY = 0.0;
  if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((srcObj->domain.core->type != WLZ_INTERVALDOMAIN_INTVL) &&
          (srcObj->domain.core->type != WLZ_INTERVALDOMAIN_RECT))
  {
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }
  else
  {
    if((srcObj->values.core == NULL) ||
       (srcObj->values.core->type == WLZ_EMPTY_OBJ))
    {
      binObjFlag = 1;
    }
    if(binObjFlag)
    {
      errNum = WlzInitRasterScan(srcObj, &iWsp, WLZ_RASTERDIR_ILIC);
    }
    else
    {
      errNum = WlzInitGreyScan(srcObj, &iWsp, &gWsp);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(binObjFlag)
    {
      while((errNum = WlzNextInterval(&iWsp)) == WLZ_ERR_NONE)
      {
	iCount = iWsp.rgtpos - iWsp.lftpos + 1;
	mass += iCount;
	sum.vtX += ((iWsp.rgtpos * (iWsp.rgtpos + 1)) -
		    (iWsp.lftpos * (iWsp.lftpos - 1))) / 2.0;
	sum.vtY += iWsp.linpos * iCount;
      }
      if(errNum == WLZ_ERR_EOO)	        /* Reset error from end of intervals */ 
      {
	errNum = WLZ_ERR_NONE;
      }
    }
    else
    {
      if((gWsp.pixeltype != WLZ_GREY_INT) &&
	 (gWsp.pixeltype != WLZ_GREY_SHORT) &&
	 (gWsp.pixeltype != WLZ_GREY_UBYTE) &&
	 (gWsp.pixeltype != WLZ_GREY_FLOAT) &&
	 (gWsp.pixeltype != WLZ_GREY_DOUBLE) &&
	 (gWsp.pixeltype != WLZ_GREY_RGBA))
      {
        errNum = WLZ_ERR_GREY_TYPE;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	while((errNum = WlzNextGreyInterval(&iWsp)) == WLZ_ERR_NONE)
	{
	  pos.vtX = iWsp.lftpos;
	  pos.vtY = iWsp.linpos;
	  gPix = gWsp.u_grintptr;
	  iCount = iWsp.rgtpos - iWsp.lftpos + 1;
	  switch(gWsp.pixeltype)
	  {
	    case WLZ_GREY_INT:
	      while(iCount-- > 0)
	      {
		tmpD = *(gPix.inp);
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.inp);
		++(pos.vtX);
	      }
	      break;
	    case WLZ_GREY_SHORT:
	      while(iCount-- > 0)
	      {
		tmpD = *(gPix.shp);
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.shp);
		++(pos.vtX);
	      }
	      break;
	    case WLZ_GREY_UBYTE:
	      while(iCount-- > 0)
	      {
		tmpD = *(gPix.ubp);
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.ubp);
		++(pos.vtX);
	      }
	      break;
	    case WLZ_GREY_FLOAT:
	      while(iCount-- > 0)
	      {
		tmpD = *(gPix.flp);
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.flp);
		++(pos.vtX);
	      }
	      break;
	    case WLZ_GREY_DOUBLE:
	      while(iCount-- > 0)
	      {
		tmpD = *(gPix.dbp);
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.dbp);
		++(pos.vtX);
	      }
	      break;
	    case WLZ_GREY_RGBA:
	      while(iCount-- > 0)
	      {
		tmpD = WLZ_RGBA_MODULUS(*(gPix.rgbp));
		sum.vtY += pos.vtY * tmpD;
		sum.vtX += pos.vtX * tmpD;
		mass += tmpD;
		++(gPix.rgbp);
		++(pos.vtX);
	      }
	      break;
	    default:
	      break;
	  }
	}
	if(errNum == WLZ_ERR_EOO)        /* Reset error from end of intervals */ 
	{
	  errNum = WLZ_ERR_NONE;
	}
      }
      (void )WlzEndGreyScan(&iWsp, &gWsp);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if((mass > DBL_EPSILON) || (mass < (-(DBL_EPSILON))))
    {
      cMass.vtX = sum.vtX / mass;
      cMass.vtY = sum.vtY / mass;
    }
    if(dstMass)
    {
      *dstMass = mass;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(cMass);
}
Exemplo n.º 3
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        Calculate the pixel value for a given channel.
For grey-pixel types the colour channel values are set equal to the
 grey value i.e. the pixel is assumed to be (g,g,g). If the grey-channel
 is requested of a colour pixel the modulus is returned. For colour
 pixels the error return value is -1, for grey pixels the error return
 should be tested since all values are valid (except grey-type WlzUByte).
 Hue and saturation are zero for grey-pixel types.
*
* \return       requested value of pixel
* \param    pixVal	input pixel value structure
* \param    chan        requested pixel channel
* \param    dstErr	error destination
* \par      Source:
*                WlzRGBAPixelUtils.c
*/
double WlzRGBAPixelValue(
  WlzPixelV		pixVal,
  WlzRGBAColorChannel	chan,
  WlzErrorNum		*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  double	val=-1;
  int		col[3];

  switch( pixVal.type ){
  case WLZ_GREY_INT:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
      val = 0.0;
      break;

    default:
      val = pixVal.v.inv;
      break;
    }
    break;

  case WLZ_GREY_SHORT:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
      val = 0.0;
      break;

    default:
      val = pixVal.v.shv;
      break;
    }
    break;

  case WLZ_GREY_UBYTE:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
      val = 0.0;
      break;

    default:
      val = pixVal.v.ubv;
      break;
    }
    break;

  case WLZ_GREY_FLOAT:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
      val = 0.0;
      break;

    default:
      val = pixVal.v.flv;
      break;
    }
    break;

  case WLZ_GREY_DOUBLE:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
      val = 0.0;
      break;

    default:
      val = pixVal.v.dbv;
      break;
    }
    break;

  case WLZ_GREY_RGBA:
    switch( chan ){
    case WLZ_RGBA_CHANNEL_GREY:
      /* ????? */
      val = WLZ_RGBA_MODULUS(pixVal.v.rgbv);
      break;

    case WLZ_RGBA_CHANNEL_RED:
      val = WLZ_RGBA_RED_GET(pixVal.v.rgbv);
      break;

    case WLZ_RGBA_CHANNEL_GREEN:
      val = WLZ_RGBA_GREEN_GET(pixVal.v.rgbv);
      break;

    case WLZ_RGBA_CHANNEL_BLUE:
      val = WLZ_RGBA_BLUE_GET(pixVal.v.rgbv);
      break;

    case WLZ_RGBA_CHANNEL_HUE:
      col[0] = WLZ_RGBA_RED_GET(pixVal.v.rgbv);
      col[1] = WLZ_RGBA_GREEN_GET(pixVal.v.rgbv);
      col[2] = WLZ_RGBA_BLUE_GET(pixVal.v.rgbv);
      WlzRGBAConvertRGBToHSV_UBYTENormalised(col);
      val = col[0];
      break;

    case WLZ_RGBA_CHANNEL_SATURATION:
      col[0] = WLZ_RGBA_RED_GET(pixVal.v.rgbv);
      col[1] = WLZ_RGBA_GREEN_GET(pixVal.v.rgbv);
      col[2] = WLZ_RGBA_BLUE_GET(pixVal.v.rgbv);
      WlzRGBAConvertRGBToHSV_UBYTENormalised(col);
      val = col[1];
      break;

    case WLZ_RGBA_CHANNEL_BRIGHTNESS:
      col[0] = WLZ_RGBA_RED_GET(pixVal.v.rgbv);
      col[1] = WLZ_RGBA_GREEN_GET(pixVal.v.rgbv);
      col[2] = WLZ_RGBA_BLUE_GET(pixVal.v.rgbv);
      WlzRGBAConvertRGBToHSV_UBYTENormalised(col);
      val = col[2];
      break;

    case WLZ_RGBA_CHANNEL_CYAN:
      val = (WLZ_RGBA_BLUE_GET(pixVal.v.rgbv) +
	     WLZ_RGBA_GREEN_GET(pixVal.v.rgbv)) / 2;
      break;

    case WLZ_RGBA_CHANNEL_MAGENTA:
      val = (WLZ_RGBA_BLUE_GET(pixVal.v.rgbv) +
	     WLZ_RGBA_RED_GET(pixVal.v.rgbv)) / 2;
      break;

    case WLZ_RGBA_CHANNEL_YELLOW:
      val = (WLZ_RGBA_RED_GET(pixVal.v.rgbv) +
	     WLZ_RGBA_GREEN_GET(pixVal.v.rgbv)) / 2;
      break;

    default:
      errNum = WLZ_ERR_GREY_TYPE;
      break;

    }
    break;

  case WLZ_GREY_BIT:
  default:
    errNum = WLZ_ERR_GREY_TYPE;
    break;
  }
  if(errNum == WLZ_ERR_NONE){
    if( val < 0 ){
      val = -1.0;
      errNum = WLZ_ERR_GREY_DATA;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return val;
}
Exemplo n.º 4
0
/*!
* \return	Angle in radians.
* \ingroup	WlzRegistration
* \brief	Calculates the angle  which the long principal axis
*               makes with the x-axis in the given object.
*               \f[
		  \theta = \frac{1}{2}
		  	   \arctan{(2 \frac{I_{xy}}{I_{yy}-I_{xx}})}
		\f]
*               where
*               \f[
		  I_{xx} = \sum_y \sum_x ((y - C_y) (y - C_y) G(x, y))
		\f]
*		\f[
                  I_{yy} = \sum_y \sum_x ((x - C_x) (x - C_x) G(x, y))
		\f]
*		\f[
                  I_{xy} = - \sum_y \sum_x (((x - C x) (y - C_y) G(x, y))
		\f]
*               and \f$(C_x, C_y)\f$ are the coordinates of the centre of
*               mass.
* \param	srcObj			Given object.
* \param	cMass			Center of mass of given object.
* \param	binObjFlag		Given object is binary if non
*                                       zero.
* \param	dstErrNum		Destination pointer for error
*                                       number, may be NULL if not
*                                       required.
*/
double		WlzPrincipalAngle(WlzObject *srcObj, WlzDVertex2 cMass,
				  int binObjFlag, WlzErrorNum *dstErrNum)
{
  int 		tI0,
		tI1,
  		iCount;
  double 	tD0,
		tD1,
		root0,
		root1,
		ixx = 0.0,
		iyy = 0.0,
		ixy = 0.0,
		pAngle = 0.0;
  WlzIVertex2	delta;
  WlzIntervalWSpace iWsp = {0};
  WlzGreyWSpace	gWsp;
  WlzGreyP	gPix;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  WLZ_DBG((WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1),
	  ("WlzPrincipalAngle FE %p {%d %d} %d\n",
	   srcObj, cMass.vtX, cMass.vtY, binObjFlag));
  if(srcObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(srcObj->type != WLZ_2D_DOMAINOBJ)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((srcObj->domain.core->type != WLZ_INTERVALDOMAIN_INTVL) &&
          (srcObj->domain.core->type != WLZ_INTERVALDOMAIN_RECT))
  {
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }
  else
  {
    if((srcObj->values.core == NULL) ||
       (srcObj->values.core->type == WLZ_EMPTY_OBJ))
    {
      binObjFlag = 1;
    }
    if(binObjFlag)
    {
      errNum = WlzInitRasterScan(srcObj, &iWsp, WLZ_RASTERDIR_ILIC);
    }
    else
    {
      errNum = WlzInitGreyScan(srcObj, &iWsp, &gWsp);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(binObjFlag)
    {
      while((errNum = WlzNextInterval(&iWsp)) == WLZ_ERR_NONE)
      {
	delta.vtY = (int )(iWsp.linpos - cMass.vtY);
	delta.vtX = (int )(iWsp.lftpos - cMass.vtX);
	iCount = iWsp.rgtpos - iWsp.lftpos + 1;
	tI0 = iCount * (iCount - 1);
	ixx += iCount * delta.vtY * delta.vtY;
	iyy += (iCount * delta.vtX * delta.vtX) + (tI0 * delta.vtX) +
	       (tI0 * ((2 * iCount) - 1) / 6);
	ixy -= (iCount * delta.vtX * delta.vtY) + (tI0 * delta.vtY / 2);
      }
      if(errNum == WLZ_ERR_EOO)		/* Reset error from end of intervals */
      {
        errNum = WLZ_ERR_NONE;
      }
    }
    else
    {
      while((errNum == WLZ_ERR_NONE) &&
            ((errNum = WlzNextGreyInterval(&iWsp)) == WLZ_ERR_NONE))
      {
	gPix = gWsp.u_grintptr;
	delta.vtX = (int )(iWsp.lftpos - cMass.vtX);
	delta.vtY = (int )(iWsp.linpos - cMass.vtY);
	iCount = iWsp.rgtpos - iWsp.lftpos;
	switch(gWsp.pixeltype)
	{
	  case WLZ_GREY_INT:
	    while(iCount-- >= 0)
	    {
	      tI0 = *gPix.inp;
	      tI1 = delta.vtX * tI0;
	      ixx += delta.vtY * delta.vtY * tI0;
	      iyy += delta.vtX * tI1;
	      ixy -= delta.vtY * tI1;
	      ++gPix.inp;
	      ++delta.vtX;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    while(iCount-- >= 0)
	    {
	      tI0 = *gPix.shp;
	      tI1 = delta.vtX * tI0;
	      ixx += delta.vtY * delta.vtY * tI0;
	      iyy += delta.vtX * tI1;
	      ixy -= delta.vtY * tI1;
	      ++gPix.inp;
	      ++delta.vtX;
	    }
	    break;
	  case WLZ_GREY_UBYTE:
	    while(iCount-- >= 0)
	    {
	      tI0 = *gPix.ubp;
	      tI1 = delta.vtX * tI0;
	      ixx += delta.vtY * delta.vtY * tI0;
	      iyy += delta.vtX * tI1;
	      ixy -= delta.vtY * tI1;
	      ++gPix.ubp;
	      ++delta.vtX;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    while(iCount-- >= 0)
	    {
	      tD0 = *gPix.flp;
	      tD1 = delta.vtX * tD0;
	      ixx += delta.vtY * delta.vtY * tD0;
	      iyy += delta.vtX * tD1;
	      ixy -= delta.vtY * tD1;
	      ++gPix.flp;
	      ++delta.vtX;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    while(iCount-- >= 0)
	    {
	      tD0 = *gPix.dbp;
	      tD1 = delta.vtX * tD0;
	      ixx += delta.vtY * delta.vtY * tD0;
	      iyy += delta.vtX * tD1;
	      ixy -= delta.vtY * tD1;
	      ++gPix.dbp;
	      ++delta.vtX;
	    }
	    break;
	  case WLZ_GREY_RGBA:
	    while(iCount-- >= 0)
	    {
	      tI0 = (WlzUInt )WLZ_RGBA_MODULUS(*gPix.rgbp);
	      tI1 = delta.vtX * tI0;
	      ixx += delta.vtY * delta.vtY * tI0;
	      iyy += delta.vtX * tI1;
	      ixy -= delta.vtY * tI1;
	      ++gPix.rgbp;
	      ++delta.vtX;
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_GREY_TYPE;
	    break;
	}
      }
      (void )WlzEndGreyScan(&iWsp, &gWsp);
      if(errNum == WLZ_ERR_EOO)		/* Reset error from end of intervals */
      {
        errNum = WLZ_ERR_NONE;
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    tD0 = ixx + iyy;
    tD1 = sqrt((tD0 * tD0) - (4.0 * ((ixx * iyy) - (ixy * ixy))));
    root0 = (tD0 - tD1) / 2.0;
    root1 = (tD0 + tD1) / 2.0;
    if(WLZ_ABS(root0) > WLZ_ABS(root1))
    {
      root0 = root1;
    }
    if(WLZ_ABS(root0 - ixx) < DBL_EPSILON)
    {
      pAngle = 0.0;
    }
    else if(WLZ_ABS(ixy) < DBL_EPSILON)
    {
      pAngle = WLZ_M_PI_2;
    }
    else
    {
      pAngle = atan((root0 - ixx) / ixy);
    }
  }
  if(dstErrNum)
  {
    *dstErrNum = errNum;
  }
  WLZ_DBG((WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1),
	  ("WlzPrincipalAngle FX %d\n",
	   pAngle));
  return(pAngle);
}
Exemplo n.º 5
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        Calculate the modulus of the rgb values and return
 in an image of grey type WLZ_GREY_SHORT
*
* \return       Grey-level object of modulus values
* \param    obj	Input rgba object
* \param    dstErr	error return
* \par      Source:
*                WlzRGBAConvert.c
*/
WlzObject *WlzRGBAToModulus(
  WlzObject	*obj,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check object type, and value type */
  if( obj ){
    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( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){
	errNum = WLZ_ERR_VALUES_TYPE;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      if( obj->domain.core == NULL ){
	errNum = WLZ_ERR_DOMAIN_NULL;
      }
      else if( obj->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN ){
	errNum = WLZ_ERR_DOMAIN_TYPE;
      }
      else if ( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      else if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){
	errNum = WLZ_ERR_VALUES_TYPE;
      }
      else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){
	errNum = WLZ_ERR_VALUES_TYPE;
      }
      return WlzRGBAToModulus3D(obj, dstErr);

    case WLZ_TRANS_OBJ:
      /* not difficult, do it later */
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;

    case WLZ_COMPOUND_ARR_1:
    case WLZ_COMPOUND_ARR_2:
      /* bit recursive this ! */
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
    }
  }
  else {
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* create object return */
  if( errNum == WLZ_ERR_NONE ){
    WlzValues	values;
    WlzObjectType	type;
    WlzPixelV	oldBck, newBck;

    type = WlzGreyTableType(
      WlzGreyTableTypeToTableType(obj->values.core->type, &errNum),
      WLZ_GREY_SHORT, &errNum);
    oldBck = WlzGetBackground(obj, &errNum);
    newBck.type = WLZ_GREY_SHORT;
    newBck.v.shv = (short )WLZ_RGBA_MODULUS(oldBck.v.rgbv);

    /* make values table and return object */
    values.v = WlzNewValueTb(obj, type, newBck, &errNum);
    rtnObj = WlzMakeMain(obj->type, obj->domain, values,
			 NULL, NULL, &errNum);
  }

  /* iterate through objects setting values */
  if( errNum == WLZ_ERR_NONE ){
    WlzIntervalWSpace	iwsp0, iwsp1;
    WlzGreyWSpace	gwsp0, gwsp1;
    int			j, k;

    errNum = WlzInitGreyScan(obj, &iwsp0, &gwsp0);
    errNum = WlzInitGreyScan(rtnObj, &iwsp1, &gwsp1);
    while((errNum == WLZ_ERR_NONE) &&
	  ((errNum = WlzNextGreyInterval(&iwsp0)) == WLZ_ERR_NONE)){
      errNum = WlzNextGreyInterval(&iwsp1);
      for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++,
	    gwsp0.u_grintptr.rgbp++){
	*(gwsp1.u_grintptr.shp++) = (short )
	                            WLZ_RGBA_MODULUS(*(gwsp0.u_grintptr.rgbp));
      }
    }
    if( errNum == WLZ_ERR_EOO ){
      errNum = WLZ_ERR_NONE;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}