Beispiel #1
0
/*!
* \return	Woolz error code.
* \ingroup	WlzTransform
* \brief	Walks along a line segment calling the given function.
* \param	obj		Object passed to function.
* \param	fn		Function to call.
* \param	pWSp		Workspace in which the start and end positions,
* 				a valid interval domain and sufficent
* 				intervals have been set.
*/
static WlzErrorNum WlzProfileWalk(
  WlzObject *obj,
  WlzProfileWalkFn fn,
  WlzProfileWalkWSp *pWSp)
{
  int		i,
  		m;
  WlzIVertex3	d,
  		e,
		p,
  		s;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  WLZ_VTX_3_SUB(d, pWSp->end, pWSp->start);
  WLZ_VTX_3_SIGN(s, d);
  WLZ_VTX_3_ABS(d, d);
  m = ALG_MAX3(d.vtX, d.vtY, d.vtZ);
  WLZ_VTX_3_SET(e, m / 2, m / 2, m / 2);
  i = m;
  pWSp->index = 0;
  pWSp->inside = 0;
  p = pWSp->start;
  while(1)
  {
    WlzIVertex3 t0,
    		t1;

    errNum = (*fn)(obj, p, pWSp);
    if((errNum != WLZ_ERR_NONE) || (--i < 0))
    {
      break;
    }
    ++(pWSp->index);
    WLZ_VTX_3_SUB(e, e, d);
    WLZ_VTX_3_SET(t0, (e.vtX < 0), (e.vtY < 0), (e.vtZ < 0));
    WLZ_VTX_3_SCALE_ADD(e, t0, m, e);
    WLZ_VTX_3_HAD(t1, t0, s);
    WLZ_VTX_3_ADD(p, p, t1);
  }
  return(errNum);
}
Beispiel #2
0
/*!
* \return	New filtered object with new values or NULL on error.
* \ingroup	WlzValuesFilters
* \brief	Applies a seperable filter to the given object using the given
* 		convolution kernels.
* \param	inObj			Input 2 or 3D spatial domain object
* 					to be filtered which must have scalar
* 					values.
* \param	cBufSz			Convolution kernel sizes (sz), each
* 					kernel buffer is sized (2 * sz) + 1
* 					with the centre indexed sz into the
* 					buffer.
* \param	cBuf			Convolution kernel buffers.
* \param	direc			Set to non-zero in directions for which
* 					the filter is to be applied.
* \param	gType			Required return object grey type.
* 					Passing in WLZ_GREY_ERROR will
* 					request the given input object's grey
* 					type.
* \param	pad			Type of padding.
* \param	padVal			Padding value, only used when
* 					pad == ALG_PAD_VALUE.
* \param	dstErr			Destination error pointer may be NULL.
*/
WlzObject			*WlzSepFilter(WlzObject *inObj,
				  WlzIVertex3 cBufSz,
				  double *cBuf[],
				  WlzIVertex3 direc,
				  WlzGreyType gType,
				  AlgPadType pad,
				  double padVal,
				  WlzErrorNum *dstErr)
{
  int		dim = 0,
  		vSz = 0,
  		nThr = 1;
  double	**iBuf = NULL,
  		**rBuf = NULL;
  double	*vBuf = NULL;
  WlzObject	*rnObj = NULL;
  WlzIVertex3	vBufSz = {0};
  WlzIBox3	bBox = {0};
  WlzErrorNum	errNum = WLZ_ERR_NONE;

#ifdef _OPENMP
#pragma omp parallel
  {
#pragma omp master
    {
      nThr = omp_get_num_threads();
    }
  }
#endif
  if(inObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(inObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(inObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    switch(inObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
        dim = 2;
	break;
      case WLZ_3D_DOMAINOBJ:
        dim = 3;
        break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if((errNum == WLZ_ERR_NONE) && (gType == WLZ_GREY_ERROR))
  {
    gType = WlzGreyTypeFromObj(inObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(errNum == WLZ_ERR_NONE)
    {
      switch(gType)
      {
        case WLZ_GREY_INT:    /* FALLTHROUGH */
        case WLZ_GREY_SHORT:  /* FALLTHROUGH */
        case WLZ_GREY_UBYTE:  /* FALLTHROUGH */
        case WLZ_GREY_FLOAT:  /* FALLTHROUGH */
        case WLZ_GREY_DOUBLE:
	  break;
        default:
	  errNum = WLZ_ERR_GREY_TYPE;
	  break;
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    bBox = WlzBoundingBox3I(inObj, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      vBufSz.vtX = bBox.xMax - bBox.xMin + 1;
      vBufSz.vtY = bBox.yMax - bBox.yMin + 1;
      if(dim == 3)
      {
	vBufSz.vtZ = bBox.zMax - bBox.zMin + 1;
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    vSz = ALG_MAX3(vBufSz.vtX, vBufSz.vtY, vBufSz.vtZ);
    if(((iBuf = (double **)AlcMalloc(sizeof(double *) * 2 * nThr)) == NULL) ||
       ((vBuf = (double *)AlcMalloc(sizeof(double) * 2 * nThr * vSz)) == NULL))
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else
    {
      int	idt;

      rBuf = iBuf + nThr;
      for(idt = 0; idt < nThr; ++idt)
      {
        iBuf[idt] = vBuf + (idt * vSz);
	rBuf[idt] = vBuf + ((nThr + idt) * vSz);
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    /* Convolve the object values. */
    if(direc.vtX)
    {
      rnObj = WlzSepFilterX(inObj, dim, nThr,
			    iBuf, rBuf, cBufSz.vtX, cBuf[0],
			    pad, padVal, &errNum);
    }
    if((errNum == WLZ_ERR_NONE) && direc.vtY)
    {
      WlzObject *tObj;

      tObj = WlzSepFilterY((rnObj)? rnObj: inObj, dim, nThr,
                            iBuf, rBuf, cBufSz.vtY, cBuf[1],
			    pad, padVal, &errNum);
      (void )WlzFreeObj(rnObj);
      rnObj = tObj;
    }
    if((errNum == WLZ_ERR_NONE) && (dim == 3) && direc.vtZ)
    {
      WlzObject *tObj;

      tObj = WlzSepFilterZ((rnObj)? rnObj: inObj, bBox, nThr,
                            iBuf, rBuf, cBufSz.vtZ, cBuf[2],
			    pad, padVal, &errNum);
      (void )WlzFreeObj(rnObj);
      rnObj = tObj;
    }
  }
  if((errNum == WLZ_ERR_NONE) && (rnObj != NULL) && (gType != WLZ_GREY_DOUBLE))
  {
    WlzObject *tObj;

    /* Convert object values to the required grey type. */
    tObj = WlzConvertPix((rnObj)? rnObj: inObj, gType, &errNum);
    (void )WlzFreeObj(rnObj);
    rnObj = tObj;
  }
  if(errNum != WLZ_ERR_NONE)
  {
    (void )WlzFreeObj(rnObj);
    rnObj = NULL;
  }
  AlcFree(iBuf);
  AlcFree(vBuf);
  return(rnObj);
}