Ejemplo n.º 1
0
WlzObject *WlzRGBABoxThreshold(
  WlzObject	*obj,
  WlzPixelV	lowVal,
  WlzPixelV	highVal,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  int		h, l;
  WlzUInt	combineMode;

  /* check and reset low annd high values */
  l = WLZ_RGBA_RED_GET(lowVal.v.rgbv);
  h = WLZ_RGBA_RED_GET(highVal.v.rgbv);
  if( l > h ){
    WLZ_RGBA_RED_SET(highVal.v.rgbv, l);
    WLZ_RGBA_RED_SET(lowVal.v.rgbv, h);
  }
  l = WLZ_RGBA_GREEN_GET(lowVal.v.rgbv);
  h = WLZ_RGBA_GREEN_GET(highVal.v.rgbv);
  if( l > h ){
    WLZ_RGBA_GREEN_SET(highVal.v.rgbv, l);
    WLZ_RGBA_GREEN_SET(lowVal.v.rgbv, h);
  }
  l = WLZ_RGBA_BLUE_GET(lowVal.v.rgbv);
  h = WLZ_RGBA_BLUE_GET(highVal.v.rgbv);
  if( l > h ){
    WLZ_RGBA_BLUE_SET(highVal.v.rgbv, l);
    WLZ_RGBA_BLUE_SET(lowVal.v.rgbv, h);
  }

  /* set all AND for combine value and call multi-threshold */
  WLZ_RGBA_RGBA_SET(combineMode,
		    WLZ_BO_AND, WLZ_BO_AND, WLZ_BO_AND, 255);
  rtnObj = WlzRGBAMultiThreshold(obj, lowVal, highVal,
				 combineMode, &errNum);

  /* check error and return */
  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Ejemplo n.º 2
0
void warpSetSignalDomain(
  WlzIVertex2	*selVtx)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzPixelV	threshV, threshV1;
  WlzObject	*obj, *obj1;
  WlzUInt	combineMode;

  /* image processing sequence */
  if( warpGlobals.sgnlThreshObj == NULL ){
    warpSetSignalThreshObj();
  }
  if( warpGlobals.sgnlThreshObj ){
    obj1 = WlzAssignObject(warpGlobals.sgnlThreshObj, &errNum);
  }
  else {
    return;
  }

  /* threshold the resultant image */
  if( errNum == WLZ_ERR_NONE ){
    switch( warpGlobals.thresholdType ){
    case WLZ_RGBA_THRESH_NONE:
      break;

    case WLZ_RGBA_THRESH_SINGLE:
      threshV.type = WLZ_GREY_INT;
      threshV.v.inv = warpGlobals.threshRangeLow;
      if( obj1 ){
	/* clear signal object */
	if( warpGlobals.sgnlObj ){
	  WlzFreeObj(warpGlobals.sgnlObj);
	}
	  
	if((obj = WlzThreshold(obj1, threshV, WLZ_THRESH_HIGH, &errNum)) && (WlzVolume(obj, &errNum) > 0)){
	  obj = WlzAssignObject(obj, &errNum);
	  WlzFreeObj(obj1);
	  threshV.v.inv = warpGlobals.threshRangeHigh + 1;
	  if((obj1 = WlzThreshold(obj, threshV, WLZ_THRESH_LOW, &errNum)) && (WlzVolume(obj1, &errNum) > 0)){
	    warpGlobals.sgnlObj = WlzAssignObject(obj1, &errNum);
	  }
	  else {
	    if( obj1 ){
	      WlzFreeObj(obj1);
	    }
	    warpGlobals.sgnlObj = NULL;
	  }
	  WlzFreeObj(obj);
	}
	else {
	  if( obj ) {
	    WlzFreeObj(obj);
	  }
	  WlzFreeObj(obj1);
	  warpGlobals.sgnlObj = NULL;
	}
      }
      break;

    case WLZ_RGBA_THRESH_MULTI:
      /* clear signal object */
      if( warpGlobals.sgnlObj ){
	WlzFreeObj(warpGlobals.sgnlObj);
      }

      /* set the thresholds and combine mode */
      threshV.type = WLZ_GREY_RGBA;
      WLZ_RGBA_RGBA_SET(threshV.v.rgbv,
			warpGlobals.threshRangeRGBLow[0],
			warpGlobals.threshRangeRGBLow[1],
			warpGlobals.threshRangeRGBLow[2],
			255);
      threshV1.type = WLZ_GREY_RGBA;
      WLZ_RGBA_RGBA_SET(threshV1.v.rgbv,
			warpGlobals.threshRangeRGBHigh[0],
			warpGlobals.threshRangeRGBHigh[1],
			warpGlobals.threshRangeRGBHigh[2],
			255);
      WLZ_RGBA_RGBA_SET(combineMode,
			WLZ_BO_AND, WLZ_BO_AND, WLZ_BO_AND, 255);

      /* use multi-threshold */
      if((obj = WlzRGBAMultiThreshold(obj1, threshV, threshV1,
				      combineMode, &errNum))){
	if( WlzIsEmpty(obj, &errNum) ){
	    WlzFreeObj(obj);
	    warpGlobals.sgnlObj = NULL;
	} else {
	    warpGlobals.sgnlObj = WlzAssignObject(obj, &errNum);
	}
      }
      else {
	warpGlobals.sgnlObj = NULL;
      }
      WlzFreeObj(obj1);
      break;

    case WLZ_RGBA_THRESH_BOX:
      /* clear signal object */
      if( warpGlobals.sgnlObj ){
	WlzFreeObj(warpGlobals.sgnlObj);
      }

      /* use box-threshold */
      if((obj = WlzRGBABoxThreshold(obj1,
				    warpGlobals.lowRGBPoint,
				    warpGlobals.highRGBPoint,
				    &errNum))){
	if( WlzIsEmpty(obj, &errNum) ){
	    WlzFreeObj(obj);
	    warpGlobals.sgnlObj = NULL;
	} else {
	    warpGlobals.sgnlObj = WlzAssignObject(obj, &errNum);
	}
      }
      else {
	warpGlobals.sgnlObj = NULL;
      }
      WlzFreeObj(obj1);	  
      break;

    case WLZ_RGBA_THRESH_SLICE:
      /* clear signal object */
      if( warpGlobals.sgnlObj ){
	WlzFreeObj(warpGlobals.sgnlObj);
      }

      /* use slice-threshold */
      if((obj = WlzRGBASliceThreshold(obj1,
				      warpGlobals.lowRGBPoint,
				      warpGlobals.highRGBPoint,
				      &errNum))){
	if( WlzIsEmpty(obj, &errNum) ){
	    WlzFreeObj(obj);
	    warpGlobals.sgnlObj = NULL;
	} else {
	    warpGlobals.sgnlObj = WlzAssignObject(obj, &errNum);
	}
      }
      else {
	warpGlobals.sgnlObj = NULL;
      }
      WlzFreeObj(obj1);	  
      break;

    case WLZ_RGBA_THRESH_SPHERE:
      /* clear signal object */
      if( warpGlobals.sgnlObj ){
	WlzFreeObj(warpGlobals.sgnlObj);
      }

      /* use Ellipsoid-threshold */
      if((obj = WlzRGBAEllipsoidThreshold(obj1,
					  warpGlobals.lowRGBPoint,
					  warpGlobals.highRGBPoint,
					  warpGlobals.colorEllipseEcc,
					  &errNum))){
	if( WlzIsEmpty(obj, &errNum) ){
	    WlzFreeObj(obj);
	    warpGlobals.sgnlObj = NULL;
	} else {
	    warpGlobals.sgnlObj = WlzAssignObject(obj, &errNum);
	}
      }
      else {
	warpGlobals.sgnlObj = NULL;
      }
      WlzFreeObj(obj1);	  
      break;

    default:
      errNum = WLZ_ERR_PARAM_DATA;
      if( obj1 ){
	WlzFreeObj(obj1);
      }
      if( warpGlobals.sgnlObj ){
	WlzFreeObj(warpGlobals.sgnlObj);
	warpGlobals.sgnlObj = NULL;
      }
      break;
    }
  }

  /* check for local mode */
  if( warpGlobals.sgnlObj && !warpGlobals.globalThreshFlg ){
    if( selVtx != NULL ){
      warpGlobals.globalThreshVtx = *selVtx;
    }
    /* extract a local domain if the vertex is sensible */
    if( warpGlobals.globalThreshVtx.vtX != -10000 ){
      WlzObject	**objs=NULL;
      int	i, numObjs;
      double	x, y;
      obj1 = NULL;
      x = warpGlobals.globalThreshVtx.vtX;
      y = warpGlobals.globalThreshVtx.vtY;
      errNum = WlzLabel(warpGlobals.sgnlObj, &numObjs, &objs, 8192, 0,
			WLZ_4_CONNECTED);
      if( (errNum == WLZ_ERR_INT_DATA) && (numObjs == 8192) ){
	WlzObject	*tmpObj1, *tmpObj2;
	WlzDomain	domain;
	WlzValues	values;

	/* try again, smaller domain */
	for(i=0; i < numObjs; i++){
	  WlzFreeObj( objs[i] );
	}
	AlcFree((void *) objs);
	objs = NULL;
	numObjs = 0;
	domain.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_RECT,
					 y - 80, y + 80,
					 x - 80, x + 80, &errNum);
	values.core = NULL;
	if((tmpObj1 = WlzMakeMain(warpGlobals.sgnlObj->type, domain, values,
				  NULL, NULL, &errNum))){
	  if((tmpObj2 = WlzIntersect2(warpGlobals.sgnlObj, tmpObj1, &errNum))){
	    tmpObj2->values = WlzAssignValues(warpGlobals.sgnlObj->values, NULL);
	    errNum = WlzLabel(warpGlobals.sgnlObj, &numObjs, &objs, 8192, 0,
			      WLZ_4_CONNECTED);
	    WlzFreeObj(tmpObj2);
	    if((errNum == WLZ_ERR_INT_DATA) && (numObjs == 8192) ){
	      errNum = WLZ_ERR_NONE;
	    }
	  }
	  WlzFreeObj(tmpObj1);
	}
	
      }
      if( errNum == WLZ_ERR_NONE ){

	for(i=0; i < numObjs; i++){
	  if( WlzInsideDomain( objs[i], 0.0, y, x, NULL ) ){
	    obj1 = WlzMakeMain(objs[i]->type,
			       objs[i]->domain,
			       objs[i]->values,
			       NULL, NULL, NULL);
	    obj1 = WlzAssignObject(obj1, NULL);
	  }
	  WlzFreeObj( objs[i] );
	}
	AlcFree((void *) objs);
      }
      if( obj1 ){
	WlzFreeObj(warpGlobals.sgnlObj);
	warpGlobals.sgnlObj = obj1;
      }
    }
    else {
      WlzFreeObj(warpGlobals.sgnlObj);
      warpGlobals.sgnlObj = NULL;
    }
  }

  /* check for increment mode */
  if( warpGlobals.incrThreshFlg && sgnlIncrObj() ){
    if( warpGlobals.sgnlObj ){
      if((obj1 = WlzUnion2(warpGlobals.sgnlObj, sgnlIncrObj(),
			   &errNum))){
	WlzFreeObj(warpGlobals.sgnlObj);
	warpGlobals.sgnlObj = WlzAssignObject(obj1, &errNum);
      }
    }
    else {
      warpGlobals.sgnlObj = WlzAssignObject(sgnlIncrObj(),
					    &errNum);
    }
  }

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "warpSetSignalDomain", errNum);
  }
  return;
}
Ejemplo n.º 3
0
/*! 
* \ingroup      WlzThreshold
* \brief        Apply independent thresholds to each colour channel
 independently and combine according to the settings encoded in
 combineMode. Each channel can have one of two modes: WLZ_BO_AND
 and WLZ_BO_OR. These are encoded into a single mode variable using
 the RGBA macro, e.g.:
 WLZ_RGBA_RGBA_SET(combineMode, redMode, greenMode, blueMode, 255);

 The macro WLZ_RGBA_RED_GET(combineMode) will return redMode and
 similarly for green and blue.
*
* \return       Thresholded object
* \param    obj	Object to be thresholded
* \param    lowVal	RGB low values
* \param    highVal	RGB high values
* \param    combineMode	Combination rules as an RGBA encoded unsigned integer
* \param    dstErr	Error return
* \par      Source:
*                WlzRGBAThreshold.c
*/
WlzObject *WlzRGBAMultiThreshold(
  WlzObject	*obj,
  WlzPixelV	lowVal,
  WlzPixelV	highVal,
  WlzUInt	combineMode,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  WlzObject	*obj1, *obj2;
  WlzValues	values;
  WlzCompoundArray	*cobj=NULL;
  int		low[3], high[3];
  WlzUInt	mode[3]; 

  /* check inputs */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    /* must be grey-type RGBA or compound with at least three channels */
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
    case WLZ_3D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      else {
	/* create compound object */
	if((cobj = WlzRGBAToCompound(obj, WLZ_RGBA_SPACE_RGB,
	                             &errNum)) != NULL){
	  cobj = (WlzCompoundArray *) WlzAssignObject((WlzObject *) cobj,
						      &errNum);
	}
      }
      break;

    case WLZ_TRANS_OBJ:
      if((obj1 = WlzRGBAMultiThreshold(obj->values.obj, lowVal, highVal,
				       combineMode, &errNum)) != NULL){
	values.obj = WlzAssignObject(obj1, NULL);
	rtnObj = WlzMakeMain(obj->type, obj->domain, values,
			     NULL, obj, &errNum);
      }
      break;

    case WLZ_COMPOUND_ARR_1:
    case WLZ_COMPOUND_ARR_2:
      cobj = (WlzCompoundArray *) WlzAssignObject(obj, &errNum);
      if( cobj->n < 3 ){
	errNum = WLZ_ERR_OBJECT_DATA;
	WlzFreeObj((WlzObject *) cobj);
      }
      else if((cobj->o[0]->values.core == NULL) ||
	      (cobj->o[1]->values.core == NULL) ||
	      (cobj->o[2]->values.core == NULL)){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      break;

    case WLZ_EMPTY_OBJ:
      rtnObj = WlzMakeEmpty(&errNum);
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  if((errNum == WLZ_ERR_NONE) && (rtnObj == NULL)){
    if((lowVal.type != WLZ_GREY_RGBA) ||
       (highVal.type != WLZ_GREY_RGBA)){
      errNum = WLZ_ERR_PARAM_TYPE;
    }
    else {
      low[0] = WLZ_RGBA_RED_GET(lowVal.v.rgbv);
      low[1] = WLZ_RGBA_GREEN_GET(lowVal.v.rgbv);
      low[2] = WLZ_RGBA_BLUE_GET(lowVal.v.rgbv);
      high[0] = WLZ_RGBA_RED_GET(highVal.v.rgbv);
      high[1] = WLZ_RGBA_GREEN_GET(highVal.v.rgbv);
      high[2] = WLZ_RGBA_BLUE_GET(highVal.v.rgbv);
    }
  }

  if((errNum == WLZ_ERR_NONE) && (rtnObj == NULL)){
    mode[0] = WLZ_RGBA_RED_GET(combineMode);
    mode[1] = WLZ_RGBA_GREEN_GET(combineMode);
    mode[2] = WLZ_RGBA_BLUE_GET(combineMode);
  }

  /* get thresholded channels */
  if((errNum == WLZ_ERR_NONE) &&
     (cobj != NULL) && (rtnObj == NULL)){
    WlzObject	*objs[3];
    int		i;
    WlzPixelV	threshV;

    for(i=0; i < 3; i++){
      threshV.type = WLZ_GREY_INT;
      threshV.v.inv = low[i];
      if((obj1 = WlzThreshold(cobj->o[i], threshV, WLZ_THRESH_HIGH,
      			      &errNum)) != NULL){
	obj1 = WlzAssignObject(obj1, &errNum);
	threshV.v.inv = high[i] + 1;
	if((obj2 = WlzThreshold(obj1, threshV, WLZ_THRESH_LOW,
	                        &errNum)) != NULL){
	  objs[i] = WlzAssignObject(obj2, &errNum);
	}
	else {
	  objs[i] = NULL;
	}
	WlzFreeObj(obj1);
      }
      else {
	objs[i] = NULL;
      }
    }

    /* combine according to mode
       what to do here? AND against a channel implies that the threshold
       constraint must be satisfied, OR implies it may be satisfied so
       all AND implies intersection, all OR implies union. Otherwise union
       of ORs and intersect with the ANDs. What about XOR? */
    /* find union of all then intersect with ANDs */
    obj1 = WlzAssignObject(WlzMakeEmpty(&errNum), NULL);
    for(i=0; (i < 3) && (errNum == WLZ_ERR_NONE); i++){
      if( objs[i] ){
	obj2 = WlzUnion2(obj1, objs[i], &errNum);
	WlzFreeObj(obj1);
	obj1 = WlzAssignObject(obj2, &errNum);
      }
    }
    for(i=0; i < 3; i++){
      if( objs[i] ){
	if( (mode[i] == WLZ_BO_AND) && (errNum == WLZ_ERR_NONE) ){
	  obj2 = WlzIntersect2(obj1, objs[i], &errNum);
	  WlzFreeObj(obj1);
	  obj1 = WlzAssignObject(obj2, &errNum);
	}
	WlzFreeObj(objs[i]);
      }
    }

    /* create the return object and add grey-table if possible */
    if( obj1 ){
      if( WlzIsEmpty(obj1, &errNum) ){
	rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj1->values,
			     NULL, NULL, &errNum);
      }
      else {
	if( obj1->type == obj->type ){
	  rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj->values,
			       NULL, NULL, &errNum);
	}
	else {
	  rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj1->values,
			       NULL, NULL, &errNum);
	}
      }
      WlzFreeObj(obj1);
    }
  }

  if( cobj ){
    WlzFreeObj((WlzObject *) cobj);
  }

  /* check error and return */
  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}