示例#1
0
int             main(int argc, char **argv)
{
  int		tI,
		idN,
  		option,
		con = WLZ_0_CONNECTED,
		nLo = 0,
		nHi = 0,
		maxSep = 1024,
		nObj = 0,
  		ok = 1,
		usage = 0;
  char		tC;
  double  	tD,
		mrkMass = 1.0,
  		rad = 0.0;
  int		tR[4];
  WlzPixelV	gV,
  		bV;
  WlzBlobMark	mrk = WLZ_BLOBMARK_CIRCLE;
  WlzObject     *inObj = NULL,
  		*outObj = NULL,
		*mrkObj = NULL;
  WlzObject	**lObj = NULL;
  FILE		*fP = NULL;
  char 		*inObjFileStr,
  		*outObjFileStr;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
  static char	optList[] = "c:g:G:hm:n:N:o:r:x:",
  		fileStrDef[] = "-";

  opterr = 0;
  memset(&gV, 0, sizeof(WlzPixelV));
  bV.type = WLZ_GREY_UBYTE;
  bV.v.ubv = 0;
  gV.type = WLZ_GREY_ERROR;
  inObjFileStr = fileStrDef;
  outObjFileStr = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'c':
        if(sscanf(optarg, "%d", &tI) != 1)
	{
	  usage = 1;
	}
	else
	{
	  switch(tI)
	  {
	    case  4:
	      con = WLZ_4_CONNECTED;
	      break;
	    case  6:
	      con = WLZ_6_CONNECTED;
	      break;
	    case  8:
	      con = WLZ_8_CONNECTED;
	      break;
	    case 18:
	      con = WLZ_18_CONNECTED;
	      break;
	    case 26:
	      con = WLZ_26_CONNECTED;
	      break;
	    default:
	      usage = 1;
	      break;
	  }
	}
	break;
      case 'g':
        switch(gV.type)
	{
	  case WLZ_GREY_UBYTE:
	    if((sscanf(optarg, "%d", &tI) != 1) ||
	       (tI < 0) || (tI > 255))
	    {
	      usage = 1;
	    }
	    else
	    {
	      gV.v.ubv = tI;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    if((sscanf(optarg, "%d", &tI) != 1) ||
	       (tI < SHRT_MIN) || (tI > SHRT_MAX))
	    {
	      usage = 1;
	    }
	    else
	    {
	      gV.v.shv = tI;
	    }
	    break;
	  case WLZ_GREY_INT:
	    if(sscanf(optarg, "%d", &tI) != 1)
	    {
	      usage = 1;
	    }
	    else
	    {
	      gV.v.inv = tI;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    if((sscanf(optarg, "%lg", &tD) != 1) ||
	       (tD < -(FLT_MAX)) || (tD > FLT_MAX))
	    {
	      usage = 1;
	    }
	    else
	    {
	      gV.v.flv = tD;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    if(sscanf(optarg, "%lg", &tD) != 1)
	    {
	      usage = 1;
	    }
	    else
	    {
	      gV.v.dbv = tD;
	    }
	    break;
	  case WLZ_GREY_RGBA:
	    tR[3] = 255;
	    tR[0] = tR[1] = tR[2] = 0;
	    if((sscanf(optarg, "%d,%d,%d,%d",
	               &(tR[0]), &(tR[1]), &(tR[2]), &(tR[3])) == 0) ||
	       (tR[0] < 0) || (tR[0] > 255) ||
	       (tR[1] < 0) || (tR[1] > 255) ||
	       (tR[2] < 0) || (tR[2] > 255) ||
	       (tR[3] < 0) || (tR[3] > 255))
	    {
	      usage = 1;
	    }
	    else
	    {
	      WLZ_RGBA_RGBA_SET(gV.v.rgbv, tR[0], tR[1], tR[2], tR[3]);
	    }
	    break;
	  default:
	    usage = 1;
	    break;
	}
	break;
      case 'G':
        if(sscanf(optarg, "%c", &tC) != 1)
	{
	  usage = 1;
	}
	switch(tC)
	{
	  case 'v':
	    gV.type = WLZ_GREY_ERROR;
	    break;
	  case 'u':
	    gV.type = WLZ_GREY_UBYTE;
	    break;
	  case 's':
	    gV.type = WLZ_GREY_SHORT;
	    break;
	  case 'i':
	    gV.type = WLZ_GREY_INT;
	    break;
	  case 'f':
	    gV.type = WLZ_GREY_FLOAT;
	    break;
	  case 'd':
	    gV.type = WLZ_GREY_DOUBLE;
	    break;
	  case 'r':
	    gV.type = WLZ_GREY_RGBA;
	    break;
	  default:
	    usage = 1;
	    break;
	}
	break;
      case 'm':
        if((sscanf(optarg, "%d", &tI) != 1) ||
	   ((tI != WLZ_BLOBMARK_CIRCLE) && (tI != WLZ_BLOBMARK_SQUARE)))
	{
	  usage = 1;
	}
	else
	{
	  mrk = (WlzBlobMark )tI;
	}
	break;
      case 'n':
        if((sscanf(optarg, "%d", &nLo) != 1) || (nLo < 0))
	{
	  usage = 1;
	}
	break;
      case 'N':
        if((sscanf(optarg, "%d", &nHi) != 1) || (nHi < 0))
	{
	  usage = 1;
	}
	break;
      case 'o':
        outObjFileStr = optarg;
	break;
      case 'r':
        if((sscanf(optarg, "%lg", &rad) != 1) || (rad < 0.0))
	{
	  usage = 1;
	}
	break;
      case 'x':
        if((sscanf(optarg, "%d", &maxSep) != 1) || (maxSep < 1))
	{
	  usage = 1;
	}
      case 'h': /* FALLTHROUGH */
      default:
        usage = 1;
	break;
    }
  }
  if((usage == 0) && (nLo > nHi) && (nHi != 0))
  {
    usage = 1;
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  ok = (usage == 0);
  /* Read input domain object. */
  if(ok)
  {
    if((inObjFileStr == NULL) ||
	(*inObjFileStr == '\0') ||
	((fP = (strcmp(inObjFileStr, "-")?
	       fopen(inObjFileStr, "r"): stdin)) == NULL) ||
	((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
	(errNum != WLZ_ERR_NONE))
    {
      ok = 0;
    }
    if(fP)
    {
      if(strcmp(inObjFileStr, "-"))
      {
	(void )fclose(fP);
      }
      fP = NULL;
    }
  }
  /* Check object type and connectivity. */
  if(ok)
  {
    switch(inObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	switch(con)
	{
	  case WLZ_0_CONNECTED:
	    con = WLZ_8_CONNECTED;
	    break;
	  case WLZ_4_CONNECTED: /* FALLTHROUGH */
	  case WLZ_8_CONNECTED:
	    break;
	  default:
	    ok = 0;
	    errNum = WLZ_ERR_PARAM_DATA;
	    (void )WlzStringFromErrorNum(errNum, &errMsg);
	    (void )fprintf(stderr,
	           "%s: Connectivity for 2D must be 4 or 8 (%s).\n",
		   *argv, errMsg);
	    break;
	}
	break;
      case WLZ_3D_DOMAINOBJ:
	switch(con)
	{
	  case WLZ_0_CONNECTED:
	    con = WLZ_26_CONNECTED;
	    break;
	  case  WLZ_6_CONNECTED: /* FALLTHROUGH */
	  case WLZ_18_CONNECTED: /* FALLTHROUGH */
	  case WLZ_26_CONNECTED:
	    break;
	  default:
	    ok = 0;
	    errNum = WLZ_ERR_PARAM_DATA;
	    (void )WlzStringFromErrorNum(errNum, &errMsg);
	    (void )fprintf(stderr,
	           "%s: Connectivity for 3D must be 6, 18 or 26 (%s).\n",
		   *argv, errMsg);
	    break;
	}
	break;
      default:
	ok = 0;
	errNum = WLZ_ERR_OBJECT_TYPE;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	       "%s: Input object must either a 2 or 3D domain object (%s).\n",
	       *argv, errMsg);
	break;
    }
  }
  /* Make basic marker with centre at the origin. */
  if(ok)
  {
    double	mrkRad;

    if(rad > 0.5)
    {
      mrkRad = rad;
    }
    else
    {
      mrkRad = 127;
    }
    if(mrk == WLZ_BLOBMARK_SQUARE)
    {
      mrkObj = WlzMakeCuboidObject(inObj->type, mrkRad, mrkRad, mrkRad,
                                   0, 0, 0, &errNum);
    }
    else /* mrk = WLZ_BLOBMARK_CIRCLE */
    {
      mrkObj = WlzMakeSphereObject(inObj->type, mrkRad, 0, 0, 0, &errNum);
    }
    if(mrkObj == NULL)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
             "%s: Failed to create basic marker object (%s).\n",
	     *argv, errMsg);
    }
    else
    {
      mrkMass = WlzVolume(mrkObj, NULL);
    }
  }
  /* Label the given domain. */
  if(ok)
  {
    errNum = WlzLabel(inObj, &nObj, &lObj, maxSep, 1, con);
    if((errNum != WLZ_ERR_NONE) || (nObj == 0))
    {
      ok = 0;
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = WLZ_ERR_DOMAIN_DATA;
      }
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      "%s: Failed to split the given object into separate regions (%s)\n",
      *argv, errMsg);
    }
  }
  /* Work through the separate object list removing small/large objects
   * according to the low and high thresholds. */
  if(ok)
  {
    int		idM;

    for(idN = 0, idM = 0; idN < nObj; ++idN)
    {
      int	vol;

      vol = WlzVolume(lObj[idN], &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
        if(((nLo > 0) && (vol < nLo)) || ((nHi > 0) && (vol > nHi)))
	{
	  (void )WlzFreeObj(lObj[idN]);
	}
	else
	{
	  lObj[idM] = lObj[idN];
	  ++idM;
	}
      }
    }
    nObj = idM;
    if(nObj == 0)
    {
      ok = 0;
      errNum = WLZ_ERR_DOMAIN_DATA;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to find and separate regions (%s)\n",
		     *argv, errMsg);

    }
  }
  /* Build a marker object by adding a mark at the centre of mass of each
   * separate fragment. */
  if(ok)
  {
    WlzObject	*obj0 = NULL;

    idN = 0;
    obj0 = WlzMakeEmpty(&errNum);
    while((errNum == WLZ_ERR_NONE) && (idN < nObj))
    {
      double	  mass;
      WlzDVertex3 com;
      WlzObject	  *obj1 = NULL,
      		  *obj2 = NULL;
      WlzAffineTransform *tr = NULL;

      com = WlzCentreOfMass3D(lObj[idN], 1, &mass, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
        double	s;

	if(rad < 0.5)
	{
	  double t;

	  t = mass / mrkMass;
	  if(inObj->type == WLZ_2D_DOMAINOBJ)
	  {
	    s = sqrt(t);
	  }
	  else /* inObj->type == WLZ_3D_DOMAINOBJ */
	  {
	    s = cbrt(t);
	  }
	}
	else
	{
	  s = 1.0;
	}
        tr = (inObj->type == WLZ_2D_DOMAINOBJ)?
             WlzAffineTransformFromPrimVal(
	       WLZ_TRANSFORM_2D_AFFINE, com.vtX, com.vtY, 0.0,
	       s, 0.0, 0.0, 0.0, 0.0, 0.0, 0, &errNum):
             WlzAffineTransformFromPrimVal(
	       WLZ_TRANSFORM_3D_AFFINE, com.vtX, com.vtY, com.vtZ,
	       s, 0.0, 0.0, 0.0, 0.0, 0.0, 0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	obj1 = WlzAffineTransformObj(mrkObj, tr, WLZ_INTERPOLATION_NEAREST,
				     &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	obj2 = WlzUnion2(obj0, obj1, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
        (void )WlzFreeObj(obj0);
	obj0 = obj2;
	obj2 = NULL;
      }
      (void )WlzFreeObj(obj1);
      (void )WlzFreeObj(obj2);
      (void )WlzFreeAffineTransform(tr);
      ++idN;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      WlzValues	val;
      WlzObjectType vTT;

      val.core = NULL;
      if(gV.type != WLZ_GREY_ERROR)
      {
	vTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gV.type, NULL);
	if(inObj->type == WLZ_2D_DOMAINOBJ)
	{
	  val.v = WlzNewValueTb(obj0, vTT, bV, &errNum);
	}
	else /* inObj->type == WLZ_3D_DOMAINOBJ */
	{
	  val.vox = WlzNewValuesVox(obj0, vTT, bV, &errNum);
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
        outObj = WlzMakeMain(inObj->type, obj0->domain, val, NULL, NULL,
	                     &errNum);
      }
      if((errNum == WLZ_ERR_NONE) && (gV.type != WLZ_GREY_ERROR))
      {
        errNum = WlzGreySetValue(outObj, gV);
      }
    }
  }
  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, "-"))
    {
      (void )fclose(fP);
    }
  }
  (void )WlzFreeObj(inObj);
  if(lObj != NULL)
  {
    for(idN = 0; idN < nObj; ++idN)
    {
      (void )WlzFreeObj(lObj[idN]);
    }
    AlcFree(lObj);
  }
  (void )WlzFreeObj(outObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%sExample: %s%s",
    *argv,
    " [-c#] [-g#] [-G#] [-h] [-m#] [-n#] [-N#]\n"
    "       [-o<output object>] [-r#]] [-x#] [<input object>]\n"
    "Options:\n"
    "  -c  Connectivity: 4, 6, 8, 18 or 26 connected (default 8 for 2D\n"
    "      domains and 26 for 3D domains).\n"
    "  -g  Grey value for marker. This is a single number for all except\n"
    "      RGBA (colour) grey values. RGBA components must be separated by\n"
    "      by a comma.\n"
    "  -G  Grey value type for marker specified by letter:\n"
    "        v  no grey values (default).\n"
    "        u  unsigned byte grey values.\n"
    "        s  short grey values.\n"
    "        i  int grey values.\n"
    "        f  int grey values.\n"
    "        d  int grey values.\n"
    "        r  red, green, blue, alpha grey values.\n"
    "  -h  Help, prints usage message.\n"
    "  -m  Marker type specified by a number:\n"
    "        1  circle/sphere (default)\n"
    "        2  square/cube\n"
    "  -n  Threshold minimum area/volume of blob for a marker (default\n"
    "      >= 1).\n"
    "  -N  Threshold maximum area/volume of blob for a marker. If zero\n"
    "      there is no upper limit. (default  0).\n"
    "  -o  Output object file.\n"
    "  -r  Marker radius. Attempts to keep the same area/volume if zero.\n"
    "      (default 0).\n"
    "  -x  Maximum number of separate regions in the object (default 1024).\n"
    "Reads a spatial domain object and replaces each spatialy separate\n"
    "region with a marker placed at the centre of mass of the region.\n"
    "All files are read from the standard input and written to the standard\n"
    "output unless filenames are given.\n"
    "If grey values are required then the grey value type must be set before\n"
    "the actual grey value.\n",
    *argv,
    " -o out.wlz -n 4 -r 10 -G r -g 200,100,0,255 in.wlz\n"
    "A spatial domain object is read from the file in.wlz and each\n"
    "spatialy separate region of the domain is replaced by a circle or\n"
    "sphere of radius 10 (pixels). All small regions with less than four\n"
    "(pixels voxels) is ignored. The output object (with grey values set\n"
    "to orange) is written to the file out.wlz.\n");
  }
  return(!ok);
}
示例#2
0
/*! 
* \ingroup      WlzBoundary
* \brief        Convert the input boundary list to a domain object.
 Use WlzBoundaryToObj if conversion of a 3D stack of boundary list is required
 or if the boundary is available as a first class object.
*
* \return       Domain object corresponding to the input boundary domain,
 NULL on error.
* \param    bound	Input boundary list domain.
* \param    fillMode	Polyline fill mode, see WlzPolyToObj().
* \param    dstNum	Error return.
* \par      Source:
*                WlzBoundToObj.c
*/
WlzObject *WlzBoundToObj(
  WlzBoundList		*bound,
  WlzPolyFillMode	fillMode,
  WlzErrorNum		*dstNum)
{
  WlzObject *obj, *selfobj = NULL, *nextobj, *downobj;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check input */
  if( bound == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* find object corresponding to the current boundary */
  if( errNum == WLZ_ERR_NONE ){
    if( bound->poly != NULL ){
      selfobj = WlzPolyToObj(bound->poly, fillMode, &errNum);
    }
    else {
      selfobj = NULL;
    }
  }
  if( (errNum == WLZ_ERR_NONE) && (selfobj != NULL)
     && (bound->type != WLZ_BOUNDLIST_PIECE)
     && (fillMode != WLZ_VERTEX_FILL) ){
    obj = WlzErosion(selfobj, WLZ_4_CONNECTED, &errNum);
    WlzFreeObj(selfobj);
    selfobj = obj;
  }

  /* add object corresponding to next */
  if( (errNum == WLZ_ERR_NONE) && bound->next ){
    nextobj = WlzBoundToObj(bound->next, fillMode, &errNum);
    if( selfobj == NULL ){
      selfobj = nextobj;
    }
    else {
      if( (errNum == WLZ_ERR_NONE) && (nextobj != NULL) ){
	obj = WlzUnion2(selfobj, nextobj, &errNum);
	WlzFreeObj(nextobj);
	WlzFreeObj(selfobj);
	selfobj = obj;
      }
    }
  }

  /* remove object corresponding to down */
  if( (errNum == WLZ_ERR_NONE) && bound->down ){
    downobj = WlzBoundToObj(bound->down, fillMode, &errNum);
    if( downobj != NULL ){
      if( selfobj != NULL ){
	if( fillMode != WLZ_VERTEX_FILL ){
	  obj = WlzDiffDomain(selfobj, downobj, &errNum);
	}
	else {
	  obj = WlzUnion2(selfobj, downobj, &errNum);
	}
	WlzFreeObj(selfobj);
	selfobj = obj;
      }
      WlzFreeObj(downobj);
    }
  }

  /* return object */
  if( dstNum ){
    *dstNum = errNum;
  }
  return(selfobj);
}
示例#3
0
/*!
* \return	Woolz error code.
* \ingroup	WlzBinaryOps
* \brief	Make temporary objects as in WlzRCCTOIdx for
* 		WlzRegConCalcRCC().
* \param	o			Array of objects, o[0] and o[1].
* \param	t			Array of temporary objects.
* \param	i			Temporary object index.
*/
static WlzErrorNum 		WlzRCCMakeT(
				  WlzObject **o,
				  WlzObject **t,
				  WlzRCCTOIdx i)
{
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if((i >= 0) && (i < WLZ_RCCTOIDX_CNT))
  {
    if(t[i] == NULL)
    {
      switch(i)
      {
	case WLZ_RCCTOIDX_O0O1U:			/* o_0 \cup \o_1 */
	  t[i] = WlzAssignObject(
		 WlzUnion2(o[0], o[1], &errNum), NULL);
	  break;
	case WLZ_RCCTOIDX_O0O1I:			/* o_0 \cap \o_1 */
	  t[i] = WlzAssignObject(
		 WlzIntersect2(o[0], o[1], &errNum), NULL);
	  break;
	case WLZ_RCCTOIDX_O0D:			/* o_0^+ */
	  t[i] = WlzAssignObject(
		 WlzDilation(o[0],
			     (o[0]->type == WLZ_2D_DOMAINOBJ)?
			     WLZ_8_CONNECTED: WLZ_26_CONNECTED,
			     &errNum), NULL);
	  break;
	case WLZ_RCCTOIDX_O1D:			/* o_1^+ */
	  t[i] = WlzAssignObject(
		 WlzDilation(o[1],
			     (o[1]->type == WLZ_2D_DOMAINOBJ)?
			     WLZ_8_CONNECTED: WLZ_26_CONNECTED,
			     &errNum), NULL);
	  break;

	case WLZ_RCCTOIDX_O0F:			/* o_0^{\bullet} */
	  t[i] = WlzAssignObject(
		 WlzDomainFill(o[0], &errNum), NULL);
	  break;
	case WLZ_RCCTOIDX_O1F:			/* o_1^{\bullet} */
	  t[i] = WlzAssignObject(
		 WlzDomainFill(o[1], &errNum), NULL);
	  break;

	case WLZ_RCCTOIDX_O0DO1U:		/* o_0^+ \cup o_1 */
	  errNum = WlzRCCMakeT(o, t, WLZ_RCCTOIDX_O0D);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    t[i] = WlzAssignObject(
		   WlzUnion2(t[WLZ_RCCTOIDX_O0D], o[1], &errNum), NULL);
	  }
	  break;
	case WLZ_RCCTOIDX_O0O1DU:		/* o_0   \cup o_1^+ */
	  errNum = WlzRCCMakeT(o, t, WLZ_RCCTOIDX_O1D);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    t[i] = WlzAssignObject(
		   WlzUnion2(o[0], t[WLZ_RCCTOIDX_O1D], &errNum), NULL);
	  }
	  break;
	case WLZ_RCCTOIDX_O0CO1I:               /* o_0^{\circ} \cap o_1   */
	case WLZ_RCCTOIDX_O0O1CI:  /* FALLTHROUGH  o_0   \cap o_1^{\circ} */
	  {
	    int		i0;
	    WlzObject	*c = NULL,
			  *x = NULL;

	    i0 = (i == WLZ_RCCTOIDX_O0CO1I)? 0: 1;
	    c = WlzObjToConvexHull(o[i0], &errNum);
	    if((errNum == WLZ_ERR_NONE) || (errNum == WLZ_ERR_DEGENERATE))
	    {
	      x = WlzAssignObject(
		  WlzConvexHullToObj(c, o[i0]->type, &errNum), NULL);
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      t[i] = WlzAssignObject(
		     WlzIntersect2(o[!i0], x, &errNum), NULL);
	    }
	    (void )WlzFreeObj(c);
	    (void )WlzFreeObj(x);
	  }
	  break;
	case WLZ_RCCTOIDX_O0FO1U:		/* o_0^{\bullet} \cup o_1 */
	  errNum = WlzRCCMakeT(o, t, WLZ_RCCTOIDX_O0F);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    t[i] = WlzAssignObject(
		   WlzUnion2(t[WLZ_RCCTOIDX_O0F], o[1], &errNum), NULL);
	  }
	  break;
	case WLZ_RCCTOIDX_O0O1FU:		/* o_0 \cup o_1^{\bullet} */
	  errNum = WlzRCCMakeT(o, t, WLZ_RCCTOIDX_O1F);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    t[i] = WlzAssignObject(
		   WlzUnion2(o[0], t[WLZ_RCCTOIDX_O1F], &errNum), NULL);
	  }
	  break;
	default:
	  errNum = WLZ_ERR_PARAM_DATA;
	  break;
      }
    }
  }
  else
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  return(errNum);
}
示例#4
0
/*!
* \return	New Woolz object without holes or NULL on error.
* \ingroup	WlzDomainOps
* \brief	Fills the holes in the given object's domain (which are by
* 		definition not connected to the outside). When the given
* 		object's domain has more than one component part, the
* 		object should first be labeled, this function should then be
* 		called for each of the labeled parts and then the union of
* 		the filled domains should be formed.
* \param	srcObj			Given 3D domain object.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject 			*WlzDomainFill3D(
  				  WlzObject *srcObj,
    				  WlzErrorNum *dstErr)
{
  int		nPln = 0;
  WlzObject	*bndObj = NULL,
  		*filObj = NULL,
  		*gvnObj = NULL,
		*sedObj = NULL,
		*shlObj = NULL;
  WlzPixelV	zeroV;
  WlzValues 	nullVal;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  nullVal.core = NULL;
  zeroV.type = WLZ_GREY_UBYTE;
  zeroV.v.ubv = 0;
  if(srcObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(srcObj->type != WLZ_3D_DOMAINOBJ)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else
  {
    gvnObj = WlzMakeMain(srcObj->type, srcObj->domain, nullVal,
    		         NULL, NULL, &errNum);
  }
  /* Create a then shell 1 voxel thick just inside the given objects's
   * domain. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzObject	*difObj = NULL;

    difObj = WlzAssignObject(
	     WlzBoundaryDomain(gvnObj, &errNum), NULL);
    if(errNum == WLZ_ERR_NONE)
    {
      WlzIBox3	clipBox;

      /* Clip the dilated shell domain to make sure it stays within the
       * bounding box of the given object then all planes will align. */
      clipBox.xMin = gvnObj->domain.p->kol1;
      clipBox.yMin = gvnObj->domain.p->line1;
      clipBox.zMin = gvnObj->domain.p->plane1;
      clipBox.xMax = gvnObj->domain.p->lastkl;
      clipBox.yMax = gvnObj->domain.p->lastln;
      clipBox.zMax = gvnObj->domain.p->lastpl;
      shlObj = WlzAssignObject(
	       WlzClipObjToBox3D(difObj, clipBox, &errNum), NULL);
    }
    (void )WlzFreeObj(difObj);
  }
  /* Make sure that the bounding box of the thin shell domain fits it and
   * that it's first and last planes have interrvals. */
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzStandardPlaneDomain(shlObj->domain.p, NULL);
  }
  /* Create a value table for the shell object with values set to zero. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzValues	val;
    WlzObjectType tType;

    tType = WlzGreyTableType(WLZ_GREY_TAB_INTL, WLZ_GREY_UBYTE, NULL);
    val.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
				  shlObj->domain.p->plane1,
				  shlObj->domain.p->lastpl,
				  zeroV, NULL, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      int	p;

      nPln = shlObj->domain.p->lastpl - shlObj->domain.p->plane1 + 1;
      shlObj->values = WlzAssignValues(val, NULL);
#ifdef _OPENMP
#pragma omp parallel for shared(shlObj)
#endif
      for(p = 0; p < nPln; ++p)
      {
	if(errNum == WLZ_ERR_NONE)
	{
	  WlzDomain dom2;
	  WlzErrorNum errNum2;

	  dom2 = shlObj->domain.p->domains[p];
	  if(dom2.core)
	  {
	    WlzValues val2;
	    WlzObject *shlObj2;
	    shlObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, dom2, nullVal, NULL, NULL,
				&errNum2);
	    if(errNum2 == WLZ_ERR_NONE)
	    {
	      val2.i = WlzMakeIntervalValues(tType, shlObj2, zeroV, &errNum2);
	      /* WlzMakeIntervalValues() sets all values to zero. */
	    }
	    if(errNum2 == WLZ_ERR_NONE)                          
	    {
	      shlObj->values.vox->values[p] = WlzAssignValues(val2, NULL);
	    }
	    (void )WlzFreeObj(shlObj2);
	    if(errNum2 == WLZ_ERR_NONE)
	    {
#ifdef _OPENMP
#pragma omp critical
	      {
#endif
		if((errNum == WLZ_ERR_NONE) && (errNum2 != WLZ_ERR_NONE))
		{
		  errNum = errNum2;
		}
#ifdef _OPENMP
	      }
#endif
	    }
	  }
	}
      }
    }
  }
  /* Compute the (plane-wise) boundary list for the given object. */
  if(errNum == WLZ_ERR_NONE)
  {
    bndObj = WlzObjToBoundary(gvnObj, 0, &errNum);
  }
  /* Sweep down through the boundary object setting the values of
   * those voxels in the shell object to a non zero value when they
   * correspond to top level boundaries. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		p;

#ifdef _OPENMP
#pragma omp parallel for shared(bndObj,shlObj)
#endif
    for(p = 0; p < nPln; ++p)
    {
      if(errNum == WLZ_ERR_NONE)
      {
	WlzDomain bDom2;

	bDom2 = bndObj->domain.p->domains[p];
	if(bDom2.core)
	{
	  WlzDomain iDom2;
	  WlzValues iVal2;
	  WlzObject *iObj2 = NULL;
	  WlzGreyValueWSpace *gVWSp = NULL;
	  WlzErrorNum errNum2 = WLZ_ERR_NONE;

	  iDom2 = shlObj->domain.p->domains[p];
	  iVal2 = shlObj->values.vox->values[p];
	  iObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, iDom2, iVal2, NULL, NULL,
			      &errNum2);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    gVWSp = WlzGreyValueMakeWSp(iObj2, &errNum2);
	  }
	  if(errNum2 == WLZ_ERR_NONE)
	  {
	    WlzBoundList *bnd,
			 *bnd2;

	    bnd2 = bDom2.b;
	    for(bnd = bnd2; bnd != NULL; bnd = bnd->next)
	    {
	      if(bnd->poly != NULL)
	      {
		WlzPolygonDomain *ply;

		ply = bnd->poly;
		if(ply)
		{
		  int	i;
		  WlzIVertex2 *vtx;

		  vtx = ply->vtx;
		  for(i = 0; i < ply->nvertices; ++i)
		  {
		    WlzGreyValueGet(gVWSp, 0, vtx[i].vtY, vtx[i].vtX);
		    *(gVWSp->gPtr[0].ubp) = 255;
		  }
		}
	      }
	    }
	  }
	  else
	  {
#ifdef _OPENMP
#pragma omp critical
	    {
#endif
	      if(errNum == WLZ_ERR_NONE)
	      {
		errNum = errNum2;
	      }
#ifdef _OPENMP
	    }
#endif
	  }
	  (void )WlzFreeObj(iObj2);
	  WlzGreyValueFreeWSp(gVWSp);
	}
      }
    }
  }
  /* Threshold the shell object, throwing away all but where the voxels
   * are set to create a seed domain. Then remove the value table from
   * the shell object and free it as it's no longer needed. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzObject	*tObj = NULL;
    WlzPixelV	tV;

    tV.type = WLZ_GREY_UBYTE;
    tV.v.ubv = 1;
    tObj = WlzAssignObject(
    	   WlzThreshold(shlObj, tV, WLZ_THRESH_HIGH, &errNum), NULL);
    if(errNum == WLZ_ERR_NONE)
    {
      sedObj = WlzAssignObject(
      	       WlzMakeMain(tObj->type, tObj->domain, nullVal,
			   NULL, NULL, &errNum), NULL);
    }
    (void )WlzFreeObj(tObj); tObj = NULL;
    if(errNum == WLZ_ERR_NONE)
    {
      tObj = WlzAssignObject(
             WlzMakeMain(shlObj->type, shlObj->domain, nullVal,
			 NULL, NULL, &errNum), NULL);
    }
    (void )WlzFreeObj(shlObj); shlObj = NULL;
    if(errNum == WLZ_ERR_NONE)
    {
      shlObj = tObj;
      tObj = NULL;
    }
    (void )WlzFreeObj(tObj);
#ifdef WLZ_DOMOMAINFILL3D_DEBUG
    {
      FILE	*fP;
      fP = fopen("debug-shlObj-00.wlz", "w");
      (void )WlzWriteObj(fP, shlObj);
      (void )fclose(fP);
    }
#endif
  }
  /* Label the shell domain using 26-connectivity in 3D and then
   * keep only those component objects which intersect the seed domain.
   * Then free the shell and seed domains replacing the shell domain
   * with the union of the intersecting labeled component objects.
   * Finaly free the intersecting component objects, keeping only the
   * new shell domain. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		i,
		j,
    		nCSObj = 0;
    WlzIBox3	bBox;
    WlzObject	**csObj = NULL;

    bBox = WlzBoundingBox3I(shlObj, &errNum);
    if(errNum == WLZ_ERR_NONE)      
    {
      int	maxCSObj;

      maxCSObj = ((bBox.xMax - bBox.xMin + 1) *
      		  (bBox.yMax - bBox.yMin + 1) *
      		  (bBox.zMax - bBox.zMin + 1)) / 8;
      if(maxCSObj < 8)
      {
        maxCSObj = 8;
      }
      errNum = WlzLabel(shlObj, &nCSObj, &csObj, maxCSObj, 0,
			WLZ_26_CONNECTED);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      for(i = 0; i < nCSObj; ++i)
      {
        if(!WlzHasIntersection(csObj[i], sedObj, &errNum))
	{
	  (void )WlzFreeObj(csObj[i]);
	  csObj[i] = NULL;
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      /* Squeeze out any NULL objects reseting their number.*/
      for(i = 0, j = 0; i < nCSObj; ++i)
      {
        if(csObj[i])
	{
	  csObj[j++] = csObj[i];
	}
      }
      nCSObj = j;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*iObj = NULL,
      		*uObj = NULL;

      uObj = WlzAssignObject(
      	     WlzUnionN(nCSObj, csObj, 0, &errNum), NULL);
      iObj = WlzAssignObject(
               WlzIntersect2(uObj, shlObj, &errNum),  NULL);
      (void )WlzFreeObj(uObj);
      (void )WlzFreeObj(shlObj);
      shlObj = iObj;
#ifdef WLZ_DOMOMAINFILL3D_DEBUG
      {
	FILE	*fP;
	fP = fopen("debug-shlObj-01.wlz", "w");
	(void )WlzWriteObj(fP, shlObj);
	(void )fclose(fP);
      }
#endif
    }
    if(csObj)
    {
      for(i = 0; i < nCSObj; ++i)
      {
        (void )WlzFreeObj(csObj[i]);
      }
      (void )AlcFree(csObj);
    }
  }
  /* Sweep down through the boundary lists again creating new boundary lists
   * which do not have boundaries that do not intersect the new shell domain.
   * Then create a new filled object from these boundary lists. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		p,
    		nPlnFil;
    WlzDomain	filDom;

    nPlnFil = shlObj->domain.p->lastpl - shlObj->domain.p->plane1 + 1;
    filDom.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 
		shlObj->domain.p->plane1, shlObj->domain.p->lastpl,
                shlObj->domain.p->line1, shlObj->domain.p->lastln,
                shlObj->domain.p->kol1, shlObj->domain.p->lastkl,
		&errNum);
#ifdef _OPENMP
#pragma omp parallel for shared(bndObj,shlObj)
#endif
    for(p = 0; p < nPlnFil; ++p)
    {
      if(errNum == WLZ_ERR_NONE)
      {
	WlzDomain bDom2;
	
	bDom2 = bndObj->domain.p->domains[p];
	if(bDom2.core)
	{
	  WlzDomain 	sDom2;
	  WlzObject	*fObj2 = NULL;
	  WlzBoundList  *newBnd = NULL;
	  WlzErrorNum	errNum2 = WLZ_ERR_NONE;

	  sDom2 = shlObj->domain.p->domains[p];
	  if(sDom2.core)
	  {
	    newBnd = WlzDomFill3DDoBound2D(bDom2.b, sDom2, &errNum2);
	    if(newBnd != NULL)
	    {
	      fObj2 = WlzBoundToObj(newBnd, WLZ_SIMPLE_FILL, &errNum2);
	      (void )WlzFreeBoundList(newBnd);
	    }
	    if(errNum2 == WLZ_ERR_NONE)
	    {
	      if(fObj2)
	      {
		filDom.p->domains[p] = WlzAssignDomain(fObj2->domain, NULL);
	      }
	    }
	    else
	    {
#ifdef _OPENMP
#pragma omp critical
	      {
#endif
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = errNum2;
		}
#ifdef _OPENMP
	      }
#endif
	    }
	    (void )WlzFreeObj(fObj2);
	  }
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzStandardPlaneDomain(filDom.p, NULL);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*tObj0 = NULL,
      		*tObj1 = NULL;

      /* Put back any isolated voxels this function has removed. */
      tObj0 = WlzAssignObject(
              WlzMakeMain(srcObj->type, filDom, nullVal,
      			  NULL, NULL, &errNum), NULL);
      if(errNum == WLZ_ERR_NONE)
      {
        tObj1 = WlzUnion2(gvnObj, tObj0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	filObj = WlzMakeMain(tObj1->type, tObj1->domain, nullVal,
			     NULL, NULL, &errNum);
      }
      (void )WlzFreeObj(tObj0);
      (void )WlzFreeObj(tObj1);
    }
  }
  (void )WlzFreeObj(bndObj);
  (void )WlzFreeObj(gvnObj);
  (void )WlzFreeObj(shlObj);
  (void )WlzFreeObj(sedObj);
  if((errNum != WLZ_ERR_NONE) && (filObj != NULL))
  {
    (void )WlzFreeObj(filObj);
    filObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(filObj);
}
示例#5
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;
}
示例#6
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;
}
示例#7
0
int main(
  int   argc,
  char  **argv)
{
  FILE		*inFile;
  char 		optList[] = "d:m:t:hv";
  int		option;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  int		verboseFlg=0;
  int		type=1;
  WlzObject	*obj = NULL, *obj1, *obj2, *obj3;
  double	matchVal=0.0;
  double	s1, s2, s3, s4;
  double	delta=0.01;
  double	**mixing=NULL, **contrib=NULL;
  int		k, l;
  int		numCatRows=-1, numCatCols=-1;

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

    case 'd':
      delta = atof(optarg);
      if((delta >= 1.0) || (delta <= 1.0e-10)){
	delta = 0.01;
	fprintf(stderr, "%s: invalid delta, reset to 0.01", argv[0]);
      }
      break;

    case 'm':
      if((inFile = fopen(optarg, "r")) != NULL){
	if( fscanf(inFile, "%d, %d", &numCatCols, &numCatRows) < 2 ){
	  fprintf(stderr, "%s: can't read mixing matrix dimensions\n", argv[0]);
	  usage(argv[0]);
	  return 1;
	}
	AlcDouble2Malloc(&mixing, numCatRows, numCatCols);
	AlcDouble2Malloc(&contrib, numCatRows, numCatCols);
	for(l=0; l < numCatRows; l++){
	  for(k=0; k < numCatCols; k++){
	    if( fscanf(inFile, "%lg,", &(mixing[l][k])) < 1 ){
	      fprintf(stderr, "%s: can't read mixing matrix\n", argv[0]);
	      usage(argv[0]);
	      return 1;
	    }
	  }
	}
	for(l=0; l < numCatRows; l++){
	  for(k=0; k < numCatCols; k++){
	    if( fscanf(inFile, "%lg,", &(contrib[l][k])) < 1 ){
	      fprintf(stderr, "%s: can't read contributing matrix\n", argv[0]);
	      usage(argv[0]);
	      return 1;
	    }
	  }
	}
      }
      else {
	fprintf(stderr, "%s: can't open matrix file\n", argv[0]);
	usage(argv[0]);
	return 1;
      }
      break; 

    case 't':
      type = atoi(optarg);
      break;

    case 'v':
      verboseFlg = 1;
      break;

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

    }
  }

  /* verbose output */
  if( verboseFlg ){
    fprintf(stderr, "%s: parameter values:\n", argv[0]);
    fprintf(stderr, "\ttype = %d, delta = %f\n", type, delta);
    if( type == 6 ){
      fprintf(stderr, "\t mixing matrix:\n");
      for(l=0; l < numCatRows; l++){
	for(k=0; k < numCatCols; k++){
	  fprintf(stderr, "%f, ", mixing[l][k]);
	}
	fprintf(stderr, "\n");
      }
      fprintf(stderr, "\n");
      fprintf(stderr, "\t contributing matrix:\n");
      for(l=0; l < numCatRows; l++){
	for(k=0; k < numCatCols; k++){
	  fprintf(stderr, "%f, ", contrib[l][k]);
	}
	fprintf(stderr, "\n");
      }
    }
  }

  /* get objects from stdin */
  inFile = stdin;
  if((obj1 = WlzReadObj(inFile, &errNum)) != NULL){
    switch( obj1->type ){
    case WLZ_2D_DOMAINOBJ:
    case WLZ_3D_DOMAINOBJ:
    case WLZ_EMPTY_OBJ:
      break;

    default:
      fprintf(stderr, "%s: invalid object type: %d\n", argv[0],
	      obj->type);
      usage(argv[0]);
      return 1;
    }
  }
  else {
    fprintf(stderr, "%s: can't read first object\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  if((obj2 = WlzReadObj(inFile, &errNum)) != NULL){
    if( (obj2->type != obj1->type) && (obj2->type != WLZ_EMPTY_OBJ) ){
      fprintf(stderr, "%s: objects must be same type\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
  }
  else {
    fprintf(stderr, "%s: can't read second object\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  /* this can fail silently but if there is an object it must
     be valid */
  if((obj3 = WlzReadObj(inFile, &errNum)) != NULL){
    if( (obj3->type != obj1->type) && (obj3->type != WLZ_EMPTY_OBJ) ){
      fprintf(stderr, "%s: objects must be same type\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
  }

  /* now calculate a match value */
  switch( type ){
  case 1:
    if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
      s1 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s1 = 0;
    }
    if((obj = WlzUnion2(obj1, obj2, &errNum)) != NULL){
      s2 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s2 = 1;
    }
    matchVal = s1 / s2;
    break;

  case 2:
    if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
      s1 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s1 = 0;
    }
    if((obj = WlzUnion2(obj1, obj2, &errNum)) != NULL){
      s2 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s2 = 1;
    }
    matchVal = s1 / s2;
    if( type == 2 ){
      s1 = WlzSize(obj1, &errNum);
      s2 = WlzSize(obj2, &errNum);
      if( s2 > s1 ){
	if( matchVal == 0.0 ){
	  matchVal = 10.0;
	}
	else {
	  matchVal = 1.0 / matchVal;
	  matchVal = WLZ_MIN(matchVal, 10.0);
	}
      }
    }
    break;

  case 3:
    if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
      s1 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s1 = 0;
    }
    s2 = WlzSize(obj1, &errNum);
    matchVal = 0.0;
    if( s2 > 0 ){
      matchVal = s1 / s2;
    }
    break;

  case 4:
    if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
      s1 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s1 = 0;
    }
    s2 = WlzSize(obj2, &errNum);
    matchVal = 0.0;
    if( s2 > 0 ){
      matchVal = s1 / s2;
    }
    break;

  case 5:
    /* this is a coparative measure designed to give a value of 1
       to a random pattern and between zero and infinite for
       matches to one or the other. For analysis for clustering
       probably better to use the logarithm. Zero and infinite are
       delta and 1/delta. */
    /* must be a third object */
    if( obj3 == NULL ){
      fprintf(stderr, "%s: for match option 5 3 input object required\n",
	      argv[0]);
      return 1;
    }
    s1 = WlzSize(obj2, &errNum);
    if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
      s2 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s2 = 0.0;
    }
    s3 = WlzSize(obj3, &errNum);
    if((obj = WlzIntersect2(obj1, obj3, &errNum)) != NULL){
      s4 = WlzSize(obj, &errNum);
      WlzFreeObj(obj);
    }
    else {
      s4 = 0.0;
    }
    if((s1 < 0.0) || (s2 < 0.0) || (s3 < 0.0) || (s4 < 0.0)){
      /* just fail */
      fprintf(stderr, "%s: something gone wrong, negative size.\n",
	      argv[0]);
      return 1;
    }
    /* calculating (s2/s1) * (s3/s4) */
    /* if the denominator non-zero then simple formula */
    if( s2 > 0.0 ){
      if( s4 > 0.0 ){
	matchVal = (s2/s1) * (s3/s4);
      }
      else {
	matchVal = s2 / s1;
      }
    }
    else {
      if( s4 > 0.0 ){
	matchVal = s3/s4;
      }
      else {
	matchVal = 1.0;
      }
    }
    matchVal = WLZ_MAX(matchVal, delta);
    matchVal = WLZ_MIN(matchVal, 1.0/delta);
    break;

  case 6:
    /* this requires a mixing and contributing matrix and the images
       read in must have grey-values set to the right categories */
    if((numCatRows == -1) || (numCatCols == -1) ||
       (mixing == NULL) || (contrib == NULL)){
      fprintf(stderr, "%s: bad matrix data\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
    matchVal = WlzMixtureValue(obj1, obj2, numCatRows, numCatCols,
			       mixing, contrib, &errNum);
    break;

  default:
    fprintf(stderr, "%s: invalid match type\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  /* print value */
  fprintf(stdout, "%f\n", matchVal);
  return 0;
}
示例#8
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);
}
示例#9
0
文件: WlzPoints.c 项目: dscho/Woolz
/*!
* \return	New domain object which coresponds to the union of
* 		the given points.
* \ingroup	WlzFeatures
* \brief	Creates a domain object which coresponds to the union of
* 		the given points.
* \param	pnt			Point domain.
* \param	scale			Scale, which if greater than zero
* 					is used as the diameter of a circle
* 					or sphere centred on each of the
* 					points vertices and a multiplier
* 					for the point position.
* \param	dstErr			Destination error poiter, may be NULL.
*/
WlzObject	*WlzPointsToDomObj(WlzPoints *pnt, double scale,
    				   WlzErrorNum *dstErr)
{
  int		idP;
  WlzObjectType	dType;
  WlzObject	*tObj0,
		*tObj1,
		*tObj2,
		*dObj = NULL;
  WlzVertex	pos;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  idP = 0;
  if(scale > DBL_EPSILON)
  {
    pos.d3.vtZ = 0.0;
  }
  else
  {
    pos.i3.vtZ = 0;
  }
  if(pnt == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else
  {
    switch(pnt->type)
    {
      case WLZ_POINTS_2I: /* FALLTHROUGH */
      case WLZ_POINTS_2D:
	dType = WLZ_2D_DOMAINOBJ;
	break;
      case WLZ_POINTS_3I: /* FALLTHROUGH */
      case WLZ_POINTS_3D:
	dType = WLZ_3D_DOMAINOBJ;
	break;
      default:
	errNum = WLZ_ERR_DOMAIN_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    tObj0 = WlzMakeEmpty(&errNum);
  }
  while((errNum == WLZ_ERR_NONE) && (idP < pnt->nPoints))
  {
    if(scale > DBL_EPSILON)
    {
      switch(pnt->type)
      {
	case WLZ_POINTS_2I:
	  pos.d3.vtX = pnt->points.i2[idP].vtX;
	  pos.d3.vtY = pnt->points.i2[idP].vtY;
	  break;
	case WLZ_POINTS_2D:
	  pos.d3.vtX = pnt->points.d2[idP].vtX;
	  pos.d3.vtY = pnt->points.d2[idP].vtY;
	  pos.d3.vtZ = 0.0;
	  break;
	case WLZ_POINTS_3I:
	  pos.d3.vtX = pnt->points.i3[idP].vtX;
	  pos.d3.vtY = pnt->points.i3[idP].vtY;
	  pos.d3.vtZ = pnt->points.i3[idP].vtZ;
	  break;
	case WLZ_POINTS_3D:
	  pos.d3 = pnt->points.d3[idP];
	  break;
        default:
	  errNum = WLZ_ERR_PARAM_TYPE;
	  break;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	tObj1 = WlzMakeSphereObject(dType, scale / 2.0,
				    scale * pos.d3.vtX,
				    scale * pos.d3.vtY,
				    scale * pos.d3.vtZ,
				    &errNum);
      }
    }
    else
    {
      switch(pnt->type)
      {
	case WLZ_POINTS_2I:
	  pos.i3.vtX = pnt->points.i2[idP].vtX;
	  pos.i3.vtY = pnt->points.i2[idP].vtY;
	  break;
	case WLZ_POINTS_2D:
	  pos.i3.vtX = WLZ_NINT(pnt->points.d2[idP].vtX);
	  pos.i3.vtY = WLZ_NINT(pnt->points.d2[idP].vtY);
	  break;
	case WLZ_POINTS_3I:
	  pos.i3 = pnt->points.i3[idP];
	  break;
	case WLZ_POINTS_3D:
	  pos.i3.vtX = WLZ_NINT(pnt->points.d3[idP].vtX);
	  pos.i3.vtY = WLZ_NINT(pnt->points.d3[idP].vtY);
	  pos.i3.vtZ = WLZ_NINT(pnt->points.d3[idP].vtZ);
	  break;
        default:
	  errNum = WLZ_ERR_PARAM_TYPE;
	  break;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	tObj1 = WlzMakeSinglePixelObject(dType,
					 pos.i3.vtX, pos.i3.vtY, pos.i3.vtZ,
				         &errNum);
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      tObj2 = WlzUnion2(tObj0, tObj1, &errNum);
    }
    (void )WlzFreeObj(tObj0);
    (void )WlzFreeObj(tObj1);
    tObj0 = tObj2;
    ++idP;
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dObj = tObj0;
  }
  else
  {
    (void )WlzFreeObj(tObj0);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dObj);
}
示例#10
0
/*!
* \return	Thresholded object or NULL on error.
* \ingroup      WlzThreshold
* \brief	Hysteresis thresholds the given Woolz object.
*               Values are in the domain of the hysteresis threshold'd
*               object if they are above/below the primary threshold
*               or above/below the secondary threshold and connected
*               to values above/below the primary threshold.
* \param	srcObj			Object to be thresholded.
* \param	pThrV			Primary hysteresis threshold
*                                       value.
* \param	sThrV			Threshold for above or below
*                                       values.
* \param	hilo			Threshold for above or below
*                                       values.
* \param	con			Connectivity to examine for
*                                       hysteresis.
* \param	dstErr			Destination error pointer, may
*                                       be null.
*/
WlzObject	*WlzHyThreshold(WlzObject *srcObj,
			       WlzPixelV pThrV, WlzPixelV sThrV,
			       WlzThresholdType hilo, WlzConnectType con,
			       WlzErrorNum *dstErr)
{
  int		simpleThr = 0;
  WlzPixelV	tmpV;
  WlzObject	*dstObj = NULL,
  		*pThrObj = NULL,
  		*sThrObj = NULL,
		*dThrObj = NULL,
		*iThrObj = NULL,
		*uThrObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if(srcObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(srcObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    if(con == WLZ_0_CONNECTED)
    {
      simpleThr = 1;
    }
    else
    {
      if((errNum = WlzValueConvertPixel(&tmpV, sThrV,
      					pThrV.type)) == WLZ_ERR_NONE)
      {
        switch(pThrV.type)
	{
	  case WLZ_GREY_INT:
	    if(tmpV.v.inv == pThrV.v.inv)
	    {
	      simpleThr = 1;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    if(tmpV.v.shv == pThrV.v.shv)
	    {
	      simpleThr = 1;
	    }
	    break;
	  case WLZ_GREY_UBYTE:
	    if(tmpV.v.ubv == pThrV.v.ubv)
	    {
	      simpleThr = 1;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    if(fabs(tmpV.v.flv - pThrV.v.flv) <= FLT_EPSILON)
	    {
	      simpleThr = 1;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    if(fabs(tmpV.v.dbv - pThrV.v.dbv) <= DBL_EPSILON)
	    {
	      simpleThr = 1;
	    }
	    break;
	  case WLZ_GREY_RGBA:
	    if( tmpV.v.rgbv == pThrV.v.rgbv )
	    {
	      simpleThr = 1;
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_GREY_TYPE;
	    break;
	}
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(simpleThr)
    {
      dstObj = WlzThreshold(srcObj, pThrV, hilo, &errNum);
    }
    else
    {
      pThrObj = WlzThreshold(srcObj, pThrV, hilo, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	if(pThrObj->type == WLZ_EMPTY_OBJ)
	{
	  dstObj = pThrObj;
	  pThrObj = NULL;
	}
	else
	{
	  sThrObj = WlzThreshold(srcObj, sThrV, hilo, &errNum);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    if(sThrObj->type == WLZ_EMPTY_OBJ)
	    {
	      dstObj = pThrObj;
	      pThrObj = NULL;
	    }
	    else
	    {
	      dThrObj = WlzDilation(pThrObj, con, &errNum);
	      if(errNum == WLZ_ERR_NONE)
	      {
		iThrObj = WlzIntersect2(dThrObj, sThrObj, &errNum);
	      }
	      if(errNum == WLZ_ERR_NONE)
	      {
		uThrObj = WlzUnion2(pThrObj, iThrObj, &errNum);
	      }
	      if(errNum == WLZ_ERR_NONE)
	      {
		dstObj = WlzMakeMain(uThrObj->type,
				     uThrObj->domain, srcObj->values,
				     srcObj->plist, srcObj, &errNum);
	      }
	      if(dThrObj)
	      {
		WlzFreeObj(dThrObj);
	      }
	      if(iThrObj)
	      {
		WlzFreeObj(iThrObj);
	      }
	      if(uThrObj)
	      {
		WlzFreeObj(uThrObj);
	      }
	    }
	    if(sThrObj)
	    {
	      WlzFreeObj(sThrObj);
	    }
	    if(pThrObj)
	    {
	      WlzFreeObj(pThrObj);
	    }
	  }
	}
      }
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dstObj);
}
示例#11
0
void getViewDomains(
  ThreeDViewStruct	*view_struct)
{
  int		i, j, numOverlays;
  WlzObject	*allDomainsObj=NULL, *tmpObj;
  WlzPixelV	thresh;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* check initialisation */
  if( !view_struct->wlzViewStr->initialised ){
    if( init_view_struct( view_struct ) ){
      errNum = WLZ_ERR_UNSPECIFIED;
    }
  }

  /* check for painted object */

  /* clear any current domains */
  numOverlays = globals.cmapstruct->num_overlays +
    globals.cmapstruct->num_solid_overlays;
  for(i=0; i <= numOverlays; i++){
    if( view_struct->curr_domain[i] ){
      errNum = WlzFreeObj(view_struct->curr_domain[i]);
      view_struct->curr_domain[i] = NULL;
    }
    if( errNum != WLZ_ERR_NONE ){
      break;
    }
  }

  /* get the union of all domains */
  if( errNum == WLZ_ERR_NONE ){
    thresh.type = WLZ_GREY_INT;
    thresh.v.inv = globals.cmapstruct->ovly_cols[DOMAIN_1];
    tmpObj = WlzThreshold(view_struct->painted_object,
			  thresh, WLZ_THRESH_HIGH, &errNum);
    if( (errNum == WLZ_ERR_NONE) && tmpObj ){
      if( WlzArea(tmpObj, &errNum) > 0 ){
	allDomainsObj = WlzAssignObject(tmpObj, &errNum);
      }
      else {
	errNum = WlzFreeObj(tmpObj);
      }
    }
  }

  /* segment the painted section image to establish each domain object */
  if( (errNum == WLZ_ERR_NONE) && allDomainsObj ){
    WlzPixelV	min, max;
    int		max_i=numOverlays;

    /* get maximum number of domains */
    WlzGreyRange(allDomainsObj, &min, &max);
    WlzValueConvertPixel(&max, max, WLZ_GREY_INT);

    while( (max_i > 0) && (globals.cmapstruct->ovly_cols[max_i] > max.v.inv) ){
      max_i--;
    }

    for(i=1; i <= max_i; i++){
      tmpObj = get_domain_from_object(view_struct->painted_object, i);
      if( tmpObj ){
	view_struct->curr_domain[i] = WlzAssignObject(tmpObj, NULL);
      }
    }
  }

  /* propogate from previous section 
     asking for confirmation if a domain will be changed by
     propogation.
     This will either be if the current domain exists or if the 
     propogating domain overlaps the union of all existing domains */
  if( (errNum == WLZ_ERR_NONE) && (globals.propogate||globals.propogate_sel) ){
    for(i=1; (i <= numOverlays) && (errNum == WLZ_ERR_NONE); i++){
      /* test for propogate currently selected domain only */
      if((!globals.propogate) && (i != globals.current_domain)){
	continue;
      }
      if((view_struct->prev_domain[i]) &&
	 (view_struct->prev_domain[i]->type != WLZ_EMPTY_OBJ)){
	if( allDomainsObj ){
	  /* first check if there is a curr_domain */
	  int needConfirm = 0;
	  if((view_struct->curr_domain[i]) && 
	     (view_struct->curr_domain[i]->type != WLZ_EMPTY_OBJ)){
	    needConfirm = 1;
	  }
	  else {
	    tmpObj = WlzIntersect2(view_struct->prev_domain[i],
				   allDomainsObj, &errNum);
	    if( tmpObj && (WlzArea(tmpObj, &errNum) > 0) ){
	      needConfirm = 1;
	      WlzFreeObj(tmpObj);
	    }
	  }
	  if( (errNum == WLZ_ERR_NONE) && needConfirm ){
	    if( HGU_XmUserConfirm(view_struct->dialog,
				  "Warning: propogation may modify\n"
				  "    one or more existing domains.\n"
				  "    Propogate anyway?",
				  "Yes", "No", 0) ){
	      if( view_struct->curr_domain[i] ){
		tmpObj = WlzUnion2(view_struct->curr_domain[i],
				   view_struct->prev_domain[i], &errNum);
		WlzFreeObj(view_struct->curr_domain[i]);
		view_struct->curr_domain[i] = 
		  WlzAssignObject(tmpObj, NULL);
	      }
	      else {
		view_struct->curr_domain[i] =
		  WlzAssignObject(view_struct->prev_domain[i], NULL);
	      }
	      globals.domain_changed_since_saved[i] = 1;
	    }
	  }
	  else {
	    view_struct->curr_domain[i] =
	      WlzAssignObject(view_struct->prev_domain[i], NULL);
	    globals.domain_changed_since_saved[i] = 1;
	  }
	}
	else {
	  view_struct->curr_domain[i] =
	    WlzAssignObject(view_struct->prev_domain[i], &errNum);
	  globals.domain_changed_since_saved[i] = 1;
	}
      }
    }
  }

  /* put all objects onto painted image in reverse dominance order */
  for(j=numOverlays; (j > 0) && (errNum == WLZ_ERR_NONE); j--){
    i = globals.priority_to_domain_lut[j];
    if( view_struct->curr_domain[i] ){
      if( i > globals.cmapstruct->num_overlays )
      {
	if( set_grey_values_from_domain(view_struct->curr_domain[i],
					view_struct->painted_object,
					globals.cmapstruct->ovly_cols[i],
					255) ){
	  break;
	}
      }
      else
      {
	if( set_grey_values_from_domain(view_struct->curr_domain[i],
					view_struct->painted_object,
					globals.cmapstruct->ovly_cols[i],
					globals.cmapstruct->ovly_planes) ){
	  break;
	}
      }
    }
  }      

  /* redisplay the view */
  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "getViewDomains", errNum);
  }
  else{
    redisplay_view_cb(view_struct->canvas, view_struct, NULL);
  }

  return;
}
示例#12
0
int main(
  int   argc,
  char  **argv)
{
  FILE		*inFile;
  char 		optList[] = "d:m:t:hv";
  int		option;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  int		verboseFlg=0;
  int		type=1;
  int		numRows=0, numCols=0;
  WlzObject	*obj, *obj1, *obj2, *obj3;
  WlzObject	**rowDoms, **colDoms;
  WlzObjectType	objType;
  double	matchVal=0.0;
  double	s1, s2, s3, s4;
  double	delta=0.01;
  double	**mixing=NULL, **contrib=NULL;
  int		i, j, k, l;
  int		numCatRows=-1, numCatCols=-1;
  WlzDBox3	box1, box2;

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

    case 'd':
      delta = atof(optarg);
      if((delta >= 1.0) || (delta <= 1.0e-10)){
	delta = 0.01;
	fprintf(stderr, "%s: invalid delta, reset to 0.01", argv[0]);
      }
      break;

    case 'm':
      if((inFile = fopen(optarg, "r")) != NULL){
	if( fscanf(inFile, "%d, %d", &numCatCols, &numCatRows) < 2 ){
	  fprintf(stderr, "%s: can't read mixing matrix dimensions\n", argv[0]);
	  usage(argv[0]);
	  return 1;
	}
	AlcDouble2Malloc(&mixing, numCatRows, numCatCols);
	AlcDouble2Malloc(&contrib, numCatRows, numCatCols);
	for(l=0; l < numCatRows; l++){
	  for(k=0; k < numCatCols; k++){
	    if( fscanf(inFile, "%lg,", &(mixing[l][k])) < 1 ){
	      fprintf(stderr, "%s: can't read mixing matrix\n", argv[0]);
	      usage(argv[0]);
	      return 1;
	    }
	  }
	}
	for(l=0; l < numCatRows; l++){
	  for(k=0; k < numCatCols; k++){
	    if( fscanf(inFile, "%lg,", &(contrib[l][k])) < 1 ){
	      fprintf(stderr, "%s: can't read contributing matrix\n", argv[0]);
	      usage(argv[0]);
	      return 1;
	    }
	  }
	}
      }
      else {
	fprintf(stderr, "%s: can't open matrix file\n", argv[0]);
	usage(argv[0]);
	return 1;
      }
      break; 

    case 't':
      type = atoi(optarg);
      break;

    case 'v':
      verboseFlg = 1;
      break;

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

    }
  }

  /* there must be two more arguments */
  if( (argc - optind) < 2 ){
    fprintf(stderr, "%s: not enough arguments\n", argv[0]);
    usage(argv[0]);
    return 1;
  }
  numRows = atoi(*(argv+optind));
  numCols = atoi(*(argv+optind+1));
  if((numRows <= 0) || (numCols <= 0)){
    fprintf(stderr, "%s: both number of rows and columns must be > 0\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  /* verbose output */
  if( verboseFlg ){
    fprintf(stderr, "%s: parameter values:\n", argv[0]);
    fprintf(stderr, "\ttype = %d, delta = %f\n", type, delta);
    if( type == 6 ){
      fprintf(stderr, "\t mixing matrix:\n");
      for(l=0; l < numCatRows; l++){
	for(k=0; k < numCatCols; k++){
	  fprintf(stderr, "%f, ", mixing[l][k]);
	}
	fprintf(stderr, "\n");
      }
      fprintf(stderr, "\n");
      fprintf(stderr, "\t contributing matrix:\n");
      for(l=0; l < numCatRows; l++){
	for(k=0; k < numCatCols; k++){
	  fprintf(stderr, "%f, ", contrib[l][k]);
	}
	fprintf(stderr, "\n");
      }
    }
  }

  /* get objects from stdin */
  inFile = stdin;
  rowDoms = (WlzObject **) AlcMalloc(sizeof(WlzObject *) * numRows);
  for(i=0; i < numRows; i++){
    if((rowDoms[i] =  WlzReadObj(inFile, &errNum)) != NULL){
    if((i == 0) || (objType == WLZ_EMPTY_OBJ)){
      objType = rowDoms[i]->type;
    }
    if((rowDoms[i]->type != objType) &&
       (rowDoms[i]->type != WLZ_EMPTY_OBJ)){
      fprintf(stderr, "%s: invalid object type: %d\n", argv[0],
	      rowDoms[i]->type);
      usage(argv[0]);
      return 1;
    }
    }
    else {
      fprintf(stderr, "%s: not enough row objects\n", argv[0]);
    }
  }

  /* now the column domains */
  if( type == 5 ){
    colDoms = (WlzObject **) AlcMalloc(sizeof(WlzObject *) * numCols * 2);
    for(i=0; i < numCols*2; i++){
      if((colDoms[i] =  WlzReadObj(inFile, &errNum)) != NULL){
	if((colDoms[i]->type != objType) &&
	   (colDoms[i]->type != WLZ_EMPTY_OBJ)){
	  fprintf(stderr, "%s: invalid object type: %d\n", argv[0],
		  colDoms[i]->type);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	fprintf(stderr, "%s: not enough row objects\n", argv[0]);
      }
    }
  }
  else {
    colDoms = (WlzObject **) AlcMalloc(sizeof(WlzObject *) * numCols);
    for(i=0; i < numCols; i++){
      if((colDoms[i] =  WlzReadObj(inFile, &errNum)) != NULL){
	if((colDoms[i]->type != objType) &&
	   (colDoms[i]->type != WLZ_EMPTY_OBJ)){
	  fprintf(stderr, "%s: invalid object type: %d\n", argv[0],
		  colDoms[i]->type);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	fprintf(stderr, "%s: not enough row objects\n", argv[0]);
      }
    }
  }

  /* now calculate the match values */
  for(i=0; i < numRows; i ++){
    if( verboseFlg ){
      fprintf(stderr, "%s: start row %d\n", argv[0], i+1);
    }
    obj1 = rowDoms[i];
    for(j=0; j < numCols; j++){
      if( type == 5 ){
	obj2 = colDoms[j*2];
	obj3 = colDoms[j*2 + 1];
      }
      else {
	obj2 = colDoms[j];
      }
      
      switch( type ){
      case 1:
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s1 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s1 = 0;
	}
	if((obj = WlzUnion2(obj1, obj2, &errNum)) != NULL){
	  s2 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s2 = 1;
	}
	matchVal = s1 / s2;
	break;

      case 2:
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s1 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s1 = 0;
	}
	if((obj = WlzUnion2(obj1, obj2, &errNum)) != NULL){
	  s2 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s2 = 1;
	}
	matchVal = s1 / s2;
	if( type == 2 ){
	  s1 = WlzSize(obj1, &errNum);
	  s2 = WlzSize(obj2, &errNum);
	  if( s2 > s1 ){
	    if( matchVal == 0.0 ){
	      matchVal = 10.0;
	    }
	    else {
	      matchVal = 1.0 / matchVal;
	      matchVal = WLZ_MIN(matchVal, 10.0);
	    }
	  }
	}
	break;

      case 3:
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s1 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s1 = 0;
	}
	s2 = WlzSize(obj1, &errNum);
	matchVal = 0.0;
	if( s2 > 0 ){
	  matchVal = s1 / s2;
	}
	break;

      case 4:
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s1 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s1 = 0;
	}
	s2 = WlzSize(obj2, &errNum);
	matchVal = 0.0;
	if( s2 > 0 ){
	  matchVal = s1 / s2;
	}
	break;

      case 5:
	/* this is a coparative measure designed to give a value of 1
	   to a random pattern and between zero and infinite for
	   matches to one or the other. For analysis for clustering
	   probably better to use the logarithm. Zero and infinite are
	   delta and 1/delta. */
	/* must be a third object */
	if( obj3 == NULL ){
	  fprintf(stderr, "%s: for match option 5 3 input object required\n",
		  argv[0]);
	  return 1;
	}
	s1 = WlzSize(obj2, &errNum);
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s2 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s2 = 0.0;
	}
	s3 = WlzSize(obj3, &errNum);
	if((obj = WlzIntersect2(obj1, obj3, &errNum)) != NULL){
	  s4 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s4 = 0.0;
	}
	if((s1 < 0.0) || (s2 < 0.0) || (s3 < 0.0) || (s4 < 0.0)){
	  /* just fail */
	  fprintf(stderr, "%s: something gone wrong, negative size.\n",
		  argv[0]);
	  return 1;
	}
	/* calculating (s2/s1) * (s3/s4) */
	/* if the denominator non-zero then simple formula */
	if( s2 > 0.0 ){
	  if( s4 > 0.0 ){
	    matchVal = (s2/s1) * (s3/s4);
	  }
	  else {
	    matchVal = s2 / s1;
	  }
	}
	else {
	  if( s4 > 0.0 ){
	    matchVal = s3/s4;
	  }
	  else {
	    matchVal = 1.0;
	  }
	}
	matchVal = WLZ_MAX(matchVal, delta);
	matchVal = WLZ_MIN(matchVal, 1.0/delta);
	break;

      case 6:
	/* this requires a mixing and contributing matrix and the images
	   read in must have grey-values set to the right categories */
	if((numCatRows == -1) || (numCatCols == -1) ||
	   (mixing == NULL) || (contrib == NULL)){
	  fprintf(stderr, "%s: bad matrix data\n", argv[0]);
	  usage(argv[0]);
	  return 1;
	}
	matchVal = WlzMixtureValue(obj1, obj2, numCatRows, numCatCols,
				   mixing, contrib, &errNum);
	break;

      case 7:
	box1 = WlzBoundingBox3D(obj1, &errNum);
	box2 = WlzBoundingBox3D(obj2, &errNum);
	s1 = (box1.xMax + box1.xMin)/2.0 - (box2.xMax + box2.xMin)/2.0;
	s2 = (box1.yMax + box1.yMin)/2.0 - (box2.yMax + box2.yMin)/2.0;
	matchVal = sqrt(s1*s1 + s2*s2);
	break;

      case 8:
	if((obj = WlzIntersect2(obj1, obj2, &errNum)) != NULL){
	  s1 = WlzSize(obj, &errNum);
	  WlzFreeObj(obj);
	}
	else {
	  s1 = -1;
	}
	matchVal = s1;
	break;

      default:
	fprintf(stderr, "%s: invalid match type\n", argv[0]);
	usage(argv[0]);
	return 1;
      }

      /* print value */
      fprintf(stdout, "%f", matchVal);
      if( (numCols - j) > 1 ){
	fprintf(stdout, "\t");
      }
      if( verboseFlg ){
	fprintf(stderr, ".");
      }
    }
    fprintf(stdout, "\n");
    if( verboseFlg ){
      fprintf(stderr, "\n%s: completed row %d\n", argv[0], i+1);
    }
  }

  return 0;
}
示例#13
0
void installNewDomain(
  WlzObject	*obj,
  char		*file,
  int		displayIndx)
{
  DomainListItem	*newItem, *matchItem=NULL;
  HGUDlpListItem	*item;
  int			i;
  WlzObject		*obj1;
  WlzErrorNum		errNum;

  /* check for repeats - need confirm to continue */
  obj = WlzAssignObject(obj, NULL);
  item = HGUDlpListHead(globals.dmnList);
  while( item ){
    newItem = (DomainListItem *) HGUDlpListEntryGet(globals.dmnList, item);
    if( strcmp(newItem->file, file) ){
      item = HGUDlpListNext(globals.dmnList, item);
    }
    else {
      /* may want to reset this object */
      if( !HGU_XmUserConfirm(globals.topl,
			     "This domain is already on installed.\n"
			     "Do you want to re-read the domain\n"
			     "to extend the existing region?\n"
			     "Note: to reset a domain then delete\n"
			     "it first then re-read.",
			     "Yes", "No", 1) ){
	WlzFreeObj(obj);
	return;
      }
      matchItem = newItem;
      break;
    }
  }

  /* remove overlaps with existing domains  - the new dominates */
  item = HGUDlpListHead(globals.dmnList);
  while( item ){
    newItem = (DomainListItem *) HGUDlpListEntryGet(globals.dmnList, item);
    if( strcmp(newItem->file, file) ){
      obj1 = WlzDiffDomain(newItem->obj, obj, &errNum);
      if( errNum == WLZ_ERR_NONE ){
	WlzFreeObj(newItem->obj);
	if( obj1 ){
	  newItem->obj = WlzAssignObject(obj1, NULL);
	}
	else {
	  newItem->obj = NULL;
	}
      }
    }
    item = HGUDlpListNext(globals.dmnList, item);
  }


  /* OK extend old or create a new list item */
  if( matchItem ){
    obj1 = WlzUnion2(matchItem->obj, obj, &errNum);
    if( errNum == WLZ_ERR_NONE ){
      WlzFreeObj(matchItem->obj);
      if( obj1 ){
	matchItem->obj = WlzAssignObject(obj1, NULL);
      }
      else {
	matchItem->obj = NULL;
      }
    }
  }
  else if( newItem = (DomainListItem *) AlcCalloc(sizeof(DomainListItem), 1) ){
    newItem->file = AlcStrDup(file);
    newItem->fileDisplayIndx = displayIndx;
    newItem->obj = WlzAssignObject(obj, NULL);
    newItem->listStr = XmStringCreateLocalized(newItem->file+displayIndx);

    /* add it to the domain list and domain list widget */
    (void) HGUDlpListInsert(globals.dmnList, NULL, newItem,
			    freeDomainListItem);
    XmListAddItem(globals.dmnListWidget, newItem->listStr, 0);
    XmListSelectItem(globals.dmnListWidget, newItem->listStr, True);
  }

  /* re-display the view */
/*  canvasExposeCb(globals.canvas, NULL, NULL);*/

  WlzFreeObj(obj);
  return;
}