예제 #1
0
/*!
* \return	Woolz error code.
* \ingroup	WlzValuesUtils
* \brief	Sets the values of a 2 or 3D domain object with int 
* 		values so that they increment throughout the object
* 		in scan order. Object values are set by incrementing
* 		the given value in place. The given object must have
* 		WLZ_GREY_INT values.
* \param	obj			The given object.
* \param	gVal			Pointer to current value, this is
* 					incremented in place. If NULL then
* 					the values will be incremented from
* 					zero.
*/
WlzErrorNum 	WlzGreySetIncValues(WlzObject *obj, int *gVal)
{
  int		val;
  WlzGreyType	gType;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  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
  {
    gType = WlzGreyTypeFromObj(obj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(gType != WLZ_GREY_INT)
    {
      errNum = WLZ_ERR_GREY_TYPE;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    val = (gVal)? *gVal: 0;
    switch(obj->type)
    {
      case WLZ_2D_DOMAINOBJ: /* FALLTROUGH */
      case WLZ_3D_DOMAINOBJ:
	errNum = WlzGreySetIncValuesItr(obj, &val);
	break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
    if(gVal && (errNum == WLZ_ERR_NONE))
    {
      *gVal = val;
    }
  }
  return(errNum);
}
예제 #2
0
/*!
* \return	Woolz error code.
* \ingroup	WlzExtFF
* \brief	Writes the given object to a jpeg image.
* \param	fP			Given file stream.
* \param	obj			Given object to be written.
* \param	params			Jpeg parameters string, currently this
*					is a single ascii integer, which should
*					have the range 1 - 100 and rpresents
*					the image quality with 100 being
*					lossless.
*/
WlzErrorNum WlzEffWriteObjJpeg(
  FILE 		*fP,
  WlzObject 	*obj,
  char		*params)
{
  WlzErrorNum			errNum=WLZ_ERR_NONE;
  struct jpeg_compress_struct cinfo;
  struct my_error_mgr		jerr;
  JSAMPARRAY 	buffer = NULL;	/* Output row buffer */
  int		quality = 100;	/* Output quality. */
  int 		row_stride;	/* physical row width in input buffer */
  int		width, height;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  int		i, j;
  WlzObject	*rectObj=NULL;
  WlzGreyType 	gType = WLZ_GREY_ERROR;

  /* check input */
  if( fP == NULL ){
    errNum = WLZ_ERR_PARAM_NULL;
  }
  if( obj ){
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj->domain.core ){
	if( obj->values.core == NULL ){
	  errNum = WLZ_ERR_VALUES_NULL;
	}
	else {
	  WlzIBox2	cutBox;
	  
	  cutBox.xMin = obj->domain.i->kol1;
	  cutBox.yMin = obj->domain.i->line1;
	  cutBox.xMax = obj->domain.i->lastkl;
	  cutBox.yMax = obj->domain.i->lastln;
	  gType = WlzGreyTypeFromObj(obj, &errNum);
	  if((rectObj = WlzCutObjToBox2D(obj, cutBox, gType,
					 0, 0.0, 0.0, &errNum)) != NULL){
	    width = rectObj->domain.i->lastkl - rectObj->domain.i->kol1 + 1;
	    height = rectObj->domain.i->lastln - rectObj->domain.i->line1 + 1;
	  }
	}
      }
      else {
	errNum = WLZ_ERR_DOMAIN_NULL;
      }
      break;

    case WLZ_TRANS_OBJ:
      errNum = WlzEffWriteObjJpeg(fP, obj->values.obj, params);
      break;

    case WLZ_EMPTY_OBJ:
      return WLZ_ERR_NONE;

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

  /* We set up the normal JPEG error routines, then override error_exit. */
  if( errNum == WLZ_ERR_NONE ){
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;
    /* Establish the setjmp return context for my_error_exit to use. */
    if (setjmp(jerr.setjmp_buffer)) {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_compress(&cinfo);
      if( rectObj ){
	WlzFreeObj(rectObj);
      }
      errNum = WLZ_ERR_WRITE_INCOMPLETE;
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, fP);

    /* set the image parameters */
    width = obj->domain.i->lastkl - obj->domain.i->kol1 + 1;
    height = obj->domain.i->lastln - obj->domain.i->line1 + 1;
    cinfo.image_width = width;
    cinfo.image_height = height;
    switch( gType ){
    case WLZ_GREY_INT:
    case WLZ_GREY_SHORT:
    case WLZ_GREY_FLOAT:
    case WLZ_GREY_DOUBLE:
      errNum = WLZ_ERR_UNIMPLEMENTED;
      break;

    case WLZ_GREY_UBYTE:
      cinfo.input_components = 1;
      cinfo.in_color_space = JCS_GRAYSCALE;
      break;

    case WLZ_GREY_RGBA:
      cinfo.input_components = 3;
      cinfo.in_color_space = JCS_RGB;
      break;
    default:
      break;
    }

    if( errNum == WLZ_ERR_NONE ){
      /* set the default parameters */
      jpeg_set_defaults(&cinfo);

      /* check for other parameters */
      if( params ){
	sscanf(params, "%d", &quality);
      }
      jpeg_set_quality(&cinfo, quality, TRUE);

      /* JSAMPLEs per row in output buffer */
      row_stride = cinfo.image_width * cinfo.input_components;
      /* Make a one-row-high sample array that will go away when done with
       * image */
      buffer = (*cinfo.mem->alloc_sarray)
	((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

    }
    else {
      jpeg_destroy_compress(&cinfo);
      if( rectObj ){
	WlzFreeObj(rectObj);
      }
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    jpeg_start_compress(&cinfo, TRUE);

    /* loop through the woolz object setting the output buffer
       note this is the "input" to the compressor */
    if((errNum = WlzInitGreyScan(rectObj, &iwsp, &gwsp)) == WLZ_ERR_NONE){
      while((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE){
	WlzUInt val;
	switch( gType ){
	case WLZ_GREY_UBYTE:
	  for(i=0, j=0; i < width; i++){
	    buffer[0][j++] = gwsp.u_grintptr.ubp[i];
	  }
	  break;
	case WLZ_GREY_RGBA:
	  for(i=0, j=0; i < width; i++){
	    val = gwsp.u_grintptr.rgbp[i];
	    buffer[0][j++] = WLZ_RGBA_RED_GET(val);
	    buffer[0][j++] = WLZ_RGBA_GREEN_GET(val);
	    buffer[0][j++] = WLZ_RGBA_BLUE_GET(val);
	  }
	  break;
	default:
	  break;
	}
	(void) jpeg_write_scanlines(&cinfo, buffer, 1);
      }

      if( errNum == WLZ_ERR_EOO ){
	errNum = WLZ_ERR_NONE;
      }

    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    WlzFreeObj(rectObj);
  }

  return errNum;
}
예제 #3
0
/*! 
* \ingroup      WlzValuesFilters
* \brief        Gaussian filter of grey-level 2D woolz object. x- and
 y-coordinate width parameters and derivative degree can be independently
 specified. For derivative zero, i.e. Gaussian smoothing, the filter is
 normalised. Derivatives are derivative of the normalised filter. RGB
 data will only return values for smoothing, higher derivatives are not
 implemented. The width parameter is the full-width half-height of the
 Gaussian distribution. Note RGB pixel types are converted to a compound 
 object with each channel returned with WLZ_GREY_SHORT pixel type.
*
* \return       Pointer to transformed object
* \param    obj	Input object
* \param    wx	x-direction width parameter
* \param    wy	y-direction width parameter
* \param    x_deriv	x-direction derivative
* \param    y_deriv	y-direction derivative
* \param    wlzErr	error return
* \par      Source:
*                WlzGauss.c
*/
WlzObject *WlzGauss2(
  WlzObject	*obj,
  double	wx,
  double	wy,
  int		x_deriv,
  int		y_deriv,
  WlzErrorNum	*wlzErr)
{
  WlzObject		*newobj=NULL;
  Wlz1DConvMask		x_params, y_params;
  float 		alpha, sum;
  int 			i, n, value;
  WlzErrorNum		errNum=WLZ_ERR_NONE;
    
  /* check object, don't need to check type etc. because WlzSepTrans
     does it */
  if( obj == NULL )
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* do need to check for rgb grey type */
  if( errNum == WLZ_ERR_NONE ){
    if( (obj->type == WLZ_2D_DOMAINOBJ) &&
        (WlzGreyTypeFromObj(obj, &errNum) == WLZ_GREY_RGBA) ){
      if( (x_deriv != 0) || (y_deriv != 0) ){
	/* implement this using a compond object since the
	   result should be a vector value */
	WlzCompoundArray *cobj;

	if((cobj = WlzRGBAToCompound(obj, WLZ_RGBA_SPACE_RGB,
	                             &errNum)) != NULL){
	  /* need to convert each to short for gradient calc */
	  for(i=0; i < 3; i++){
	    WlzObject *tmpObj;
	    tmpObj = cobj->o[i];
	    cobj->o[i] = WlzAssignObject(WlzConvertPix(tmpObj,
						       WLZ_GREY_SHORT,
						       &errNum), NULL);
	    WlzFreeObj(tmpObj);
	  }
	  newobj = WlzGauss2((WlzObject *) cobj, wx, wy, x_deriv, y_deriv,
			     &errNum);
	  WlzFreeObj((WlzObject *) cobj);
	  if( wlzErr ){
	    *wlzErr = errNum;
	  }
	  return newobj;
	}
      }
    }
  }

  /* now start work */
  if( errNum == WLZ_ERR_NONE ){
    alpha = (float )(4.0 * log((double )2.0));
    
    /* set up x function parameters */
    x_params.mask_size = (((int) wx * 4)/2)*2 + 1;
    if( (x_params.mask_values = (int *)
	 AlcMalloc(sizeof(int) * x_params.mask_size)) == NULL){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      n = x_params.mask_size / 2;
    
      switch( x_deriv ){

      case 0:
	for(i=0, sum = -AFACTOR; i <= n; i++){
	  value = (int )(AFACTOR * exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = value;
	  sum += 2 * value;
	}
	x_params.norm_factor = sum;
	break;

      case 1:
	*(x_params.mask_values+n) = 0.0;
	for(i=1, sum = 0; i <= n; i++){
	  value = (int )(AFACTOR * i * exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = -value;
	  sum += value;
	}
	/* sum *= -wx / 2 / sqrt( log( (double) 2 ) / WLZ_M_PI );*/
	if( n > 0 )
	  x_params.norm_factor = sum;
	else
	  x_params.norm_factor = 1;
	break;

      case 2:
	for(i=0; i <= n; i++){
	  value = (int )(AFACTOR * (alpha * i*i / wx/wx -1) *
	                 exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = value;
	}
	x_params.norm_factor = (int )(*(x_params.mask_values+n) * wx*wx*wx /
	                              4 / alpha / sqrt(log((double )2) /
				      WLZ_M_PI ));
	break;

      default:
	AlcFree((void *) x_params.mask_values);
	x_params.mask_values = NULL;
	errNum = WLZ_ERR_PARAM_DATA;
	break;
      }
    }
  }
    
  /* set up y function parameters */
  if( errNum == WLZ_ERR_NONE ){
    y_params.mask_size = (((int) wy * 4)/2)*2 + 1;
    if( (y_params.mask_values = (int *)
	 AlcMalloc(sizeof(int) * y_params.mask_size)) == NULL){
      AlcFree((void *) x_params.mask_values);
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      n = y_params.mask_size / 2;
    
      switch( y_deriv ){

      case 0:
	for(i=0, sum = -AFACTOR; i <= n; i++){
	  value = (int )(AFACTOR * exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = value;
	  sum += 2 * value;
	}
	y_params.norm_factor = sum;
	break;

      case 1:
	*(y_params.mask_values+n) = 0.0;
	for(i=1, sum = 0; i <= n; i++){
	  value = (int )(AFACTOR * i * exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = -value;
	  sum += value;
	}
	/* sum *= -wy / 2 / sqrt( log( (double) 2 ) /WLZ_M_PI );*/
	if( n > 0 )
	  y_params.norm_factor = sum;
	else
	  y_params.norm_factor = 1;
	break;

      case 2:
	for(i=0; i <= n; i++){
	  value = (int )(AFACTOR * (alpha * i*i / wy/wy -1) *
	                 exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = value;
	}
	y_params.norm_factor = (int )(*(y_params.mask_values+n) * wy*wy*wy / 4 / alpha
	  / sqrt( log( (double) 2 ) / WLZ_M_PI ));
	break;

      default:
	AlcFree((void *) x_params.mask_values);
	AlcFree((void *) y_params.mask_values);
	x_params.mask_values = NULL;
	y_params.mask_values = NULL;
	errNum = WLZ_ERR_PARAM_DATA;
	break;
      }
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    newobj = WlzSepTrans(obj,
			 Wlz1DConv, (void *) &x_params,
			 Wlz1DConv, (void *) &y_params,
			 &errNum);
    AlcFree((void *) x_params.mask_values);
    AlcFree((void *) y_params.mask_values);
  }

  if( wlzErr )
  {
    *wlzErr = errNum;
  }
  return(newobj);
}
예제 #4
0
파일: WlzSplitObj.c 프로젝트: dscho/Woolz
/*!
* \return	Woolz error code.
* \ingroup	WlzBinaryOps
* \brief	Splits the given montage object into component objects
*		clipped from the montage object.  The montage object
*		must be composed of component images embedded in a
*		background, with little variation in the background
*		values.
* \param	mObj			Montage object, which must be either
*					a WLZ_2D_DOMAINOBJ or a
*					WLZ_3D_DOMAINOBJ with values.
* \param	gapV			Value for the uniform background.
*					Must be either WLZ_GREY_INT or
*					WLZ_GREY_RGBA.
* \param	tol			Tolerance (fraction) for the
*					variation in background values.
* \param	bWidth			Additional boundary width added
*					to detected images before they are
*					clipped.
* \param	minArea			Minimum area for a valid component
*					image, must be greater than zero.
* \param	maxComp			Maximum number of components.
* \param	dstNComp		Destination pointer for the number of
*					components extracted, must not be NULL.
* \param	dstComp			Destination pointer for the extracted
*					components, must not be NULL.
*/
WlzErrorNum 	WlzSplitMontageObj(WlzObject *mObj, WlzPixelV gapV,
				      double tol, int bWidth, int minArea,
				      int maxComp,
				      int *dstNComp, WlzObject ***dstComp)
{
  int		id0,
  		id1,
		area,
		nLComp = 0;
  WlzObject	*gObj = NULL,
  		*tObj = NULL;
  WlzObject	**lComp;
  WlzGreyType	objG;
  WlzBox	box;
  WlzPixelV	gapLV,
  		gapHV;
  WlzConnectType lCon;
  int		tI[8];
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  tol = WLZ_CLAMP(tol, 0.0, 1.0);
  if(mObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(minArea < 1)
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else
  {
    switch(mObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	lCon = WLZ_4_CONNECTED;
        break;
      case WLZ_3D_DOMAINOBJ:
	lCon = WLZ_6_CONNECTED;
        break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    objG = WlzGreyTypeFromObj(mObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(gapV.type)
    {
      case WLZ_GREY_INT: /* FALLTHROUGH */
      case WLZ_GREY_RGBA:
        break;
      default:
	errNum = WLZ_ERR_GREY_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(objG == WLZ_GREY_RGBA)
    {
      if(gapV.type != WLZ_GREY_RGBA)
      {
        (void )WlzValueConvertPixel(&gapV, gapV, WLZ_GREY_RGBA);
      }
    }
    else
    {
      if(gapV.type != WLZ_GREY_INT)
      {
        (void )WlzValueConvertPixel(&gapV, gapV, WLZ_GREY_INT);
      }
    }
    gapLV.type = gapHV.type = gapV.type;
    if(gapV.type == WLZ_GREY_INT)
    {
      tI[0] = gapV.v.inv * tol;
      gapLV.v.inv = gapV.v.inv - tI[0];
      gapHV.v.inv = gapV.v.inv + tI[0];
      tObj = WlzThreshold(mObj, gapLV, WLZ_THRESH_HIGH, &errNum);
      if((errNum == WLZ_ERR_NONE) && (tObj != NULL))
      {
	gObj = WlzThreshold(tObj, gapHV, WLZ_THRESH_LOW, &errNum);
      }
      (void )WlzFreeObj(tObj);
      tObj = NULL;
    }
    else /* gapV.type == WLZ_GREY_RGBA */
    {
	tI[0] = WLZ_RGBA_RED_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[2] = tI[0] - tI[1];
	tI[5] = tI[0] + tI[1];
	tI[0] = WLZ_RGBA_GREEN_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[3] = tI[0] - tI[1];
	tI[6] = tI[0] + tI[1];
	tI[0] = WLZ_RGBA_BLUE_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[4] = tI[0] - tI[1];
	tI[7] = tI[0] + tI[1];
	tI[2] = WLZ_CLAMP(tI[2], 0, 255);
	tI[3] = WLZ_CLAMP(tI[3], 0, 255);
	tI[4] = WLZ_CLAMP(tI[4], 0, 255);
	WLZ_RGBA_RGBA_SET(gapLV.v.rgbv, tI[2], tI[3], tI[4], 255);
	tI[5] = WLZ_CLAMP(tI[5], 0, 255);
	tI[6] = WLZ_CLAMP(tI[6], 0, 255);
	tI[7] = WLZ_CLAMP(tI[7], 0, 255);
	WLZ_RGBA_RGBA_SET(gapHV.v.rgbv, tI[5], tI[6], tI[7], 255);
        gObj = WlzRGBABoxThreshold(mObj, gapLV, gapHV, &errNum);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    tObj = WlzDiffDomain(mObj, gObj, &errNum);
  }
  (void )WlzFreeObj(gObj);
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzLabel(tObj, &nLComp, &lComp, maxComp, 0, lCon);
  }
  (void )WlzFreeObj(tObj);
  if(errNum == WLZ_ERR_NONE)
  {
    /* Get rid of small objects using minArea as the threshold. */
    id0 = 0;
    id1 = 0;
    while(id0 < nLComp)
    {
      switch((*(lComp + id0))->type)
      {
        case WLZ_2D_DOMAINOBJ:
	  area = WlzArea(*(lComp + id0), NULL);
	  break;
        case WLZ_3D_DOMAINOBJ:
	  area = WlzVolume(*(lComp + id0), NULL);
	  break;
        default:
          area = 0;
	  break;
      }
      if(area >= minArea)
      {
        *(lComp + id1) = *(lComp + id0);
        ++id1;
      }
      else
      {
        (void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = NULL;
      }
      ++id0;
    }
    nLComp = id1;
  }
  if(errNum == WLZ_ERR_NONE)
  {
    /* Clip rectangular objects from the montage object. */
    id0 = 0;
    while((errNum == WLZ_ERR_NONE) && (id0 < nLComp))
    {
      if(tObj->type == WLZ_2D_DOMAINOBJ)
      {
        box.i2 = WlzBoundingBox2I(*(lComp + id0), &errNum);
	box.i2.xMin -= bWidth;
	box.i2.yMin -= bWidth;
	box.i2.xMax += bWidth;
	box.i2.yMax += bWidth;
	(void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = WlzClipObjToBox2D(mObj, box.i2, &errNum);
      }
      else /* tObj->type == WLZ_3D_DOMAINOBJ */
      {
        box.i3 = WlzBoundingBox3I(*(lComp + id0), &errNum);
	box.i3.xMin -= bWidth;
	box.i3.yMin -= bWidth;
	box.i3.zMin -= bWidth;
	box.i3.xMax += bWidth;
	box.i3.yMax += bWidth;
	box.i3.zMax += bWidth;
	(void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = WlzClipObjToBox3D(mObj, box.i3, &errNum);
      }
      ++id0;
    }
  }
  *dstNComp = nLComp;
  *dstComp = lComp;
  return(errNum);
}
예제 #5
0
/*! 
* \return       projection object
* \ingroup      WlzTransform
* \brief        Use the view transform to define a projection from
*		3D to 2D. Currently only the domain is projected as
*		an opaque shadow.
*		This is old code temporarily kept for compatibility.
* \param    obj	source 3D object
* \param    viewStr	view structure defining the projection
* \param    intFunc	grey-value summation function
* \param    intFuncData data to be passed to the integration function
* \param    dstErr	error return
*/
WlzObject *WlzGetProjectionFromObject(
  WlzObject		*obj,
  WlzThreeDViewStruct 	*viewStr,
  Wlz3DProjectionIntFn 	intFunc,
  void			*intFuncData,
  WlzErrorNum		*dstErr)
{
  WlzObject		*rtnObj=NULL,
  			*obj1;
  WlzThreeDViewStruct	*viewStr1=NULL;
  WlzDomain		domain;
  WlzValues		values;
  WlzGreyType		srcGType = WLZ_GREY_UBYTE,
  			dstGType = WLZ_GREY_UBYTE;
  WlzPixelV		pixval;
  WlzPixelP		pixptr;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyValueWSpace	*gVWSp = NULL;
  WlzDVertex3		vtx, vtx1;
  double		x, y, z;
  double		*s_to_x=NULL;
  double		*s_to_y=NULL;
  double		*s_to_z=NULL;
  int			k, xp, yp, s, sp;
  int			length = 0, size = 0, occupiedFlg;
  WlzErrorNum 	errNum=WLZ_ERR_NONE;

  /* check inputs */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if( obj->type != WLZ_3D_DOMAINOBJ ){
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if( obj->domain.core == NULL ){
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if( obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN ){
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }

  if( (errNum == WLZ_ERR_NONE) && (viewStr == NULL) ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* create new view transform */
  if( errNum == WLZ_ERR_NONE ){
    if((viewStr1 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL){
      /* need to worry about fixed line mode here sometime */
      viewStr1->fixed = viewStr->fixed;
      viewStr1->theta = viewStr->theta;
      viewStr1->phi = viewStr->phi;
      viewStr1->zeta = viewStr->zeta;
      viewStr1->dist = viewStr->dist;
      viewStr1->scale = viewStr->scale;
      viewStr1->voxelSize[0] = viewStr->voxelSize[0];
      viewStr1->voxelSize[1] = viewStr->voxelSize[1];
      viewStr1->voxelSize[2] = viewStr->voxelSize[2];
      viewStr1->voxelRescaleFlg = viewStr->voxelRescaleFlg;
      viewStr1->interp = viewStr->interp;
      viewStr1->view_mode = viewStr->view_mode;
      viewStr1->up = viewStr->up;

      /* now intialize it */
      /* could optimise by setting fixed point to object centre */
      if( (errNum = WlzInit3DViewStruct(viewStr1, obj)) != WLZ_ERR_NONE ){
	WlzFree3DViewStruct(viewStr1);
	viewStr1 = NULL;
      }
    }
  }

  /* set up orthogonal line parameters & luts */
  if( errNum == WLZ_ERR_NONE ){
    length = WLZ_NINT(viewStr1->maxvals.vtZ) -
      WLZ_NINT(viewStr1->minvals.vtZ) + 1;
    s_to_x = (double *) AlcMalloc(sizeof(double) * length );
    s_to_y = (double *) AlcMalloc(sizeof(double) * length );
    s_to_z = (double *) AlcMalloc(sizeof(double) * length );

    /* transform a perpendicular vector */
    vtx.vtX = 0.0;
    vtx.vtY = 0.0;
    vtx.vtZ = 1.0;
    Wlz3DSectionTransformInvVtx(&vtx, viewStr1);
    vtx1.vtX = 0.0;
    vtx1.vtY = 0.0;
    vtx1.vtZ = 0.0;
    Wlz3DSectionTransformInvVtx(&vtx1, viewStr1);
    vtx.vtX -= vtx1.vtX;
    vtx.vtY -= vtx1.vtY;
    vtx.vtZ -= vtx1.vtZ;

    /* assign lut values */
    s = (int )(WLZ_NINT(viewStr1->minvals.vtZ) - viewStr1->dist);
    for(sp=0; sp < length; sp++, s++){
      s_to_x[sp] = s * vtx.vtX;
      s_to_y[sp] = s * vtx.vtY;
      s_to_z[sp] = s * vtx.vtZ;
    }
  }

  /* if there is an integration function then allocate space for
     the grey-level array */
  if( (errNum == WLZ_ERR_NONE) && (intFunc) ){
    srcGType = WlzGreyTypeFromObj(obj, &errNum);
    switch( srcGType ){
    case WLZ_GREY_LONG:
      size = sizeof(WlzLong)*length;
      break;
    case WLZ_GREY_INT:
      size = sizeof(int)*length;
      break;
    case WLZ_GREY_SHORT:
      size = sizeof(short)*length;
      break;
    case WLZ_GREY_UBYTE:
      size = sizeof(WlzUByte)*length;
      break;
    case WLZ_GREY_FLOAT:
      size = sizeof(float)*length;
      break;
    case WLZ_GREY_DOUBLE:
      size = sizeof(double)*length;
      break;
    case WLZ_GREY_RGBA:
      size = sizeof(int)*length;
      break;
    default:
      errNum = WLZ_ERR_GREY_TYPE;
      break;
    }
    if( (pixptr.p.inp = (int *) AlcMalloc(size)) == NULL ){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    pixptr.type = srcGType;

    /* set up the grey-value workspace for random access */
    gVWSp = WlzGreyValueMakeWSp(obj, &errNum);
  }

  /* create rectangular projection image */
  if( errNum == WLZ_ERR_NONE ){
    if((domain.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_RECT,
				     WLZ_NINT(viewStr1->minvals.vtY),
				     WLZ_NINT(viewStr1->maxvals.vtY),
				     WLZ_NINT(viewStr1->minvals.vtX),
				     WLZ_NINT(viewStr1->maxvals.vtX),
					 &errNum)) != NULL){
      values.core = NULL;
      if((rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain, values, NULL, NULL,
			       &errNum)) != NULL){
	/* note the grey-values required are determined by the integration
	   function. Here we use WlzUByte and reset later if needed */
	dstGType = WLZ_GREY_UBYTE;
	pixval.type = WLZ_GREY_UBYTE;
	pixval.v.ubv = (WlzUByte )0;
	if((values.v = WlzNewValueTb(rtnObj,
				     WlzGreyTableType(WLZ_GREY_TAB_RECT,
						      dstGType, NULL),
				     pixval, &errNum)) != NULL){
	  rtnObj->values = WlzAssignValues(values, &errNum);
	}
	else {
	  WlzFreeObj(rtnObj);
	  rtnObj = NULL;
	}
      }
      else {
	WlzFreeDomain(domain);
	domain.core = NULL;
      }
    }
  }

  /* scan image setting values */
  if( errNum == WLZ_ERR_NONE ){
    errNum = WlzInitGreyScan(rtnObj, &iwsp, &gwsp);
  }
  if( errNum == WLZ_ERR_NONE ){
    while( (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE ){
      yp = iwsp.linpos - WLZ_NINT(viewStr1->minvals.vtY);
      for(k=iwsp.lftpos; k <= iwsp.rgtpos; k++){
	xp = k - WLZ_NINT(viewStr1->minvals.vtX);
	vtx.vtX = viewStr1->xp_to_x[xp] + viewStr1->yp_to_x[yp];
	vtx.vtY = viewStr1->xp_to_y[xp] + viewStr1->yp_to_y[yp];
	vtx.vtZ = viewStr1->xp_to_z[xp] + viewStr1->yp_to_z[yp];

	/* get the projection values */
	/* if no function then just check for occupancy */
	if( intFunc == NULL ){
	  occupiedFlg = 0;
	  sp = (int )(viewStr1->dist - WLZ_NINT(viewStr1->minvals.vtZ));
	  for(; !occupiedFlg && (sp < length); sp++){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    if( WlzInsideDomain(obj, z, y, x, &errNum) ){
	      occupiedFlg = 1;
	    }
	  }
	  sp = (int )(viewStr1->dist - WLZ_NINT(viewStr1->minvals.vtZ) - 1);
	  for(; !occupiedFlg && (sp >= 0); sp--){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    if( WlzInsideDomain(obj, z, y, x, &errNum) ){
	      occupiedFlg = 1;
	    }
	  }

	  /* set the integrated value - only WlzUByte at the moment */
	  *(gwsp.u_grintptr.ubp) = (WlzUByte )occupiedFlg;
	  gwsp.u_grintptr.ubp++;
	}
	/* use integration function */
	else {
	  /* set array of pixel values */
	  for(sp=0; sp < length; sp++){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    WlzGreyValueGet(gVWSp, WLZ_NINT(z), WLZ_NINT(y),
			    WLZ_NINT(x));
	    switch( srcGType ){
	    case WLZ_GREY_LONG:
	      pixptr.p.lnp[sp] = gVWSp->gVal[0].lnv;
	      break;
	    case WLZ_GREY_INT:
	      pixptr.p.inp[sp] = gVWSp->gVal[0].inv;
	      break;
	    case WLZ_GREY_SHORT:
	      pixptr.p.shp[sp] = gVWSp->gVal[0].shv;
	      break;
	    case WLZ_GREY_UBYTE:
	      pixptr.p.ubp[sp] = gVWSp->gVal[0].ubv;
	      break;
	    case WLZ_GREY_FLOAT:
	      pixptr.p.flp[sp] = gVWSp->gVal[0].flv;
	      break;
	    case WLZ_GREY_DOUBLE:
	      pixptr.p.dbp[sp] = gVWSp->gVal[0].dbv;
	      break;
	    case WLZ_GREY_RGBA:
	      pixptr.p.rgbp[sp] = gVWSp->gVal[0].rgbv;
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	    }
	  }
	  /* call integration function and seet value */
	  intFunc(pixptr, length, (int )(viewStr1->dist -
		                         WLZ_NINT(viewStr1->minvals.vtZ)),
		  intFuncData, &errNum);
	}
      }
    }
    (void )WlzEndGreyScan(&iwsp, &gwsp);
    if(errNum == WLZ_ERR_EOO)	   /* Reset error from end of intervals */ 
    {
      errNum = WLZ_ERR_NONE;
    }

    /* if no integration function then threshold - binary only */
    if( intFunc == NULL ){
      pixval.v.ubv = 1;
      rtnObj = WlzAssignObject(rtnObj, NULL);
      if((obj1 = WlzThreshold(rtnObj, pixval, WLZ_THRESH_HIGH,
                              &errNum)) != NULL){
	WlzFreeObj(rtnObj);
	values.core = NULL;
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, obj1->domain, values, NULL, NULL,
			     &errNum);
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
  }

  /* clear space */
  if( viewStr1 ){
    errNum = WlzFree3DViewStruct(viewStr1);
  }
  if( s_to_x ){
    AlcFree( s_to_x );
  }
  if( s_to_y ){
    AlcFree( s_to_y );
  }
  if( s_to_z ){
    AlcFree( s_to_z );
  }

  /* check error and return */
  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
예제 #6
0
/*!
* \return	New object or NULL on error.
* \ingroup	WlzValuesUtils
* \brief 	Transfers grey values from the source object to the
*               destination object within the intersection of the source
*               and destination. Grey values within the destination
*               object outside of the source object are unchanged.
*               It is an error if either object has a different dimension
*               or grey value type, except for when either is an empty
*               object.
* \param	dObj			Destination object which may be
* 					empty, but otherwise should be of the
* 					same dimension as the source object
* 					with valid values..
* \param	sObj			Source object which if not empty must
* 					have both a valid domain and valid
* 					values.
* \param	inplace			Overwrite the destination object's
* 					values if non zero.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject			*WlzGreyTransfer(
				  WlzObject *dObj,
				  WlzObject *sObj,
				  int inplace,
				  WlzErrorNum *dstErr)
{
  WlzObject	*rObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if((dObj == NULL) || (sObj == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(WlzIsEmpty(dObj, NULL))
  {
    rObj = WlzMakeEmpty(&errNum);
  }
  else if(WlzIsEmpty(sObj, NULL))
  {
    rObj = WlzMakeMain(dObj->type, dObj->domain, dObj->values,
                       dObj->plist, NULL, &errNum);
  }
  else if(dObj->type != sObj->type)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if((dObj->domain.core == NULL) || (sObj->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(sObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    switch(sObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
      case WLZ_3D_DOMAINOBJ: /* FALLTHROUGH */
        {
	  WlzObject	*rIObj = NULL;

	  rIObj = WlzIntersect2(dObj, sObj, &errNum);
	  if((errNum == WLZ_ERR_NONE) && (WlzIsEmpty(rIObj, NULL) == 0))
	  {
	    rObj = (inplace)?
		   WlzMakeMain(dObj->type, dObj->domain, dObj->values,
			       dObj->plist, NULL, &errNum):
		   WlzCopyObject(dObj, &errNum);
	    if(errNum == WLZ_ERR_NONE)
	    {
	      /* If the destination object does not have values then
	       * create them to match the domain of the destination
	       * object. */
	      if((sObj->values.core != NULL) && (rObj->values.core == NULL))
	      {
		WlzPixelV bgdV;
		WlzGreyType gType;
		WlzObjectType gTT;
		WlzValues	newVal;

		newVal.core = NULL;
		bgdV = WlzGetBackground(sObj, &errNum);
		if(errNum == WLZ_ERR_NONE)
		{
		  gType = WlzGreyTypeFromObj(sObj, &errNum);
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  gTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gType, NULL);
		  if(rObj->type == WLZ_2D_DOMAINOBJ)
		  {
		    newVal.v = WlzNewValueTb(rObj, gTT, bgdV, &errNum);
		  }
		  else /* rObj->type == WLZ_3D_DOMAINOBJ */
		  {
		    newVal.vox = WlzNewValuesVox(rObj, gTT, bgdV, &errNum);
		  }
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  rObj->values = WlzAssignValues(newVal, NULL);
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = WlzGreySetValue(rObj, bgdV);
		}
	      }
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      if(sObj->type == WLZ_2D_DOMAINOBJ)
	      {
		WlzObject *sIObj;

		rIObj->values = WlzAssignValues(rObj->values, NULL);
		sIObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				    rIObj->domain, sObj->values,
				    NULL, NULL, &errNum);
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = WlzGreyTransfer2D(rIObj, sIObj);
		}
		(void )WlzFreeObj(sIObj);
	      }
	      else /* sObj->type == WLZ_3D_DOMAINOBJ */
	      {
		int	p,
			  rTiled,
			  sTiled,
			  nPlanes;

		rTiled = WlzGreyTableIsTiled(rObj->values.core->type);
		sTiled = WlzGreyTableIsTiled(sObj->values.core->type);
		nPlanes = rIObj->domain.p->lastpl - rIObj->domain.p->plane1 + 1;
#ifdef _OPENMP
#pragma omp parallel for
#endif
		for(p = 0; p < nPlanes; ++p)
		{
		  if(errNum == WLZ_ERR_NONE)
		  {
		    int	     pln;
		    WlzDomain  dom;
		    WlzValues  val;
		    WlzObject  *rIObj2D = NULL,
			       *sIObj2D = NULL;
		    WlzErrorNum errNum2D = WLZ_ERR_NONE;

		    pln = p + rIObj->domain.p->plane1;
		    dom = rIObj->domain.p->domains[p];
		    val = (rTiled)?
			  rObj->values:
			  rObj->values.vox->values[pln -
						   rObj->values.vox->plane1];
		    rIObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ,
					  dom, val, NULL, NULL, &errNum2D);
		    if(errNum2D == WLZ_ERR_NONE)
		    {
		      val = (sTiled)?
			    sObj->values:
			    sObj->values.vox->values[pln -
						     sObj->values.vox->plane1];
		      sIObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ,
					    dom, val, NULL, NULL, &errNum2D);
		    }
		    if(errNum2D == WLZ_ERR_NONE)
		    {
		      errNum2D = WlzGreyTransfer2D(rIObj2D, sIObj2D);
		    }
		    (void )WlzFreeObj(rIObj2D);
		    (void )WlzFreeObj(sIObj2D);
#ifdef _OPENMP
#pragma omp critical
		    {
#endif
		      if((errNum == WLZ_ERR_NONE) && (errNum2D != WLZ_ERR_NONE))
		      {
			errNum = errNum2D;
		      }
#ifdef _OPENMP
		    }
#endif
		  }
		}
	      }
	    }
	  }
	  (void )WlzFreeObj(rIObj);
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
        break;
    }
  }
  if(errNum != WLZ_ERR_NONE)
  {
    WlzFreeObj(rObj);
    rObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rObj);
}
예제 #7
0
/*! 
* \ingroup      WlzValuesFilters
* \brief        Set new grey-range by simple linear interpolation. It
 assumes that the min and max values enclose the true range of
 grey-values in the object. Failure to check this could result in a
 segmentation fault.

The transform function is:
\f[g' = \frac{(gMax - gMin)}{(gmax - gmin)} (g - gmin) + gMin + \delta
\f]
Here \f$\delta\f$ is the dither value.
*
* \return       Woolz error number
* \param    obj	Input grey-level object whose values are to be reset.
* \param    min	Initial minimum value
* \param    max	Initial maximum value
* \param    Min	Final minimum value
* \param    Max	Final maximum value
* \param    Dither values if destination range is greater than source range
*           and this flag is non-zero.
* \par      Source:
*                WlzGreySetRange.c
*/
WlzErrorNum WlzGreySetRange(
  WlzObject	*obj,
  WlzPixelV	min,
  WlzPixelV	max,
  WlzPixelV	Min,
  WlzPixelV	Max,
  int		dither)
{
  double		gMin = 0.0,
  			gMax = 0.0,
			sigma = 0.0,
  			factor,
			val;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyP		gptr;
  WlzObject		*tempobj;
  WlzValues 		*values;
  WlzDomain		*domains;
  int			i, j, nplanes;
  WlzErrorNum		errNum = WLZ_ERR_NONE;

  /* check object */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  if( errNum == WLZ_ERR_NONE ){
    switch( obj->type ){

    case WLZ_2D_DOMAINOBJ:
      if( obj->domain.i == NULL ){
	return WLZ_ERR_DOMAIN_NULL;
      }
      if( obj->values.core == NULL ){
	return WLZ_ERR_VALUES_NULL;
      }
      if( WlzGreyTableIsTiled(obj->values.core->type) ){
	return WLZ_ERR_VALUES_TYPE;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      /* check planedomain and voxeltable */
      if( obj->domain.p == NULL ){
	return WLZ_ERR_DOMAIN_NULL;
      }
      if( obj->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN ){
	return WLZ_ERR_PLANEDOMAIN_TYPE;
      }
      if( obj->values.vox == NULL ){
	return WLZ_ERR_VALUES_NULL;
      }
      if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){
	return WLZ_ERR_VOXELVALUES_TYPE;
      }

      /* set range of each plane if non-empty - indicated by NULL */
      domains = obj->domain.p->domains;
      values = obj->values.vox->values;
      nplanes = obj->domain.p->lastpl - obj->domain.p->plane1 + 1;
      for(i=0; i < nplanes; i++, domains++, values++){

	if( (*domains).core == NULL || (*values).core == NULL ){
	  continue;
	}

	tempobj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
			      *domains, *values, NULL, NULL,
			      &errNum);
	if((tempobj == NULL) && (errNum == WLZ_ERR_NONE) ){
	  errNum = WLZ_ERR_UNSPECIFIED;
	  break;
	}

	errNum = WlzGreySetRange(tempobj, min, max, Min, Max, dither);
	WlzFreeObj( tempobj );
	if( errNum != WLZ_ERR_NONE ){
	  break;
	}
      }
      
      return errNum;

    case WLZ_TRANS_OBJ:
      return WlzGreySetRange(obj->values.obj, min, max, Min, Max, dither);

    case WLZ_EMPTY_OBJ:
      return errNum;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    /* get conversion function - should use LUT
       use 4 LUTS for rgb type since bounded */
    if( WlzGreyTypeFromObj(obj, &errNum) == WLZ_GREY_RGBA ){
      WlzUByte	rgbaLut[4][256];
      WlzUInt	rgbamin[4], rgbaMin[4];
      double	rgbaFactor[4], val1;
      WlzUInt	red, green, blue, alpha;

      rgbamin[0] = WLZ_RGBA_RED_GET(min.v.rgbv);
      rgbaMin[0] = WLZ_RGBA_RED_GET(Min.v.rgbv);
      if(WLZ_RGBA_RED_GET(max.v.rgbv) > WLZ_RGBA_RED_GET(min.v.rgbv)){
	rgbaFactor[0] = (((double) WLZ_RGBA_RED_GET(Max.v.rgbv) - 
			  WLZ_RGBA_RED_GET(Min.v.rgbv))/
			 (WLZ_RGBA_RED_GET(max.v.rgbv) - 
			  WLZ_RGBA_RED_GET(min.v.rgbv)));
      }
      else {
	rgbaFactor[0] = 0.0;
      }

      rgbamin[1] = WLZ_RGBA_GREEN_GET(min.v.rgbv);
      rgbaMin[1] = WLZ_RGBA_GREEN_GET(Min.v.rgbv);
      if(WLZ_RGBA_GREEN_GET(max.v.rgbv) > WLZ_RGBA_GREEN_GET(min.v.rgbv)){
	rgbaFactor[1] = (((double) WLZ_RGBA_GREEN_GET(Max.v.rgbv) - 
			  WLZ_RGBA_GREEN_GET(Min.v.rgbv))/
			 (WLZ_RGBA_GREEN_GET(max.v.rgbv) - 
			  WLZ_RGBA_GREEN_GET(min.v.rgbv)));
      }
      else {
	rgbaFactor[1] = 0.0;
      }

      rgbamin[2] = WLZ_RGBA_BLUE_GET(min.v.rgbv);
      rgbaMin[2] = WLZ_RGBA_BLUE_GET(Min.v.rgbv);
      if(WLZ_RGBA_BLUE_GET(max.v.rgbv) > WLZ_RGBA_BLUE_GET(min.v.rgbv)){
	rgbaFactor[2] = (((double) WLZ_RGBA_BLUE_GET(Max.v.rgbv) - 
			  WLZ_RGBA_BLUE_GET(Min.v.rgbv))/
			 (WLZ_RGBA_BLUE_GET(max.v.rgbv) - 
			  WLZ_RGBA_BLUE_GET(min.v.rgbv)));
      }
      else {
	rgbaFactor[2] = 0.0;
      }

      rgbamin[3] = WLZ_RGBA_ALPHA_GET(min.v.rgbv);
      rgbaMin[3] = WLZ_RGBA_ALPHA_GET(Min.v.rgbv);
      if(WLZ_RGBA_ALPHA_GET(max.v.rgbv) > WLZ_RGBA_ALPHA_GET(min.v.rgbv)){
	rgbaFactor[3] = (((double) WLZ_RGBA_ALPHA_GET(Max.v.rgbv) - 
			  WLZ_RGBA_ALPHA_GET(Min.v.rgbv))/
			 (WLZ_RGBA_ALPHA_GET(max.v.rgbv) - 
			  WLZ_RGBA_ALPHA_GET(min.v.rgbv)));
      }
      else {
	rgbaFactor[3] = 0.0;
      }

      /* now set up the LUTS */
      for(i=0; i < 4; i++){
	for(j=0; j < 256; j++){
	  val1 = rgbaFactor[i] * (j - rgbamin[i]) + rgbaMin[i];
	  rgbaLut[i][j] = (WlzUByte )WLZ_CLAMP(val1, 0, 255);
	}
      }

      /* set values - can assume rgba grey-type */
      errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
      if(errNum == WLZ_ERR_NONE) {
	while( WlzNextGreyInterval(&iwsp) == WLZ_ERR_NONE ){

	  gptr = gwsp.u_grintptr;
	  for (i=0; i<iwsp.colrmn; i++, gptr.rgbp++){
	    red = rgbaLut[0][WLZ_RGBA_RED_GET(*gptr.rgbp)];
	    green = rgbaLut[0][WLZ_RGBA_GREEN_GET(*gptr.rgbp)];
	    blue = rgbaLut[0][WLZ_RGBA_BLUE_GET(*gptr.rgbp)];
	    alpha = rgbaLut[0][WLZ_RGBA_ALPHA_GET(*gptr.rgbp)];
	    WLZ_RGBA_RGBA_SET(*gptr.rgbp, red, green, blue, alpha);
	  }
	}
	(void )WlzEndGreyScan(&iwsp, &gwsp);
	if(errNum == WLZ_ERR_EOO){
	  errNum = WLZ_ERR_NONE;
	}
      }
    }
    else {
      WlzValueConvertPixel(&min, min, WLZ_GREY_DOUBLE);
      WlzValueConvertPixel(&max, max, WLZ_GREY_DOUBLE);
      WlzValueConvertPixel(&Min, Min, WLZ_GREY_DOUBLE);
      WlzValueConvertPixel(&Max, Max, WLZ_GREY_DOUBLE);
      if( fabs(max.v.dbv - min.v.dbv) < DBL_EPSILON ){
	return WLZ_ERR_FLOAT_DATA;
      }
      errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
      if(errNum == WLZ_ERR_NONE) {
	factor = (Max.v.dbv - Min.v.dbv) / (max.v.dbv - min.v.dbv);
	if(dither)
	{
	  if(fabs(factor) < 1.0 + DBL_EPSILON)
	  {
	    dither = 0;
	  }
	  else
	  {
	    sigma = fabs(2.0 / factor);
	    AlgRandSeed(101);
	    switch(gwsp.pixeltype) {
	      case WLZ_GREY_INT:
		gMin = ALG_MAX(Min.v.dbv, INT_MIN);
		gMax = ALG_MIN(Max.v.dbv, INT_MAX);
		break;
	      case WLZ_GREY_SHORT:
		gMin = ALG_MAX(Min.v.dbv, SHRT_MIN);
		gMax = ALG_MIN(Max.v.dbv, SHRT_MAX);
		break;
	      case WLZ_GREY_UBYTE:
		gMin = ALG_MAX(Min.v.dbv, 0);
		gMax = ALG_MIN(Max.v.dbv, 255);
		break;
	      case WLZ_GREY_FLOAT:
		gMin = ALG_MAX(Min.v.dbv, FLT_MIN);
		gMax = ALG_MIN(Max.v.dbv, FLT_MAX);
		break;
	      case WLZ_GREY_DOUBLE:
		gMin = Min.v.dbv;
		gMax = Max.v.dbv;
		break;
	      default:
		break;
	    }
	  }
	}
	while((errNum == WLZ_ERR_NONE) &&
	      ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)){
	  gptr = gwsp.u_grintptr;
	  switch (gwsp.pixeltype) {
	    case WLZ_GREY_INT:
	      for (i=0; i<iwsp.colrmn; i++, gptr.inp++){
		if(dither){
		  val = factor * (*gptr.inp +
				  AlgRandZigNormal(0.0, sigma) -
				  min.v.dbv) + Min.v.dbv;
		  val = WLZ_CLAMP(val, gMin, gMax);
		} else {
		  val = factor * (*gptr.inp - min.v.dbv) + Min.v.dbv;
		}
		*gptr.inp = WLZ_NINT(val);
	      }
	      break;
	    case WLZ_GREY_SHORT:
	      for (i=0; i<iwsp.colrmn; i++, gptr.shp++){
		if(dither){
		  val = factor * (*gptr.shp +
				  AlgRandZigNormal(0.0, sigma) -
				  min.v.dbv) + Min.v.dbv;
		  val = WLZ_CLAMP(val, gMin, gMax);
		} else {
		  val = factor * (*gptr.shp - min.v.dbv) + Min.v.dbv;
		}
		*gptr.shp = (short )WLZ_NINT(val);
	      }
	      break;
	    case WLZ_GREY_UBYTE:
	      for (i=0; i<iwsp.colrmn; i++, gptr.ubp++){
		if(dither){
		  val = factor * (*gptr.ubp +
				  AlgRandZigNormal(0.0, sigma) -
				  min.v.dbv) + Min.v.dbv;
		  val = WLZ_CLAMP(val, gMin, gMax);
		} else {
		  val = factor * (*gptr.ubp - min.v.dbv) + Min.v.dbv;
		}
		*gptr.ubp = (WlzUByte )WLZ_NINT(val);
	      }
	      break;
	    case WLZ_GREY_FLOAT:
	      for (i=0; i<iwsp.colrmn; i++, gptr.flp++){
		if(dither){
		  val = factor * (*gptr.flp +
				  AlgRandZigNormal(0.0, sigma) -
				  min.v.dbv) + Min.v.dbv;
		  val = WLZ_CLAMP(val, gMin, gMax);
		} else {
		  val = factor * (*gptr.flp - min.v.dbv) + Min.v.dbv;
		}
		*gptr.flp = (float )val;
	      }
	      break;
	    case WLZ_GREY_DOUBLE:
	      for (i=0; i<iwsp.colrmn; i++, gptr.dbp++){
		if(dither){
		  val = factor * (*gptr.dbp +
				  AlgRandZigNormal(0.0, sigma) -
				  min.v.dbv) + Min.v.dbv;
		  val = WLZ_CLAMP(val, gMin, gMax);
		} else {
		  val = factor * (*gptr.dbp - min.v.dbv) + Min.v.dbv;
		}
		*gptr.dbp = val;
	      }
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	  }
	}
	(void )WlzEndGreyScan(&iwsp, &gwsp);
	if(errNum == WLZ_ERR_EOO){
	  errNum = WLZ_ERR_NONE;
	}
      }
    }
  }
  return errNum;
}
예제 #8
0
/*!
* \return	New 2D domain object.
* \ingroup	WlzArithmetic
* \brief	Computes a new 2D object which shares the domain of the given
*		object, but which has grey values that are the result of
*		applying the given function to the grey values of the
*		given object.
* \param	sObj			Given source domain object with values.
* \param	fn			Scalar function to be applied.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzScalarFn2D(WlzObject *sObj, WlzFnType fn,
			        WlzErrorNum *dstErr)
{
  WlzGreyType	sGType,
  		dGType;
  WlzPixelV	sBgd,
  		dBgd;
  WlzObjectType	dVType;
  WlzObject     *dObj = NULL;
  WlzValues	dVal;
  WlzIntervalWSpace sIWSp,
  		dIWSp;
  WlzGreyWSpace	sGWSp,
  		dGWSp;
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  sGType = WlzGreyTypeFromObj(sObj, &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    dGType = WlzScalarFnPromoteGType(fn, sGType, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dVType = WlzGreyTableType(WLZ_GREY_TAB_RAGR, dGType, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    sBgd = WlzGetBackground(sObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dBgd = WlzScalarFnPixel(sBgd, fn, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dVal.v = WlzNewValueTb(sObj, dVType, dBgd, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
    		       sObj->domain, dVal, NULL, NULL, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzInitGreyScan(sObj, &sIWSp, &sGWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzInitGreyScan(dObj, &dIWSp, &dGWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    while((errNum == WLZ_ERR_NONE) &&
          ((errNum = WlzNextGreyInterval(&sIWSp)) == WLZ_ERR_NONE) &&
          ((errNum = WlzNextGreyInterval(&dIWSp)) == WLZ_ERR_NONE))
    {
      int	len;
      WlzGreyP	dGP,
      		sGP;

      len = sIWSp.rgtpos - sIWSp.lftpos + 1;
      dGP = dGWSp.u_grintptr;
      sGP = sGWSp.u_grintptr;
      WlzValueCopyGreyToGrey(dGP, 0, dGType, sGP, 0, sGType, len);
      WlzScalarFnItv(dGP, dGType, len, fn);
    }
    if(errNum == WLZ_ERR_EOO)
    {
      errNum = WLZ_ERR_NONE;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dObj);
}
예제 #9
0
/*!
* \return	New Gaussian filtered object with new values or NULL on error.
* \ingroup	WlzValuesFilters
* \brief	Applies a Gaussian filter to the given input spatial domain
* 		object. Only scalar valued image objects are valid for use
* 		with this function.
* \param	inObj			Input 2 or 3D spatial domain object
* 					which must have values.
* \param	sigma			Gaussian sigma values for each of the
* 					Cartesian directions.
* \param	order			Derivative order for each of the
* 					Cartesian directions, range 0-2,
* 					where 0 implies no derivative.
* \param	direc			Required Cartesian directions, with
* 					zero value indicating that no filtering
* 					is to be applied for a direction.
* \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			*WlzGaussFilter(
				  WlzObject *inObj,
				  WlzDVertex3 sigma,
				  WlzIVertex3 order,
				  WlzIVertex3 direc,
				  WlzGreyType gType,
				  AlgPadType pad,
				  double padVal,
				  WlzErrorNum *dstErr)
{
  int		dim = 0;
  double	*cBuf[3] = {NULL};
  WlzIVertex3   cBufSz = {0};
  WlzObject	*rnObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const int	maxOrder = 2;
  const double  nSigma = 3.0,
  		sigmaMin = 0.0001;

  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 if((sigma.vtX < sigmaMin) || (sigma.vtY < sigmaMin) ||
          (order.vtX < 0) || (order.vtX > maxOrder) ||
	  (order.vtY < 0) || (order.vtY > maxOrder))
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else
  {
    switch(inObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
        dim = 2;
	break;
      case WLZ_3D_DOMAINOBJ:
        dim = 3;
	if((sigma.vtZ < sigmaMin) ||
	   (order.vtZ < 0) || (order.vtZ > maxOrder))
	{
	  errNum = WLZ_ERR_PARAM_DATA;
	}
        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)
  {
    cBufSz.vtX = (int )floor(nSigma * sigma.vtX);
    cBufSz.vtY = (int )floor(nSigma * sigma.vtY);
    if(errNum == WLZ_ERR_NONE)
    {
      if(dim == 3)
      {
	cBufSz.vtZ = (int )floor(nSigma * sigma.vtZ);
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    int		cSz;

    cSz = (cBufSz.vtX + cBufSz.vtY + cBufSz.vtZ + 3) * 2;
    if((cBuf[0] = (double *)AlcMalloc(sizeof(double) * cSz)) == NULL)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    cBuf[1] = cBuf[0] + 1 + (2 * cBufSz.vtX);
    cBuf[2] = cBuf[1] + 1 + (2 * cBufSz.vtY);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    int		idd;

    for(idd = 0; idd < dim; ++idd)
    {
      int	n,
		odr;
      double	*cb;

      cb = cBuf[idd];
      switch(idd)
      {
        case 0:
	  n = cBufSz.vtX;
	  odr = order.vtX;
	  break;
	case 1:
	  n = cBufSz.vtY;
	  odr = order.vtY;
	  break;
	case 2:
	  n = cBufSz.vtZ;
	  odr = order.vtZ;
	  break;
	default:
	  break;
      }
      /* Set convolution buffers. */
      {
	int	i;
	double	g,
		s,
		t,
		nsn,
		nrm;

	nrm = 0.0;
	nsn = nSigma / n;
	switch(odr)
	{
	  case 0:
	    for(i = 0; i <= n; ++i)
	    {
	      s = n - i;
	      t = s * nsn;
	      g = exp(-0.5 * t * t);
	      nrm += g;
	      cb[i] = g;
	    }
	    nrm = 1.0 / ((2.0 * nrm) - cb[n]);
	    for(i = 0; i <= n; ++i)
	    {
	      cb[i] *= nrm;
	    }
	    for(i = 1; i <= n; ++i)
	    {
	      cb[n + i] = cb[n - i]; 
	    }
	    break;
	  case 1:
	    for(i = 0; i <= n; ++i)
	    {
	      s = n - i;
	      t = s * nsn;
	      g = exp(-0.5 * t * t) * s;
	      nrm += g;
	      cb[i] = g;
	    }
	    nrm = 1.0 / ((2.0 * nrm) - cb[n]);
	    for(i = 0; i <= n; ++i)
	    {
	      cb[i] *= nrm;
	    }
	    for(i = 1; i <= n; ++i)
	    {
	      cb[n + i] = -cb[n - i]; 
	    }
	    break;
	  case 2:
	    for(i = 0; i <= n; ++i)
	    {
	      s = n - i;
	      t = s * nsn;
	      g = exp(-0.5 * t * t) * (s * s - nSigma * nSigma); 
	      nrm += g;
	      cb[i] = g;
	    }
	    nrm = -1.0 / ((2.0 * nrm) - cb[n]);
	    for(i = 0; i <= n; ++i)
	    {
	      cb[i] *= nrm;
	    }
	    for(i = 1; i <= n; ++i)
	    {
	      cb[n + i] = cb[n - i]; 
	    }
	    break;
	  default:
	    break;
	}
#ifdef WLZ_SEPFILTER_DEBUG
	for(i = 0; i < (2 * n) + 1; ++i)
	{
	  (void )fprintf(stderr, "%g\n", cb[i]);
	}
	(void )fprintf(stderr, "\n");
#endif /* WLZ_SEPFILTER_DEBUG */
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    rnObj = WlzSepFilter(inObj, cBufSz, cBuf, direc, gType, pad, padVal,
    			 &errNum);
  }
  AlcFree(cBuf[0]);
  if(errNum != WLZ_ERR_NONE)
  {
    WlzFreeObj(rnObj);
    rnObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rnObj);
}
예제 #10
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        Convert a RGBA image to a compound object. The RGBA
*		 channels are at array indices 0,1,2,3 respectively
*		 and the sub-object grey types will be WLZ_GREY_UBYTE.
*
* \return       Compound array of rgba values
* \param    obj				Input domain object with value type
* 					WLZ_GREY_RGBA
* \param    colSpc			The colour space.
* \param    dstErr			Destination error ponyer, may be NULL.
*/
WlzCompoundArray *WlzRGBAToCompound(
  WlzObject	*obj,
  WlzRGBAColorSpace	colSpc,
  WlzErrorNum	*dstErr)
{
  WlzCompoundArray	*cobj=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 WlzRGBAToCompound3D(obj, colSpc, 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 (WlzCompoundArray *) WlzMakeEmpty(dstErr);

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

  /* check colour space */
  if( errNum == WLZ_ERR_NONE ){
    switch( colSpc ){
    case WLZ_RGBA_SPACE_RGB:
    case WLZ_RGBA_SPACE_HSB:
    case WLZ_RGBA_SPACE_CMY:
      break;

    default:
      errNum = WLZ_ERR_PARAM_DATA;
      break;
    }
  }

  /* create compound object return */
  if( errNum == WLZ_ERR_NONE ){
    WlzValues	values;
    WlzObject	*objs[4];
    WlzObjectType	type;
    WlzPixelV	oldBck, newBck;

    type = WlzGreyTableType(
      WlzGreyTableTypeToTableType(obj->values.core->type, &errNum),
      WLZ_GREY_UBYTE, &errNum);
    oldBck = WlzGetBackground(obj, &errNum);

    /* red */
    newBck.type = WLZ_GREY_UBYTE;
    newBck.v.ubv = (WlzUByte )WLZ_RGBA_RED_GET(oldBck.v.rgbv);
    values.v = WlzNewValueTb(obj, type, newBck, &errNum);
    objs[0] = WlzMakeMain(obj->type, obj->domain, values,
			  NULL, NULL, &errNum);
    /* green */
    newBck.v.ubv = (WlzUByte )WLZ_RGBA_GREEN_GET(oldBck.v.rgbv);
    values.v = WlzNewValueTb(obj, type, newBck, &errNum);
    objs[1] = WlzMakeMain(obj->type, obj->domain, values,
			  NULL, NULL, &errNum);
    /* blue */
    newBck.v.ubv = (WlzUByte )WLZ_RGBA_BLUE_GET(oldBck.v.rgbv);
    values.v = WlzNewValueTb(obj, type, newBck, &errNum);
    objs[2] = WlzMakeMain(obj->type, obj->domain, values,
			  NULL, NULL, &errNum);
    /* alpha */
    newBck.v.ubv = (WlzUByte )WLZ_RGBA_ALPHA_GET(oldBck.v.rgbv);
    values.v = WlzNewValueTb(obj, type, newBck, &errNum);
    objs[3] = WlzMakeMain(obj->type, obj->domain, values,
			  NULL, NULL, &errNum);

    /* create compound object, object pointers are assigned for mode=3
       so no need to free objects */
    cobj = WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 3, 4, &(objs[0]),
				 obj->type, &errNum);
  }

  /* iterate through objects setting values */
  if( errNum == WLZ_ERR_NONE ){
    WlzIntervalWSpace	iwsp0, iwsp[4];
    WlzGreyWSpace	gwsp0, gwsp[4];
    int			i, j, k;
    int			a, col[3];

    errNum = WlzInitGreyScan(obj, &iwsp0, &gwsp0);
    for(i=0; i < 4; i++){
      errNum = WlzInitGreyScan(cobj->o[i], &(iwsp[i]), &(gwsp[i]));
    }
    while((errNum == WLZ_ERR_NONE) &&
	  ((errNum = WlzNextGreyInterval(&iwsp0)) == WLZ_ERR_NONE)){
      for(i=0; i < 4; i++){
	errNum = WlzNextGreyInterval(&(iwsp[i]));
      }
      switch( colSpc ){
      case WLZ_RGBA_SPACE_RGB:
	for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++,
	      gwsp0.u_grintptr.rgbp++){
	  *(gwsp[0].u_grintptr.ubp++) =
	    (WlzUByte )WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp));
	  *(gwsp[1].u_grintptr.ubp++) =
	    (WlzUByte )WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp));
	  *(gwsp[2].u_grintptr.ubp++) =
	    (WlzUByte )WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp));
	  *(gwsp[3].u_grintptr.ubp++) =
	    (WlzUByte )WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp));
	}
	break;
      
      case WLZ_RGBA_SPACE_HSB: /* each normalised to [0,255] */
	for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++,
	      gwsp0.u_grintptr.rgbp++){
	  col[0] = WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp));
	  col[1] = WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp));
	  col[2] = WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp));
	  a = WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp));
	  WlzRGBAConvertRGBToHSV_UBYTENormalised(col);
	  *(gwsp[0].u_grintptr.ubp++) = (WlzUByte )(col[0]);
	  *(gwsp[1].u_grintptr.ubp++) = (WlzUByte )(col[1]);
	  *(gwsp[2].u_grintptr.ubp++) = (WlzUByte )(col[2]);
	  *(gwsp[3].u_grintptr.ubp++) = (WlzUByte )a;
	    }
	break;
      
      case WLZ_RGBA_SPACE_CMY:
	for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++,
	      gwsp0.u_grintptr.rgbp++){
	  col[0] = WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp));
	  col[1] = WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp));
	  col[2] = WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp));
	  a = WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp));
	  *(gwsp[0].u_grintptr.ubp++) = (WlzUByte )((col[1] + col[2]) / 2);
	  *(gwsp[1].u_grintptr.ubp++) = (WlzUByte )((col[2] + col[0]) / 2);
	  *(gwsp[2].u_grintptr.ubp++) = (WlzUByte )((col[0] + col[1]) / 2);
	  *(gwsp[3].u_grintptr.ubp++) = (WlzUByte )a;
	    }
	break;
      default:
        errNum = WLZ_ERR_GREY_TYPE;
	break;
      }
    }
    if( errNum == WLZ_ERR_EOO ){
      errNum = WLZ_ERR_NONE;
    }
  }
      

  if( dstErr ){
    *dstErr = errNum;
  }
  return cobj;
}
예제 #11
0
int             main(int argc, char *argv[])
{
  int		option,
		nReg = 0,
		tNReg = 0,
  		ok = 1,
		usage = 0,
		verbose = 0,
		threshSet = 0,
		centreSet = 0;
  double	minArea = 2;
  char		*inExt,
		*dbgExt,
		*inDir,
		*dbgDir,
		*inFile,
		*dbgFile,
  		*inPath = NULL,
		*dbgPath = NULL,
		*outFile = NULL;
  WlzRadDistVal distSort = WLZ_RADDISTVAL_AREA;
  WlzRadDistRec	*distData = NULL;
  WlzPixelV	thrVal;
  WlzDVertex2	centre;
  WlzCompThreshType thrMtd = WLZ_COMPTHRESH_OTSU;
  WlzThresholdType thrMod = WLZ_THRESH_HIGH;
  WlzEffFormat	inFmt = WLZEFF_FORMAT_NONE,
  		dbgFmt = WLZEFF_FORMAT_NONE;
  WlzObject	*inObj = NULL,
		*disObj = NULL,
  		*segObj = NULL;
  WlzGreyValueWSpace *disGVWSp = NULL;
  WlzObject	**regObjs = NULL;
  FILE		*fP = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const int	maxObj = 1000000;
  char		pathBuf[FILENAME_MAX];
  const double	eps = 1.0e-06;
  const char	*errMsg;
  static char	optList[] = "hvAGDHELR:c:d:n:o:t:",
		defFile[] = "-";

  thrVal.type = WLZ_GREY_DOUBLE;
  thrVal.v.dbv = 0.0;
  outFile = defFile;
  while((usage == 0) && ok &&
        ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'A':
        distSort = WLZ_RADDISTVAL_AREA;
	break;
      case 'D':
        distSort = WLZ_RADDISTVAL_DIST;
	break;
      case 'G':
        distSort = WLZ_RADDISTVAL_ANGLE;
	break;
      case 'H':
        thrMod = WLZ_THRESH_HIGH;
	break;
      case 'E':
        thrMod = WLZ_THRESH_EQUAL;
	break;
      case 'L':
        thrMod = WLZ_THRESH_LOW;
	break;
      case 'R':
        distSort = WLZ_RADDISTVAL_RADIUS;
	break;
      case 'h':
        usage = 1;
	break;
      case 'v':
        verbose = 1;
	break;
      case 'c':
	centreSet = 1;
        if(sscanf(optarg, "%lg,%lg", &(centre.vtX), &(centre.vtY)) != 2)
	{
	  usage = 1;
	}
        break;
      case 'd':
        dbgPath = optarg;
	break;
      case 'o':
        outFile = optarg;
	break;
      case 'n':
        if(sscanf(optarg, "%lg", &minArea) != 1)
	{
	  usage = 1;
	}
	break;
      case 't':
	threshSet = 1;
        if(sscanf(optarg, "%lg", &(thrVal.v.dbv)) != 1)
	{
	  usage = 1;
	}
	break;
      default:
        usage = 1;
	break;
    }
  }
  ok = !usage;
  if(ok)
  {
    if((optind + 1) != argc)
    {
      usage = 1;
      ok = 0;
    }
    else
    {
      inPath = *(argv + optind);
    }
  }
  if(ok && verbose)
  {
    (void )fprintf(stderr, "inPath = %s\n", inPath);
  }
  /* Parse input file path into path + name + ext. */
  if(ok)
  {
    ok = (usage = WlzRadDistParsePath(inPath, &inDir, &inFile, &inExt,
                                      &inFmt)) == 0;
  }
  if(ok && verbose)
  {
    (void )fprintf(stderr, "inDir = %s\n", inDir);
    (void )fprintf(stderr, "inFile = %s\n", inFile);
    (void )fprintf(stderr, "inExt = %s\n", (inExt)? inExt: "(null)");
    (void )fprintf(stderr, "inFmt = %s\n",
    		   WlzEffStringFromFormat(inFmt, NULL));
  }
  /* Read image. */
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if(inExt)
    {
      (void )sprintf(pathBuf, "%s/%s.%s", inDir, inFile, inExt);
    }
    else
    {
      (void )sprintf(pathBuf, "%s/%s", inDir, inFile);
    }
    if(((inObj = WlzAssignObject(WlzEffReadObj(NULL, pathBuf, inFmt,
    					       0, 0, 0,
					       &errNum), NULL)) == NULL) ||
       (inObj->type != WLZ_2D_DOMAINOBJ))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: Failed to read 2D image object from file %s (%s)\n",
		     *argv, pathBuf, errMsg);
    }
  }
  if(ok && verbose)
  {
    (void )fprintf(stderr, "read input image ok.\n");
  }
  /* Convert to grey if needed, normalise 0 - 255 if needed and compute
   * threshold value unless already known. */
  if(ok)
  {
    if(WlzGreyTypeFromObj(inObj, NULL) == WLZ_GREY_RGBA)
    {
      WlzObject *ppObj;

      ppObj = WlzAssignObject(
	      WlzRGBAToModulus(inObj, &errNum), NULL);
      if(errNum == WLZ_ERR_NONE)
      {
	(void )WlzFreeObj(inObj);
	inObj = ppObj;
      }
    }
    if(threshSet == 0)
    {
      WlzObject *hObj = NULL;

      errNum = WlzGreyNormalise(inObj, 1);
      if(errNum == WLZ_ERR_NONE)
      {
        hObj = WlzHistogramObj(inObj, 256, 0.0, 1.0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	threshSet = 1;
        errNum = WlzCompThreshold(&thrVal.v.dbv, hObj, thrMtd, 0);
      }
      (void )WlzFreeObj(hObj);
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr, "%s: failed to normalise object (%s)\n",
		     *argv, errMsg);
    }
  }
  /* Segment the object. */
  if(ok)
  {
    if(inObj->values.core == NULL)
    {
      segObj = WlzAssignObject(inObj, NULL);
    }
    else
    {
      segObj = WlzAssignObject(
               WlzThreshold(inObj, thrVal, thrMod, &errNum), NULL);
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr, "%s: failed to segment image (%s)\n",
		       *argv, errMsg);
      }
    }
  }
  /* Compute object with the same domain as the input object but in which
   * the values are the minimum distance from an edge. */
  if(ok)
  {
    WlzObject	*bObj = NULL;

    bObj = WlzBoundaryDomain(inObj, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      disObj = WlzAssignObject(       
               WlzDistanceTransform(inObj, bObj, WLZ_OCTAGONAL_DISTANCE,
	       			    0.0, 0.0, &errNum), NULL);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      disGVWSp = WlzGreyValueMakeWSp(disObj, &errNum);
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr, "%s: failed to compute distance object (%s)\n",
		     *argv, errMsg);
    }
    (void )WlzFreeObj(bObj);
  }
  /* Output the debug image if required. */
  if(ok && dbgPath)
  {
    WlzObject	*dbgObj;

    dbgObj = WlzAssignObject(WlzCopyObject(inObj, &errNum), NULL);
    if(errNum == WLZ_ERR_NONE)
    {
      WlzPixelV	iMin,
		iMax,
		oMin,
		oMax;

      if(dbgObj->values.core == NULL)
      {
        WlzValues tmpVal;

	oMax.type = WLZ_GREY_UBYTE;
	oMax.v.ubv = 255;
	tmpVal.v = WlzNewValueTb(dbgObj,
				 WlzGreyTableType(WLZ_GREY_TAB_RAGR,
				                  WLZ_GREY_UBYTE, NULL),
	                         oMax, &errNum);
        if(errNum == WLZ_ERR_NONE)
	{
	  dbgObj->values = WlzAssignValues(tmpVal, NULL);
	}
      }
      else
      {
        WlzObject *tmpObj = NULL;

	oMin.type = WLZ_GREY_UBYTE;
	oMin.v.ubv = 0;
	oMax.type = WLZ_GREY_UBYTE;
	oMax.v.ubv = 200;
	errNum = WlzGreyRange(dbgObj, &iMin, &iMax);
	if(errNum == WLZ_ERR_NONE)
	{
	  errNum = WlzGreySetRange(dbgObj, iMin, iMax, oMin, oMax, 0);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  tmpObj = WlzMakeMain(inObj->type, segObj->domain, dbgObj->values,
	                       NULL, NULL, &errNum);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  oMax.v.ubv = 255;
	  errNum = WlzGreySetValue(tmpObj, oMax);
	}
	(void )WlzFreeObj(tmpObj);
	if(errNum == WLZ_ERR_NONE)
	{
	  tmpObj = WlzConvertPix(dbgObj, WLZ_GREY_UBYTE, &errNum);
	  (void )WlzFreeObj(dbgObj);
	  dbgObj = WlzAssignObject(tmpObj, NULL);
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      (void )WlzRadDistParsePath(dbgPath, &dbgDir, &dbgFile, &dbgExt,
      			         &dbgFmt);
      if(dbgExt)
      {
	(void )sprintf(pathBuf, "%s/%s.%s", dbgDir, dbgFile, dbgExt);
      }
      else
      {
	(void )sprintf(pathBuf, "%s/%s", dbgDir, dbgFile);
      }
      errNum = WlzEffWriteObj(NULL, pathBuf, dbgObj, dbgFmt);
    }
    (void )WlzFreeObj(dbgObj);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr, "%s: failed to output the debug image (%s)\n",
		     *argv, errMsg);
    }
  }
  /* Label the segmented object. */
  if(ok)
  {
    errNum = WlzLabel(segObj, &nReg, &regObjs, maxObj, 0, WLZ_8_CONNECTED);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      errNum = WLZ_ERR_MEM_ALLOC;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr, "%s: failed to split into components (%s)\n",
		     *argv, errMsg);
    }
    if(ok && verbose)
    {
      (void )fprintf(stderr, "nReg = %d\n", nReg);
    }
  }
  /* Compute centre of mass if not known. */
  if(ok)
  {
    if(centreSet == 0)                          
    {
      centre = WlzCentreOfMass2D(inObj, 1, NULL, &errNum);
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr, "%s: failed to compute centre of mass (%s)\n",
		       *argv, errMsg);
      }
    }
    if(ok && verbose)
    {
      (void )fprintf(stderr, "centre = %lg,%lg\n", centre.vtX, centre.vtY);
    }
  }
  /* Allocate a radial distribution table. */
  if(ok)
  {
    if((distData = (WlzRadDistRec *)
                   AlcCalloc(nReg, sizeof(WlzRadDistRec))) == NULL)
    {
      ok = 0;
      errNum = WLZ_ERR_MEM_ALLOC;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr, "%s: failed to allocate result lable (%s)\n",
		     *argv, errMsg);
    }
    
  }
  /* Compute the redial distribution data. */
  if(ok)
  {
    int		idR = 0,
    		idS = 0;

    while((errNum == WLZ_ERR_NONE) && (idR < nReg))
    {
      double	mass;
      WlzDVertex2 com;

      com = WlzCentreOfMass2D(regObjs[idR], 1, &mass, NULL);
      if(mass > minArea - eps)
      {
	WlzGreyValueGet(disGVWSp, 0.0, com.vtY, com.vtX);
	distData[idS].pos = com;
	distData[idS].area = mass;
	WLZ_VTX_2_SUB(com, centre, com);
	distData[idS].radius = WLZ_VTX_2_LENGTH(com);
	distData[idS].angle = ALG_M_PI + atan2(com.vtY, com.vtX);
	switch(disGVWSp->gType)
	{
	  case WLZ_GREY_LONG:
	    distData[idS].dist = *(disGVWSp->gPtr[0].lnp);
	    break;
	  case WLZ_GREY_INT:
	    distData[idS].dist = *(disGVWSp->gPtr[0].inp);
	    break;
	  case WLZ_GREY_SHORT:
	    distData[idS].dist = *(disGVWSp->gPtr[0].shp);
	    break;
	  case WLZ_GREY_UBYTE:
	    distData[idS].dist = *(disGVWSp->gPtr[0].ubp);
	    break;
	  case WLZ_GREY_FLOAT:
	    distData[idS].dist = *(disGVWSp->gPtr[0].flp);
	    break;
	  case WLZ_GREY_DOUBLE:
	    distData[idS].dist = *(disGVWSp->gPtr[0].dbp);
	    break;
	  default:
	    distData[idS].dist = 0.0;
	    break;
	}
	++idS;
      }
      ++idR;
    }
    tNReg = idS;
    switch(distSort)
    {
      case WLZ_RADDISTVAL_AREA:
        (void )qsort(distData, tNReg, sizeof(WlzRadDistRec),
		     WlzRadDistRecSortArea);
	break;
      case WLZ_RADDISTVAL_ANGLE:
        (void )qsort(distData, tNReg, sizeof(WlzRadDistRec), 
		     WlzRadDistRecSortAngle);
	break;
      case WLZ_RADDISTVAL_RADIUS:
        (void )qsort(distData, tNReg, sizeof(WlzRadDistRec),
		     WlzRadDistRecSortRadius);
	break;
      case WLZ_RADDISTVAL_DIST:
        (void )qsort(distData, tNReg, sizeof(WlzRadDistRec),
		     WlzRadDistRecSortDist);
	break;
    }
  }
  /* Output the sorted radial distribution table. */
  if(ok)
  {
    if(((fP = strcmp(outFile, "-")?
              fopen(outFile, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr, "%s: failed to open output file %s\n",
                     *argv, outFile);
    }
  }
  if(ok)
  {
    int		idR;

    for(idR = 0; idR < tNReg; ++idR)
    {
      double a;

      a = (distData[idR].angle > 0.0)?
	  0   + (180 * distData[idR].angle / ALG_M_PI):
          360 + (180 * distData[idR].angle / ALG_M_PI);
      (void )fprintf(fP, "%g %g %g %g,%g %g\n",
		     a,
                     distData[idR].radius,
		     distData[idR].area,
		     distData[idR].pos.vtX,
		     distData[idR].pos.vtY,
		     distData[idR].dist);
    }
  }
  if(strcmp(outFile, "-"))
  {
    (void )fclose(fP);
  }
  /* Tidy up. */
  AlcFree(distData);
  WlzGreyValueFreeWSp(disGVWSp);
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(disObj);
  (void )WlzFreeObj(segObj);
  if(regObjs)
  {
    int		idR;

    for(idR = 0; idR < nReg; ++idR)
    {
      (void )WlzFreeObj(regObjs[idR]);
    }
    AlcFree(regObjs);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-h] [-v] [-A] [-D] [-G] [-H] [-E] [-L] [-R]\n"
    "\t\t[-c #,#] [-d <debug image>] [-n #]  [-o <out file>]\n"
    "\t\t[-t #] [<input image>]\n"
    "Segments the given object using a threshold value and outputs the \n"
    "radial distribution of the thresholded components.\n"
    "Version: %s\n"
    "Options:\n"
    "  -h  Help - prints this usage masseage.\n"
    "  -v  Verbose output.\n"
    "  -A  Sort output by area (default).\n"
    "  -D  Sort output by distance from boundary.\n"
    "  -G  Sort output by angle.\n"
    "  -H  Threshold high, use pixels at or above threshold (default).\n"
    "  -E  Threshold equal, use pixels at threshold.\n"
    "  -L  Threshold low, use pixels below threshold.\n"
    "  -R  Sort output by radial distance from centre.\n"
    "  -c  Centre (default is image centre).\n"
    "  -d  Debug image.\n"
    "  -n  Minimum area (default %g).\n"
    "  -t  Threshold value (default is to compute using Otsu's method).\n"
    "By default the input image object is read from the standard input and\n"
    "the radial distribution is written to the standard output.\n"
    "The image formats understood include wlz, jpg and tif.\n"
    "The output format is:\n"
    "  <angle> <dist from centre> <area> <x pos>,<y pos> <dist form boundary>\n"
    "Example:\n"
    "  %s -o out.txt -d debug.jpg in.tif\n"
    "The input image is read from in.tif, a debug image showing the\n"
    "segmented regions is written to debug.jpg and the radial distribution\n"
    "statistics are written to the file out.txt. With the output in\n"
    "out.txt, the following R code would plot the data as a set of circles\n"
    "with radius proportional to the square root of the component area:\n"
    "  data <- read.table(\"out.txt\")\n"
    "  attach(data)\n"
    "  symbols(x=data$V1, y=data$V2, circles=sqrt(data$V3))\n",
    argv[0],
    WlzVersion(),
    minArea,
    argv[0]);
  }
  return(!ok);
}
예제 #12
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;
}
예제 #13
0
WlzObject *WlzRGBAToChannel(
  WlzObject	*obj,
  WlzRGBAColorChannel	chan,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzValues		values;
  WlzObjectType	type;
  WlzPixelV		pixVal, oldBck, newBck;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check object and channel */
  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 WlzRGBAToChannel3D(obj, chan, 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;
  }

  if( errNum == WLZ_ERR_NONE ){
    switch( chan ){
    case WLZ_RGBA_CHANNEL_RED:
    case WLZ_RGBA_CHANNEL_GREEN:
    case WLZ_RGBA_CHANNEL_BLUE:
    case WLZ_RGBA_CHANNEL_HUE:
    case WLZ_RGBA_CHANNEL_SATURATION:
    case WLZ_RGBA_CHANNEL_BRIGHTNESS:
    case WLZ_RGBA_CHANNEL_CYAN:
    case WLZ_RGBA_CHANNEL_MAGENTA:
    case WLZ_RGBA_CHANNEL_YELLOW:
      break;

    default:
      errNum = WLZ_ERR_PARAM_DATA;
      break;
    }
  }

  /* now extract data */
  if( errNum == WLZ_ERR_NONE ){

    type = WlzGreyTableType(
      WlzGreyTableTypeToTableType(obj->values.core->type, &errNum),
      WLZ_GREY_UBYTE, &errNum);
    oldBck = WlzGetBackground(obj, &errNum);
    newBck.type = WLZ_GREY_UBYTE;
    newBck.v.ubv = (WlzUByte )WlzRGBAPixelValue(oldBck, chan, &errNum);
  }

  /* make values table and return object */
  if( errNum == WLZ_ERR_NONE ){
    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);
    pixVal.type = WLZ_GREY_RGBA;
    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++){
	pixVal.v.rgbv = (*(gwsp0.u_grintptr.rgbp));
	*(gwsp1.u_grintptr.ubp++) = (WlzUByte )
	  WlzRGBAPixelValue(pixVal, chan, &errNum);
      }
    }
    if( errNum == WLZ_ERR_EOO ){
      errNum = WLZ_ERR_NONE;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
예제 #14
0
int             main(int argc, char **argv)
{
  int		idx,
  		option,
		noiseFlg = 0,
		ok = 1,
		usage = 0;
  double	noiseMu = 0.0,
  		noiseSigma = 0.0;
  WlzIBox3	cutBox,
		cutSet;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzGreyType	dstGreyType = WLZ_GREY_ERROR;
  FILE		*fP = NULL;
  WlzObject	*inObj = NULL,
		*outObj = NULL;
  char 		*outObjFileStr,
  		*inObjFileStr;
  int		cutVal[2];
  char		*cutStr[2];
  const char	*errMsg;
  static char	optList[] = "iNsufdM:S:o:x:y:z:h",
		outObjFileStrDef[] = "-",
  		inObjFileStrDef[] = "-";

  opterr = 0;
  cutSet.xMin = 0;
  cutSet.xMax = 0;
  cutSet.yMin = 0;
  cutSet.yMax = 0;
  cutSet.zMin = 0;
  cutSet.zMax = 0;
  outObjFileStr = outObjFileStrDef;
  inObjFileStr = inObjFileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'i':
        dstGreyType = WLZ_GREY_INT;
	break;
      case 's':
        dstGreyType = WLZ_GREY_SHORT;
	break;
      case 'u':
        dstGreyType = WLZ_GREY_UBYTE;
	break;
      case 'f':
        dstGreyType = WLZ_GREY_FLOAT;
	break;
      case 'd':
        dstGreyType = WLZ_GREY_DOUBLE;
	break;
      case 'N':
        noiseFlg = 1;
        break;
      case 'M':
        if(sscanf(optarg, "%lg", &noiseMu) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'S':
        if(sscanf(optarg, "%lg", &noiseSigma) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'o':
        outObjFileStr = optarg;
	break;
      case 'x':
      case 'y':
      case 'z':
	if(optarg)
	{
	  while(*optarg && isspace(*optarg))
	  {
	    ++optarg;
	  }
	  if(*optarg == ',')
	  {
	    cutStr[0] = NULL;
	    cutStr[1] = strtok(optarg, ",");
	  }
	  else
	  {
	    cutStr[0] = strtok(optarg, ",");
	    cutStr[1] = strtok(NULL, ",");
	  }
	  if((cutStr[0] == NULL) && (cutStr[1] == NULL))
	  {
	    usage = 1;
	    ok = 0;
	  }
	  else
	  {
	    idx = 0;
	    while(ok && (idx < 2))
	    {
	      if(cutStr[idx] && (sscanf(cutStr[idx], "%d",
					 cutVal + idx) != 1))
	      {
		usage = 1;
		ok = 0;
	      }
	      ++idx;
	    }
	  }
	}
	if(ok)
	{
	  switch(option)
	  {
	    case 'x':
	      if(cutStr[0])
	      {
		cutSet.xMin = 1;
		cutBox.xMin = cutVal[0];
	      }
	      if(cutStr[1])
	      {
		cutSet.xMax = 1;
		cutBox.xMax = cutVal[1];
	      }
	      break;
	    case 'y':
	      if(cutStr[0])
	      {
		cutSet.yMin = 1;
		cutBox.yMin = cutVal[0];
	      }
	      if(cutStr[1])
	      {
		cutSet.yMax = 1;
		cutBox.yMax = cutVal[1];
	      }
	      break;
	    case 'z':
	      if(cutStr[0])
	      {
		cutSet.zMin = 1;
		cutBox.zMin = cutVal[0];
	      }
	      if(cutStr[1])
	      {
		cutSet.zMax = 1;
		cutBox.zMax = cutVal[1];
	      }
	      break;
	  }
	}
	break;
      case 'h':
      default:
        usage = 1;
	ok = 0;
	break;
    }
  }
  if((inObjFileStr == NULL) || (*inObjFileStr == '\0') ||
     (outObjFileStr == NULL) || (*outObjFileStr == '\0'))
  {
    ok = 0;
    usage = 1;
  }
  if(ok && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
      ok = 0;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if((inObjFileStr == NULL) ||
       (*inObjFileStr == '\0') ||
       ((fP = (strcmp(inObjFileStr, "-")?
	      fopen(inObjFileStr, "r"): stdin)) == NULL) ||
       ((inObj = WlzReadObj(fP, &errNum)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to read object from file %s (%s).\n",
		     *argv, inObjFileStr, errMsg);
    }
    if(fP && strcmp(inObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  if(ok)
  {
    switch(inObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	if(cutSet.xMin == 0)
	{
          cutBox.xMin = inObj->domain.i->kol1;
	}
	if(cutSet.xMax == 0)
	{
          cutBox.xMax = inObj->domain.i->lastkl;
	}
	if(cutSet.yMin == 0)
	{
          cutBox.yMin = inObj->domain.i->line1;
	}
	if(cutSet.yMax == 0)
	{
          cutBox.yMax = inObj->domain.i->lastln;
	}
	cutBox.zMin = 0;
	cutBox.zMax = 0;
        break;
      case WLZ_3D_DOMAINOBJ:
	if(cutSet.xMin == 0)
	{
          cutBox.xMin = inObj->domain.p->kol1;
	}
	if(cutSet.xMax == 0)
	{
          cutBox.xMax = inObj->domain.p->lastkl;
	}
	if(cutSet.yMin == 0)
	{
          cutBox.yMin = inObj->domain.p->line1;
	}
	if(cutSet.yMax == 0)
	{
          cutBox.yMax = inObj->domain.p->lastln;
	}
	if(cutSet.zMin == 0)
	{
          cutBox.zMin = inObj->domain.p->plane1;
	}
	if(cutSet.zMax == 0)
	{
          cutBox.zMax = inObj->domain.p->lastpl;
	}
        break;
      default:
        ok = 0;
	errMsg = WlzStringFromObjType(inObj, NULL);
	(void )fprintf(stderr,
		       "%s: invalid object type %s.\n", 
		       *argv,
		       errMsg? errMsg: "unknown");
    }
  }
  if(ok)
  {
    if(inObj->domain.core == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
      		     "%s: invalid object, null domain\n",
		     *argv);
    }
  }
  if(ok)
  {
    if(dstGreyType == WLZ_GREY_ERROR)
    {
      if(inObj->values.core == NULL)
      {
        dstGreyType = WLZ_GREY_UBYTE;
      }
      else
      {
	dstGreyType = WlzGreyTypeFromObj(inObj, NULL);
      }
    }
    if(((outObj = WlzCutObjToBox3D(inObj, cutBox, dstGreyType,
    			           noiseFlg, noiseMu, noiseSigma,
				   &errNum)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to cut object (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if(((fP = (strcmp(outObjFileStr, "-")?
              fopen(outObjFileStr, "w"):
	      stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to write cut object (%s).\n",
		     *argv, errMsg);
    }
    if(fP && strcmp(outObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-dfhiNsu] [-o<out object>]\n"
    "       [-M <mean>] [-S <std dev>]\n"
    "       [-x<x min>,<x max>] [-y<y min>,<y max>] [-z<z min>,<z max>]\n"
    "       [<in object>]\n"
    "Cuts a  Woolz object using specified cut box.\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -d  Double output values.\n"
    "  -f  Float output values.\n"
    "  -h  Help, prints this usage message.\n"
    "  -i  Int output values.\n"
    "  -N  Use gausian noise for background.\n"
    "  -s  Short output values.\n"
    "  -u  Unsigned byte output values.\n"
    "  -M  Mean of gaussian noise.\n"
    "  -o  Output object file name.\n"
    "  -S  Standard deviation of gaussian noise.\n"
    "  -x  Column cut box limits.\n"
    "  -y  Line cut box limits.\n"
    "  -z  Plane cut box limits.\n"
    "All cut limits default to the input objects domain limits.\n"
    "Objects are read from stdin and written to stdout unless the filenames\n"
    "are given.\n",
    *argv,
    " -i -o cut.wlz -x 100,800 -y ,800 myobj.wlz\n"
    "The input Woolz object is read from myobj.wlz, cut and written\n"
    "to cut.wlz, with int values.\n");
  }
  return(!ok);
}
예제 #15
0
int             main(int argc, char **argv)
{
  int		idx,
		option,
		dither = 0,
		overwrite = 1,
		ok = 1,
		usage = 0;
  WlzImArNorm	norm = WLZ_IMARNORM_NONE;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  FILE		*fP = NULL;
  WlzObject	*outObj = NULL;
  WlzObject	*inObj[2];
  WlzBinaryOperatorType operator = WLZ_BO_ADD;
  char 		*outObjFileStr;
  char  	*inObjFileStr[2];
  WlzPixelV	gMin[3],
  		gMax[3];
  const char	*errMsg;
  static char	optList[] = "O:o:ab:dgilmsnNh",
		outObjFileStrDef[] = "-",
  		inObjFileStrDef[] = "-";

  opterr = 0;
  inObj[0] = NULL;
  inObj[1] = NULL;
  outObjFileStr = outObjFileStrDef;
  inObjFileStr[0] = inObjFileStrDef;
  inObjFileStr[1] = inObjFileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'O':
	if((sscanf(optarg, "%d", &overwrite) != 1) ||
	   (overwrite < 0) || (overwrite > 2))
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'o':
	outObjFileStr = optarg;
	break;
      case 'a':
	operator = WLZ_BO_ADD;
	break;
      case 'b':
	operator = atoi(optarg);
	switch( operator ){
	  case WLZ_BO_ADD:
	  case WLZ_BO_SUBTRACT:
	  case WLZ_BO_MULTIPLY:
	  case WLZ_BO_DIVIDE:
	  case WLZ_BO_MODULUS:
	  case WLZ_BO_EQ:
	  case WLZ_BO_NE:
	  case WLZ_BO_GT:
	  case WLZ_BO_GE:
	  case WLZ_BO_LT:
	  case WLZ_BO_LE:
	  case WLZ_BO_AND:
	  case WLZ_BO_OR:
	  case WLZ_BO_XOR:
	  case WLZ_BO_MAX:
	  case WLZ_BO_MIN:
	  case WLZ_BO_MAGNITUDE:
	    break;
	  default:
	    usage = 1;
	    ok = 0;
	    break;
	}
	break;
      case 'd':
	operator = WLZ_BO_DIVIDE;
	break;
      case 'g':
	operator = WLZ_BO_MAGNITUDE;
	break;
      case 'l':
	operator = WLZ_BO_MODULUS;
	break;
      case 'm':
	operator = WLZ_BO_MULTIPLY;
	break;
      case 's':
	operator = WLZ_BO_SUBTRACT;
	break;
      case 'n':
	norm = WLZ_IMARNORM_INPUT;
	break;
      case 'N':
	norm = WLZ_IMARNORM_256;
	break;
      case 'i':
	dither = 1;
	break;
      case 'h':
      default:
	usage = 1;
	ok = 0;
	break;
    }
  }
  if((inObjFileStr[0] == NULL) || (*inObjFileStr[0] == '\0') ||
     (inObjFileStr[1] == NULL) || (*inObjFileStr[1] == '\0') ||
     (outObjFileStr == NULL) || (*outObjFileStr == '\0'))
  {
    ok = 0;
    usage = 1;
  }
  if(ok && (optind < argc))
  {
    idx = 0;
    while((idx < 2) && (optind < argc))
    {
      inObjFileStr[idx] = *(argv + optind);
      ++optind;
      ++idx;
    }
  }
  if(ok && (optind != argc))
  {
    usage = 1;
    ok = 0;
  }
  if(ok)
  {
    idx = 0;
    while((errNum == WLZ_ERR_NONE) && (idx < 2))
    {
      errNum = WLZ_ERR_READ_EOF;
      if((inObjFileStr[idx] == NULL) ||
	  (*inObjFileStr[idx] == '\0') ||
	  ((fP = (strcmp(inObjFileStr[idx], "-")?
		  fopen(inObjFileStr[idx], "r"): stdin)) == NULL) ||
	  ((inObj[idx]= WlzAssignObject(WlzReadObj(fP,
	  					   &errNum), NULL)) == NULL))
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: failed to read object %d from file %s (%s)\n",
		       *argv, idx, inObjFileStr[idx], errMsg);
      }
      if(fP && strcmp(inObjFileStr[idx], "-"))
      {
	fclose(fP);
      }
      ++idx;
    }
  }
  if(ok)
  {
    idx = 0;
    while((errNum == WLZ_ERR_NONE) && (idx < 2))
    {
      if((inObj[idx]->type != WLZ_2D_DOMAINOBJ) &&
         (inObj[idx]->type != WLZ_3D_DOMAINOBJ))
      {
        ok = 0;
	(void )fprintf(stderr, "%s: input object %d is not a domain object\n",
		       *argv, idx);
      }
      ++idx;
    }
  }
  if(ok && (norm == WLZ_IMARNORM_INPUT))
  {
    if(((errNum = WlzGreyRange(inObj[0], gMin, gMax)) != WLZ_ERR_NONE) ||
       ((errNum = WlzGreyRange(inObj[1], gMin + 1, gMax + 1)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to find input objects grey range (%s)\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    if( WlzGreyTypeFromObj(inObj[0], &errNum) == WLZ_GREY_RGBA ){
      if((outObj = WlzRGBAImageArithmetic(inObj[0], inObj[1], operator, 1,
				      &errNum)) == NULL)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: failed to compute new object (%s).\n",
		       *argv, errMsg);
      }
    }
    else if((outObj = WlzImageArithmetic(inObj[0], inObj[1], operator, 0,
				    &errNum)) == NULL)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to compute new object (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok &&
     (norm != WLZ_IMARNORM_NONE) &&
     (WlzGreyTypeFromObj(inObj[0], &errNum) != WLZ_GREY_RGBA) )
  {
    if((errNum = WlzGreyRange(outObj, gMin+ 2, gMax + 2)) != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to find output object's grey range (%s)\n",
		     *argv, errMsg);
    }
    if(ok)
    {
      if(norm == WLZ_IMARNORM_256)
      {
        gMin[0].type = WLZ_GREY_UBYTE;
	gMin[0].v.ubv = 0;
        gMax[0].type = WLZ_GREY_UBYTE;
	gMax[0].v.ubv = 255;
	(void )WlzValueConvertPixel(gMin, gMin[0], gMin[2].type);
	(void )WlzValueConvertPixel(gMax, gMax[0], gMax[2].type);
      }
      else
      {
	(void )WlzValueConvertPixel(gMin, gMin[0], gMin[2].type);
	(void )WlzValueConvertPixel(gMax, gMax[0], gMax[2].type);
	(void )WlzValueConvertPixel(gMin + 1, gMin[1], gMin[2].type);
	(void )WlzValueConvertPixel(gMax + 1, gMax[1], gMax[2].type);
	switch(gMin[2].type)
	{
	  case WLZ_GREY_INT:
	    if(gMin[1].v.inv < gMin[0].v.inv)
	    {
	      gMin[0].v.inv = gMin[1].v.inv;
	    }
	    if(gMax[1].v.inv > gMax[0].v.inv)
	    {
	      gMax[0].v.inv = gMax[1].v.inv;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    if(gMin[1].v.shv < gMin[0].v.shv)
	    {
	      gMin[0].v.shv = gMin[1].v.shv;
	    }
	    if(gMax[1].v.shv > gMax[0].v.shv)
	    {
	      gMax[0].v.shv = gMax[1].v.shv;
	    }
	    break;
	  case WLZ_GREY_UBYTE:
	    if(gMin[1].v.ubv < gMin[0].v.ubv)
	    {
	      gMin[0].v.ubv = gMin[1].v.ubv;
	    }
	    if(gMax[1].v.ubv > gMax[0].v.ubv)
	    {
	      gMax[0].v.ubv = gMax[1].v.ubv;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    if(gMin[1].v.flv < gMin[0].v.flv)
	    {
	      gMin[0].v.flv = gMin[1].v.flv;
	    }
	    if(gMax[1].v.flv > gMax[0].v.flv)
	    {
	      gMax[0].v.flv = gMax[1].v.flv;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    if(gMin[1].v.dbv < gMin[0].v.dbv)
	    {
	      gMin[0].v.dbv = gMin[1].v.dbv;
	    }
	    if(gMax[1].v.dbv > gMax[0].v.dbv)
	    {
	      gMax[0].v.dbv = gMax[1].v.dbv;
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_GREY_TYPE;
	    break;
	}
      }
    }
    if((errNum = WlzGreySetRange(outObj, gMin[2], gMax[2],
    				 gMin[0], gMax[0], dither)) != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to set output object's grey range (%s)\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if(((fP = (strcmp(outObjFileStr, "-")?  fopen(outObjFileStr, "w"):
	      				    stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to write output object (%s).\n",
		     *argv, errMsg);
    }
    if(fP && strcmp(outObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  WlzFreeObj(inObj[0]);
  WlzFreeObj(inObj[1]);
  WlzFreeObj(outObj);
  if(usage)
  {

    fprintf(stderr,
	    "Usage: %s"
	    " [-O#] [-o<out file>] [-a] [-b <op>] [-d] [-g] [-i] [-l] [-m] [-s] [-h] "
	    "[<in object 0>] [<in object 1>]\n"
	    "Options:\n"
	    "  -O        Overwrite option (only useful for debugging)\n"
	    "  -o        Output file name.\n"
	    "  -a        Add the object's grey values.\n"
	    "  -b <op>   Apply binary operation to the grey-values.\n"
	    "            op =  %d - Add\n"   
	    "               =  %d - SUBTRACT\n"
	    "               =  %d - MULTIPLY\n"
	    "               =  %d - DIVIDE\n"
	    "               =  %d - MODULUS\n"
	    "               =  %d - EQ\n"
	    "               =  %d - NE\n"
	    "               =  %d - GT\n"
	    "               =  %d - GE\n"
	    "               =  %d - LT\n"
	    "               =  %d - LE\n"
	    "               =  %d - AND\n"
	    "               =  %d - OR\n"
	    "               =  %d - XOR\n"
	    "               =  %d - MAX\n"
	    "               =  %d - MIN\n"
	    "               =  %d - MAGNITUDE\n"
	    "  -d        Divide the grey values of the 1st object by those of the 2nd.\n"
	    "  -g        Vector magnitude of horizontal and vertical component objects\n"
	    "  -i        Dither values if setting range\n"
	    "  -l        Compute the modulus of the grey values of the 1st object wrt\n"
	    "            those of the 2nd.\n"
	    "  -m        Multiply the object's grey values.\n"
	    "  -s        Subtract the grey values of the 2nd object from those of the 1st.\n"
	    "  -n        Normalises the output object to the range of the input objects.\n"
	    "  -N        Normalises the output objects to the range [0-255].\n"
	    "  -h        Help, prints this usage message.\n"
	    "Computes an arithmetic binary (two objects) operation on two domain\n"
	    "objects. The default operator is add.\n"
	    "The input objects are read from stdin and values are written to stdout\n"
	    "unless the filenames are given.\n"
	    "Example:\n%s%s%s",
	    *argv,
	    WLZ_BO_ADD,
	    WLZ_BO_SUBTRACT,
	    WLZ_BO_MULTIPLY,
	    WLZ_BO_DIVIDE,
	    WLZ_BO_MODULUS,
	    WLZ_BO_EQ,
	    WLZ_BO_NE,
	    WLZ_BO_GT,
	    WLZ_BO_GE,
	    WLZ_BO_LT,
	    WLZ_BO_LE,
	    WLZ_BO_AND,
	    WLZ_BO_OR,
	    WLZ_BO_XOR,
	    WLZ_BO_MAX,
	    WLZ_BO_MIN,
	    WLZ_BO_MAGNITUDE,
	    "cat obj1.wlz | ",
	    *argv,
	    " -o obj3.wlz -a obj2.wlz\n"
	    "A new object 'obj3.wlz is formed by adding the grey values of obj1 and\n"
	    "obj2.wlz.\n");
  }
  return(!ok);
}
예제 #16
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);
}
예제 #17
0
int main(int	argc,
	 char	**argv)
{
  char 		optList[] = "hv";
  int		option;
  /* int		verboseFlg=0; */
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  char		*tiffFile=NULL;
  WlzObject	*inObj, *outObj, *obj, **objVec;
  int		i, objVecCount;
  WlzGreyType	gType;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'v':
      /* verboseFlg = 1; */
      break;

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

  if( optind < argc ){
    tiffFile = *(argv+optind);
  }
  else {
    usage(argv[0]);
    return WLZ_ERR_UNSPECIFIED;
  }

  /* read the TIFF file */
  if( (inObj = WlzAssignObject(WlzEffReadObj(NULL, tiffFile,
  			                     WLZEFF_FORMAT_TIFF, 0, 0, 0,
					     &errNum), NULL)) == NULL ){
    usage(argv[0]);
    return errNum;
  }

  /* if 2D then that is the shade file, else take max of 3D stack */
  switch( inObj->type ){
  case WLZ_2D_DOMAINOBJ:
    outObj = inObj;
    break;

  case WLZ_3D_DOMAINOBJ:
    if( (errNum = WlzExplode3D(&objVecCount, &objVec, inObj)) != WLZ_ERR_NONE ){
      usage(argv[0]);
      return errNum;
    }
    gType = WlzGreyTypeFromObj(objVec[0], &errNum);
    outObj = WlzAssignObject(objVec[0], NULL);
    for(i=1; i < objVecCount; i++){
      if( gType == WLZ_GREY_RGBA ){
	obj = WlzRGBAImageArithmetic(outObj, objVec[i], WLZ_BO_MAX, 0, &errNum);
      }
      else {
	obj = WlzImageArithmetic(outObj, objVec[i], WLZ_BO_MAX, 0, &errNum);
      }
      if( obj ){
	WlzFreeObj(outObj);
	outObj = WlzAssignObject(obj, &errNum);
      }
      else {
	break;
      }
    }
    
    WlzFreeObj(inObj);
    break;

  default:
    WlzFreeObj(inObj);
    errNum = WLZ_ERR_OBJECT_TYPE;
  }

  /* write shade object */
  if( errNum == WLZ_ERR_NONE ){
    WlzWriteObj(stdout, outObj);
    WlzFreeObj(outObj);
  }
  else {
    usage(argv[0]);
  }
  return errNum;
}
예제 #18
0
파일: WlzBuildObj.c 프로젝트: omsai/Woolz
/*!
* \return	New Woolz object.
* \ingroup	WlzAllocation
* \brief	Creates a new or adds to an existing 3D spatial domain
*  		object using a rectangular buffer of values to a single
*  		plane of the given current object (which may be NULL or
*  		empty if the object is to be created).
* 		The returned object will share domains and values of
* 		planes other than the given plane with the current object.
* \param	cObj			Given current object.
* \param	og			Origin of rectangular buffer.
* \param	sz			Buffer size (note 2D).
* \param	gType			Grey type which must be consistent
* 					with the current object (if it is
* 					valid) and the buffer of values.
* \param	bufSz			Number of values in the buffer
* 					(ie sz.vtX * sz.vtY).
* \param	bufP			Given buffer of values.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzBuildObj3(WlzObject *cObj,
                          WlzIVertex3 og, WlzIVertex2 sz,
                          WlzGreyType gType,
                          int bufSz, WlzGreyP bufP,
                          WlzErrorNum *dstErr)
{
    int		nPlnReq = 1;
    WlzDomain	cDom,
                nDom;
    WlzValues	cVal,
                nVal;
    WlzObject	*nObj = NULL;
    WlzErrorNum	errNum = WLZ_ERR_NONE;

    cDom.core = NULL;
    nDom.core = NULL;
    cVal.core = NULL;
    nVal.core = NULL;
    if(cObj)
    {
        WlzGreyType cGType = WLZ_GREY_ERROR;;

        switch(cObj->type)
        {
        case WLZ_EMPTY_OBJ:
            cObj = NULL;
            break;
        case WLZ_3D_DOMAINOBJ:
            if(cObj->domain.core == NULL)
            {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            else if(cObj->values.core == NULL)
            {
                errNum = WLZ_ERR_VALUES_NULL;
            }
            else
            {
                cDom = cObj->domain;
                cVal = cObj->values;
                cGType = WlzGreyTypeFromObj(cObj, &errNum);
            }
            if((errNum == WLZ_ERR_NONE) && (cGType != gType))
            {
                errNum = WLZ_ERR_GREY_TYPE;
            }
            break;
        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }
    /* Create a new object with new plane domain and voxel values. */
    if(errNum == WLZ_ERR_NONE)
    {
        WlzIBox3	nBox;
        WlzPixelV	bgdV;
        float	vxSz[3];

        nBox.xMin = og.vtX;
        nBox.yMin = og.vtY;
        nBox.zMin = og.vtZ;
        nBox.xMax = og.vtX + sz.vtX - 1;
        nBox.yMax = og.vtY + sz.vtY - 1;
        nBox.zMax = og.vtZ;
        if(cObj)
        {
            nPlnReq = (og.vtZ < cDom.p->plane1) ||
                      (og.vtZ > cDom.p->lastpl) ||
                      ((*(cDom.p->domains + og.vtZ - cDom.p->plane1)).core == NULL);
            nBox.xMin = ALG_MIN(nBox.xMin, cDom.p->kol1);
            nBox.yMin = ALG_MIN(nBox.yMin, cDom.p->line1);
            nBox.zMin = ALG_MIN(nBox.zMin, cDom.p->plane1);
            nBox.xMax = ALG_MAX(nBox.xMax, cDom.p->lastkl);
            nBox.yMax = ALG_MAX(nBox.yMax, cDom.p->lastln);
            nBox.zMax = ALG_MAX(nBox.zMax, cDom.p->lastpl);
            vxSz[0] = cDom.p->voxel_size[0];
            vxSz[1] = cDom.p->voxel_size[1];
            vxSz[2] = cDom.p->voxel_size[2];
            bgdV = WlzGetBackground(cObj, &errNum);
        }
        else
        {
            vxSz[0] = vxSz[1] = vxSz[2] = 1.0f;
            bgdV.type = WLZ_GREY_INT;
            bgdV.v.inv = 0;
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nDom.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
                                        nBox.zMin, nBox.zMax,
                                        nBox.yMin, nBox.yMax,
                                        nBox.xMin, nBox.xMax,
                                        &errNum);
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nVal.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
                                           nBox.zMin, nBox.zMax,
                                           bgdV, NULL, &errNum);
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nDom.p->voxel_size[0] = vxSz[0];
            nDom.p->voxel_size[1] = vxSz[1];
            nDom.p->voxel_size[2] = vxSz[2];
            nObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, nDom, nVal, NULL, NULL, &errNum);
        }
    }
    /* Set the domain and values on each plane for the new object. */
    if(errNum == WLZ_ERR_NONE)
    {
        int		idZ;

        for(idZ = nDom.p->plane1; idZ <= nDom.p->lastpl; ++idZ)
        {
            int	idP;
            WlzDomain	nDom2;
            WlzValues nVal2;

            nDom2.core = NULL;
            nVal2.core = NULL;
            idP = idZ - nDom.p->plane1;
            if(idZ == og.vtZ)
            {
                /* Plane with buffer. */
                WlzIVertex2 og2,
                            sz2;
                WlzObject   *cObj2 = NULL,
                             *nObj2 = NULL;

                og2.vtX = og.vtX;
                og2.vtY = og.vtY;
                sz2.vtX = sz.vtX;
                sz2.vtY = sz.vtY;
                if(nPlnReq == 0)
                {
                    int	idP;

                    idP = idZ - cDom.p->plane1;
                    cObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                                        *(cDom.p->domains  + idP),
                                        *(cVal.vox->values + idP),
                                        NULL, NULL, &errNum);
                }
                nObj2 = WlzBuildObj2(cObj2, og2, sz2, gType, bufSz, bufP, &errNum);
                if(errNum == WLZ_ERR_NONE)
                {
                    nDom2 = WlzAssignDomain(nObj2->domain, NULL);
                    nVal2 = WlzAssignValues(nObj2->values, NULL);
                }
                (void )WlzFreeObj(cObj2);
                (void )WlzFreeObj(nObj2);
            }
            else if((idZ >= cDom.p->plane1) && (idZ <= cDom.p->lastpl))
            {
                /* Not buffer plane, but previously existing plane. */
                int	idQ;

                idQ = idZ - cDom.p->plane1;
                nDom2 = WlzAssignDomain(*(cDom.p->domains  + idQ), NULL);
                nVal2 = WlzAssignValues(*(cVal.vox->values + idQ), NULL);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                *(nDom.p->domains  + idP) = nDom2;
                *(nVal.vox->values + idP) = nVal2;
            }
            else
            {
                break;
            }
        }
    }
    if(dstErr)
    {
        *dstErr = errNum;
    }
    return(nObj);
}
예제 #19
0
int main(int	argc,
	 char	**argv)
{

  char 		optList[] = "b:hv";
  int		option;
  int		verboseFlg=0;
  WlzBinaryOperatorType operator = WLZ_BO_ADD;
  FILE		*inFile;
  double	val;
  WlzPixelV	pval;
  WlzObject	*obj, *obj1;
  WlzErrorNum	errNum;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'b':
      operator = atoi(optarg);
      switch( operator ){
      case WLZ_BO_ADD:
      case WLZ_BO_SUBTRACT:
      case WLZ_BO_MULTIPLY:
      case WLZ_BO_DIVIDE:
      case WLZ_BO_MODULUS:
      case WLZ_BO_EQ:
      case WLZ_BO_NE:
      case WLZ_BO_GT:
      case WLZ_BO_GE:
      case WLZ_BO_LT:
      case WLZ_BO_LE:
      case WLZ_BO_AND:
      case WLZ_BO_OR:
      case WLZ_BO_XOR:
      case WLZ_BO_MAX:
      case WLZ_BO_MIN:
      case WLZ_BO_MAGNITUDE:
	break;

      default:
	usage(argv[0]);
	return( 1 );
      }
      break;

    case 'v':
      verboseFlg = 1;
      break;

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

  /* get the scalar value */
  switch( operator ){
  case WLZ_BO_ADD:
  case WLZ_BO_SUBTRACT:
  case WLZ_BO_MULTIPLY:
  case WLZ_BO_DIVIDE:
  case WLZ_BO_MODULUS:
  case WLZ_BO_EQ:
  case WLZ_BO_NE:
  case WLZ_BO_GT:
  case WLZ_BO_GE:
  case WLZ_BO_LT:
  case WLZ_BO_LE:
  case WLZ_BO_AND:
  case WLZ_BO_OR:
  case WLZ_BO_XOR:
  case WLZ_BO_MAX:
  case WLZ_BO_MIN:
    if( optind < argc ){
      val = atof(*(argv+optind));
      pval.type = WLZ_GREY_DOUBLE;
      pval.v.dbv = val;
      optind++;
    }
    break;

  case WLZ_BO_MAGNITUDE:
    break;
  }

  /* get the file pointer */
  inFile = stdin;
  if( optind < argc ){
    if( (inFile = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return( 1 );
    }
  }

  /* process objects */
  while( (obj = WlzReadObj(inFile, NULL)) != NULL )
  {
    if( WlzGreyTypeFromObj(obj, &errNum) == WLZ_GREY_RGBA ){
      obj1 = WlzRGBAScalarBinaryOp(obj, pval, operator, &errNum);
      WlzWriteObj(stdout, obj1);
      WlzFreeObj(obj1);
    }
    else {
      WlzScalarBinaryOp(obj, pval, obj, operator);
      WlzWriteObj(stdout, obj);
      WlzFreeObj(obj);
    }
  }

  return 0;
}
예제 #20
0
파일: WlzBuildObj.c 프로젝트: omsai/Woolz
/*!
* \return	New Woolz object.
* \ingroup	WlzAllocation
* \brief	Creates a new 2D spatial domain object by adding a
* 		rectangular buffer of values to the given current
* 		object (which may be NULL or empty).
* \param	cObj			Given current object.
* \param	og			Origin of rectangular buffer.
* \param	sz			Buffer size.
* \param	gType			Grey type which must be consistent
* 					with the current object and the
* 					buffer of values.
* \param	bufSz			Number of values in the buffer.
* \param	bufP			Given buffer of values.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzBuildObj2(WlzObject *cObj,
                               WlzIVertex2 og, WlzIVertex2 sz,
                               WlzGreyType gType, int bufSz, WlzGreyP bufP,
                               WlzErrorNum *dstErr)
{
    WlzDomain	bDom;
    WlzValues	bVal,
                nVal;
    WlzObject	*bObj = NULL,
                 *nObj = NULL;
    WlzPixelV	bgdV;
    WlzErrorNum	errNum = WLZ_ERR_NONE;

    bDom.core = NULL;
    bVal.core = NULL;
    nVal.core = NULL;
    bgdV.type = WLZ_GREY_INT;
    bgdV.v.inv = 0;
    if(cObj)
    {
        WlzGreyType cGType = WLZ_GREY_ERROR;;

        switch(cObj->type)
        {
        case WLZ_EMPTY_OBJ:
            cObj = NULL;
            break;
        case WLZ_2D_DOMAINOBJ:
            if(cObj->domain.core == NULL)
            {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            else if(cObj->values.core == NULL)
            {
                errNum = WLZ_ERR_VALUES_NULL;
            }
            else
            {
                cGType = WlzGreyTypeFromObj(cObj, &errNum);
                bgdV = WlzGetBackground(cObj, &errNum);
            }
            if((errNum == WLZ_ERR_NONE) && (cGType != gType))
            {
                errNum = WLZ_ERR_GREY_TYPE;
            }
            break;
        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }
    /* Create new object with domain and values of given rectangular buffer. */
    if(errNum == WLZ_ERR_NONE)
    {
        bDom.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_RECT,
                                       og.vtY, og.vtY + sz.vtY - 1,
                                       og.vtX, og.vtX + sz.vtX - 1,
                                       &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        WlzObjectType gTT;

        gTT = WlzGreyTableType(WLZ_GREY_TAB_RECT, gType, NULL);
        bVal.r = WlzMakeRectValueTb(gTT, bDom.i->line1, bDom.i->lastln,
                                    bDom.i->kol1, sz.vtX, bgdV, bufP.inp, &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        bObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, bDom, bVal, NULL, NULL, &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        if(cObj == NULL)
        {
            /* Just copy the buffer object. */
            nObj = WlzCopyObject(bObj, &errNum);
        }
        else
        {
            /* Compute union of current and buffer objects. */
            nObj = (cObj)? WlzUnion2(cObj, bObj, &errNum):
                   WlzMakeMain(WLZ_2D_DOMAINOBJ, bDom, nVal,
                               NULL, NULL, &errNum);
            /* Create new value table. */
            if(errNum == WLZ_ERR_NONE)
            {
                WlzObjectType gTT;

                gTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gType, NULL);
                nVal.v = WlzNewValueTb(nObj, gTT, bgdV, &errNum);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                nObj->values = WlzAssignValues(nVal, NULL);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                WlzObject 	*tObj;

                /* Copy existing values to new object. */
                tObj = WlzGreyTransfer(nObj, cObj, &errNum);
                (void )WlzFreeObj(nObj);
                nObj = tObj;
                /* Then copy buffer values to new object. */
                if(errNum == WLZ_ERR_NONE)
                {
                    tObj = WlzGreyTransfer(nObj, bObj, &errNum);
                    (void )WlzFreeObj(nObj);
                    nObj = tObj;
                }
            }
        }
    }
    (void )WlzFreeObj(bObj);
    if(dstErr)
    {
        *dstErr = errNum;
    }
    return(nObj);
}
예제 #21
0
파일: WlzExtFFAm.c 프로젝트: dscho/Woolz
/*!
* \return	Woolz error code.
* \ingroup	WlzExtFF
* \brief	Writes the given Woolz 3D domain object with values to
*		the given file using the Amira lattice (.am file) format.
* \param	fP			Output file pointer
* \param	obj			Object to be written.
*/
static WlzErrorNum	WlzEffAmWrite3DDomObj(FILE *fP, WlzObject *obj)
{
  size_t	dataCnt,
  		dataSz;
  WlzDBox3	bbD;
  WlzIBox3	bbI;
  WlzIVertex3	sz,
  		org;
  WlzDVertex3	vSz;
  char		*dateS,
  		*dataTypeS;
  time_t	tTime;
  WlzGreyType	gType;
  void		***data = NULL;
  WlzErrorNum	errNum = WLZ_ERR_UNIMPLEMENTED;

  if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN)
  {
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }
  else if(obj->values.core == NULL)
  {
     errNum = WLZ_ERR_VALUES_NULL;
  }
  else if(obj->values.core->type != WLZ_VOXELVALUETABLE_GREY)
  {
    errNum = WLZ_ERR_VALUES_TYPE;
  }
  else
  {
    bbI = WlzBoundingBox3I(obj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    tTime = time(NULL);
    dateS = ctime(&tTime);
    *(dateS + strlen(dateS) - 1) = '\0';
  }
  if(errNum == WLZ_ERR_NONE)
  {
    vSz = WlzVozelSz(obj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    bbD.xMin = bbI.xMin * vSz.vtX;
    bbD.xMax = bbI.xMax * vSz.vtX;
    bbD.yMin = bbI.yMin * vSz.vtY;
    bbD.yMax = bbI.yMax * vSz.vtY;
    bbD.zMin = bbI.zMin * vSz.vtZ;
    bbD.zMax = bbI.zMax * vSz.vtZ;
    sz.vtX = bbI.xMax - bbI.xMin + 1;
    sz.vtY = bbI.yMax - bbI.yMin + 1;
    sz.vtZ = bbI.zMax - bbI.zMin + 1;
    org.vtX = bbI.xMin;
    org.vtY = bbI.yMin;
    org.vtZ = bbI.zMin;
    gType = WlzGreyTypeFromObj(obj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(gType)
    {
      case WLZ_GREY_SHORT:
	dataTypeS = "short";
        break;
      case WLZ_GREY_UBYTE:
	dataTypeS = "byte";
        break;
      default:
	errNum = WLZ_ERR_GREY_TYPE;
        break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(fprintf(fP,
               "# AmiraMesh 3D BINARY 2.0\n"
               "# WlzExtFF\n"
               "# CreationDate: %s\n"
               "\n"
               "define Lattice %d %d %d\n"
               "\n"
               "Parameters {\n"
               "    Content \"%dx%dx%d %s, uniform coordinates\",\n"
               "    BoundingBox %g %g %g %g %g %g,\n"
               "    CoordType \"uniform\"\n"
               "}\n"
	       "\n"
               "Lattice { %s Data } @1\n"
	       "\n"
               "# Data section follows\n"
               "@1\n",
	       dateS,
	       sz.vtX, sz.vtY, sz.vtZ,
	       sz.vtX, sz.vtY, sz.vtZ, dataTypeS,
	       bbD.xMin, bbD.xMax, bbD.yMin, bbD.yMax, bbD.zMin, bbD.zMax,
	       dataTypeS) <= 0)
    {
      errNum = WLZ_ERR_WRITE_INCOMPLETE;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzToArray3D(&data, obj, sz, org, 0, gType);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dataCnt = sz.vtX * sz.vtY * sz.vtZ;
    switch(gType)
    {
      case WLZ_GREY_SHORT:
	dataSz = 2;
	break;
      case WLZ_GREY_UBYTE:
	dataSz = 1;
	break;
      default:
	break;
    }
    if(fwrite(**data, dataSz, dataCnt, fP) != dataSz * dataCnt)
    {
      errNum = WLZ_ERR_WRITE_INCOMPLETE;
    }
  }
  (void )Alc3Free(data);
  return(errNum);
}
예제 #22
0
/*!
* \return	Shade corrected object or NULL on error.
* \ingroup	WlzValueFilters
* \brief	Shade corrects the given domain object with grey
*               values.
*		\f[
		  p_i = n \frac{(o_i - d_i)}{(s_i - d_i}
		\f]
*               The shade corrected image P with values \f$p_i\f$ is
*		created by applying a correction factor to each image
*		value of the given image O with values \f$o_i\f$.
*		\f$s_i\f$ and \f$d_i\f$ are the bright and dark-field
*		shade image values respectively.
* \param	srcObj			Given object to be shade corrected.
* \param	shdObj			Given bright field object.
* \param	shdDFObj		Given dark field object (may be NULL).
* \param	nrmVal			Normalization value.
* \param	inPlace			Modify the grey values of the given
*					object in place if non-zero.
* \param	dstErr			Destination error pointer, may
*                                       be null.
*/
WlzObject	*WlzShadeCorrectBFDF(
  WlzObject 	*srcObj,
  WlzObject 	*shdObj,
  WlzObject 	*shdDFObj,
  double 	nrmVal,
  int 		inPlace,
  WlzErrorNum 	*dstErr)
{
  WlzObject	*rtnObj = NULL;
  WlzObject	*obj1, *obj2;
  WlzCompoundArray	*inCobj, *outCobj;
  WlzObject	**outArray;
  WlzValues	values;
  int		i;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if((srcObj == NULL) || (shdObj == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if((srcObj->domain.core == NULL) || (shdObj->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((srcObj->values.core == NULL) || (shdObj->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else if(WlzGreyTableIsTiled(srcObj->values.core->type) ||
          WlzGreyTableIsTiled(shdObj->values.core->type))
  {
    errNum = WLZ_ERR_VALUES_TYPE;
  }
  else
  {
    switch(srcObj->type)
    {
    case WLZ_2D_DOMAINOBJ:
      if(shdObj->type != srcObj->type)
      {
	errNum = WLZ_ERR_OBJECT_TYPE;
      }
      else if( shdDFObj ){
	if( WlzGreyTypeFromObj(srcObj, &errNum) == WLZ_GREY_RGBA ){
	  obj1 = WlzRGBAImageArithmetic(srcObj, shdDFObj, WLZ_BO_SUBTRACT,
					0, &errNum);
	  obj2 = WlzRGBAImageArithmetic(shdObj, shdDFObj, WLZ_BO_SUBTRACT,
					0, &errNum);
	}
	else {
	  obj1 = WlzImageArithmetic(srcObj, shdDFObj, WLZ_BO_SUBTRACT,
				    0, &errNum);
	  obj2 = WlzImageArithmetic(shdObj, shdDFObj, WLZ_BO_SUBTRACT,
				    0, &errNum);
	}
	rtnObj = WlzShadeCorrect2D(obj1, obj2, nrmVal, inPlace, &errNum);
	WlzFreeObj(obj1);
	WlzFreeObj(obj2);;
      }
      else {
	rtnObj = WlzShadeCorrect2D(srcObj, shdObj, nrmVal, inPlace, &errNum);
      }
      break;

    case WLZ_COMPOUND_ARR_1:
    case WLZ_COMPOUND_ARR_2:
      inCobj = (WlzCompoundArray *) srcObj;
      if( inCobj->n > 0 ){
	if( (outArray = (WlzObject **)
	     AlcCalloc(inCobj->n, sizeof(WlzObject *))) == NULL){
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else {
	  for(i=0; (i < inCobj->n) && (errNum == WLZ_ERR_NONE); i++){
	    /* allow special behaviour of a non-compound shade image
	       to be used for each object in a compound but must align */
	    switch( shdObj->type ){
	    case WLZ_2D_DOMAINOBJ:
	    case WLZ_3D_DOMAINOBJ:
	      outArray[i] = WlzShadeCorrectBFDF(inCobj->o[i],
						shdObj, shdDFObj,
						nrmVal, inPlace, &errNum);
	      break;

	    case WLZ_COMPOUND_ARR_1:
	    case WLZ_COMPOUND_ARR_2:
	      outArray[i] =
		WlzShadeCorrectBFDF(inCobj->o[i],
				    ((WlzCompoundArray *) shdObj)->o[i],
				    shdDFObj?
				    ((WlzCompoundArray *) shdDFObj)->o[i]:NULL,
				    nrmVal, inPlace, &errNum);
	      break;
	    default:
	      errNum = WLZ_ERR_OBJECT_TYPE;
	      break;
	    }
	      
	  }
	  if( errNum == WLZ_ERR_NONE ){
	    outCobj = WlzMakeCompoundArray(srcObj->type, 3, inCobj->n,
					   outArray, outArray[0]->type,
					   &errNum);
	    rtnObj = (WlzObject *) outCobj;
	  }
	  else {
	    while( i >= 0 ){
	      WlzFreeObj(outArray[i--]);
	    }
	  }
	  AlcFree(outArray);
	}
      }
      else {
	errNum = WLZ_ERR_OBJECT_DATA;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      errNum = WLZ_ERR_UNIMPLEMENTED;
      break;

    case WLZ_TRANS_OBJ:
      if((rtnObj = WlzShadeCorrectBFDF(srcObj->values.obj,
                                       shdObj, shdDFObj, nrmVal,
				       inPlace, &errNum)) != NULL){
	values.obj = rtnObj;
	return WlzMakeMain(WLZ_TRANS_OBJ, srcObj->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rtnObj);
}