Exemple #1
0
void HGU_XmImageViewResetGreyRange(
    HGU_XmImageViewDataStruct	*data)
{
    WlzPixelV	greyMin, greyMax;
    WlzErrorNum	errNum=WLZ_ERR_NONE;

    if((data == NULL) || (data->obj == NULL)) {
        return;
    }

    /* calculate the grey-range & reset the scale */
    errNum = WlzGreyRange(data->obj, &greyMin, &greyMax);
    switch( greyMin.type ) {
    case WLZ_GREY_LONG:
        data->srcMin = greyMin.v.lnv;
        data->srcMax = greyMax.v.lnv;
        break;

    case WLZ_GREY_INT:
        data->srcMin = greyMin.v.inv;
        data->srcMax = greyMax.v.inv;
        break;

    case WLZ_GREY_SHORT:
        data->srcMin = greyMin.v.shv;
        data->srcMax = greyMax.v.shv;
        break;

    case WLZ_GREY_UBYTE:
        data->srcMin = greyMin.v.ubv;
        data->srcMax = greyMax.v.ubv;
        break;

    case WLZ_GREY_FLOAT:
        data->srcMin = greyMin.v.flv;
        data->srcMax = greyMax.v.flv;
        break;

    case WLZ_GREY_DOUBLE:
        data->srcMin = greyMin.v.dbv;
        data->srcMax = greyMax.v.dbv;
        break;

    case WLZ_GREY_BIT:
    case WLZ_GREY_RGBA:
    default:
        return;
    }

    return;
}
Exemple #2
0
/*! 
* \return       Woolz error number
* \ingroup      WlzValuesFilters
* \brief        Normalizes the the grey values of the input object to
*		fill the range 0-255. Colour values are independently
*		reset which will change colour balance. Use WlzGreySetRange
*		directly to avoid this.
*		Note grey-values are reset in place and not copied.
* \par          Source:
*                 WlzGreyNormalise.c
* \param obj	Input object.
* \param    	Dither values if destination range is greater than source
* 		range and this flag is non-zero.
*/
WlzErrorNum WlzGreyNormalise(
  WlzObject	*obj,
  int		dither)
{
  WlzPixelV	min, max, Min, Max;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* get then set the grey-range of the object */
  errNum = WlzGreyRange(obj, &min, &max);
  Min = min;
  Max = max;
  if( errNum == WLZ_ERR_NONE ){
    switch( min.type ){
    case WLZ_GREY_INT:
      Min.v.inv = 0;
      Max.v.inv = 255;
      break;
    case WLZ_GREY_SHORT:
      Min.v.shv = 0;
      Max.v.shv = 255;
      break;
    case WLZ_GREY_UBYTE:
      Min.v.ubv = 0;
      Max.v.ubv = 255;
      break;
    case WLZ_GREY_FLOAT:
      Min.v.flv = 0.0;
      Max.v.flv = 255.0;
      break;
    case WLZ_GREY_DOUBLE:
      Min.v.dbv = 0.0;
      Max.v.dbv = 255.0;
      break;
    case WLZ_GREY_RGBA:
      Min.v.rgbv = 0xff000000;
      Max.v.rgbv = 0xffffffff;
      break;
    default:
      errNum = WLZ_ERR_GREY_TYPE;
      break;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzGreySetRange(obj, min, max, Min, Max, dither);
    }
  }

  return(errNum);
}
Exemple #3
0
void install_paint_reference_object(
  WlzObject	*obj)
{
  Widget		toggle;
  WlzPixelV		bckgrnd;
  WlzPixelV		min, max, Min, Max;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  if( globals.orig_obj != NULL ){
    WlzFreeObj( globals.orig_obj );
  }
  globals.orig_obj = WlzAssignObject(obj, &errNum);
  obj = NULL;

  /* check input object for grey-value type
     convert if necessary */
  if( errNum == WLZ_ERR_NONE ){
    bckgrnd = WlzGetBackground(globals.orig_obj, &errNum);
    Min.type = WLZ_GREY_INT;
    Max.type = WLZ_GREY_INT;
    Min.v.inv = 0;
    Max.v.inv = 255;
  }
  
  if( errNum == WLZ_ERR_NONE ){
    switch( bckgrnd.type ){
    case WLZ_GREY_LONG:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.lnv < 0) || (max.v.lnv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_INT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.inv < 0) || (max.v.inv > 255) ){
	obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum);
	WlzGreySetRange(obj, min, max, Min, Max, 0);
	bckgrnd = WlzGetBackground(obj, &errNum);
      }
      break;
    case WLZ_GREY_SHORT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.shv < 0) || (max.v.shv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_SHORT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_FLOAT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.flv < 0) || (max.v.flv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_DOUBLE:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.dbv < 0) || (max.v.dbv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;

    default:
    case WLZ_GREY_UBYTE:
      break;
    }
  }

  /* copy for later transform for display purposes,
     the original is kept for IP purposes note pixconvert loses
     the background value */
  if( errNum == WLZ_ERR_NONE ){
    if( globals.obj != NULL ){
      WlzFreeObj( globals.obj );
    }
    if( obj ){
      globals.obj =
	WlzAssignObject(WlzConvertPix(obj, WLZ_GREY_UBYTE, &errNum), NULL);
      WlzFreeObj(globals.orig_obj);
      globals.orig_obj = WlzAssignObject(obj, NULL);
    }
    else {
      globals.obj =
	WlzAssignObject(WlzConvertPix(globals.orig_obj,
				      WLZ_GREY_UBYTE, &errNum), NULL);
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    min.type = WLZ_GREY_UBYTE;
    max.type = WLZ_GREY_UBYTE;
    Min.type = WLZ_GREY_UBYTE;
    Max.type = WLZ_GREY_UBYTE;
    min.v.ubv = 0;
    max.v.ubv = 255;
    Min.v.ubv = globals.cmapstruct->gmin;
    Max.v.ubv = globals.cmapstruct->gmax;
    errNum = WlzGreySetRange(globals.obj, min, max, Min, Max, 0);
  }

  /* also convert the background values */
  if( errNum == WLZ_ERR_NONE ){
/*  min = WlzGetBackground(globals.orig_obj, NULL);*/
    WlzValueConvertPixel(&bckgrnd, bckgrnd, WLZ_GREY_INT);
    max.type = WLZ_GREY_INT;
    max.v.inv = ((bckgrnd.v.inv * (Max.v.ubv - Min.v.ubv)) / 255) + Min.v.ubv;
    WlzSetBackground(globals.obj, max);

    /* fill blank planes here - should be a resource option */
    if( (toggle = XtNameToWidget(read_obj_dialog, "*.fill_blanks")) ){
      Boolean	fill_blanks, min_domain;
      XtVaGetValues(toggle, XmNset, &fill_blanks, NULL);
      if( fill_blanks ){
	if( (toggle = XtNameToWidget(read_obj_dialog, "*.min_domain")) ){
	  XtVaGetValues(toggle, XmNset, &min_domain, NULL);
	  if( min_domain ){
	    WlzFillBlankPlanes(globals.obj, 1);
	  } else {
	    WlzFillBlankPlanes(globals.obj, 0);
	  }
	}
	else {
	  WlzFillBlankPlanes(globals.obj, 1);
	}
      }
    }

    /* setup the display list and properties dialog */
    setup_ref_display_list_cb(read_obj_dialog, NULL, NULL);
    setup_obj_props_cb(read_obj_dialog, NULL, NULL);
  }

  /* log the object size */
  if( (errNum == WLZ_ERR_NONE) && globals.logfileFp ){
    char strBuf[64];
    sprintf(strBuf, "(%d, %d, %d, %d, %d, %d)",
	    globals.obj->domain.p->kol1, globals.obj->domain.p->line1,
	    globals.obj->domain.p->plane1, globals.obj->domain.p->lastkl,
	    globals.obj->domain.p->lastln, globals.obj->domain.p->lastpl);
    MAPaintLogData("BoundingBox", strBuf, 0, NULL);
    sprintf(strBuf, "%d", (int) WlzVolume(globals.obj, NULL));
    MAPaintLogData("Volume", strBuf, 0, NULL);
  }

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl,
			  "install_paint_reference_object", errNum);
  }
  return;
}
Exemple #4
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);
}
int main(int	argc,
	 char	**argv)
{

  WlzObject	*obj;
  FILE		*inFile;
  char 		optList[] = "l:L:u:U:dhv";
  int		dither = 0,
  		option;
  WlzPixelV	max, min, Max, Min;
  WlzPixelV	gmin, gmax;
  int		getminFlg=1, getmaxFlg=1, verboseFlg=0;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
  int		objCount=0;
    
  /* read the argument list and check for an input file */
  opterr = 0;
  Max.type = Min.type = max.type = min.type = WLZ_GREY_DOUBLE;
  Max.v.dbv = 255.0;
  Min.v.dbv = 0.0;
  
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){
      case 'd':
	dither = 1;
	break;
      case 'l':
	min.v.dbv = atof(optarg);
	getminFlg = 0;
	break;
      case 'L':
	Min.v.dbv = atof(optarg);
	break;
      case 'u':
	max.v.dbv = atof(optarg);
	getmaxFlg = 0;
	break;
      case 'U':
	Max.v.dbv = atof(optarg);
	break;
      case 'v':
	verboseFlg = 1;
	break;
      case 'h':
      default:
	usage(argv[0]);
	return 1;
    }
  }

  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;
    }
  }

  /* read objects and threshold if possible */
  while(((obj = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) != NULL) &&
        (errNum == WLZ_ERR_NONE))
  {
    objCount++;
    switch( obj->type )
    {
    case WLZ_2D_DOMAINOBJ:
    case WLZ_3D_DOMAINOBJ:
      /* get the existing min and max grey values */
      if( (errNum = WlzGreyRange(obj, &gmin, &gmax)) == WLZ_ERR_NONE ){
	if( getminFlg ){
	  WlzValueConvertPixel(&min, gmin, WLZ_GREY_DOUBLE);
	}
	if( getmaxFlg ){
	  WlzValueConvertPixel(&max, gmax, WLZ_GREY_DOUBLE);
	}

	if( verboseFlg ){
	  fprintf(stderr,
		  "%s:\nconverting object %d with parameters:\n"
		  "\tSource (l, u) = (%f, %f)\n"
		  "\tDestination (L, U) = (%f, %f)\n",
		  argv[0], objCount, min.v.dbv, max.v.dbv,
		  Min.v.dbv, Max.v.dbv);
	}

	errNum = WlzGreySetRange(obj, min, max, Min, Max, dither);
	if( errNum == WLZ_ERR_NONE ){
	  errNum = WlzWriteObj(stdout, obj);
	}
      }
      if( errNum != WLZ_ERR_NONE ){
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: failed to write object (%s).\n",
		       argv[0], errMsg);
	return(errNum);
      }
      break;

    default:
      if((errNum = WlzWriteObj(stdout, obj)) != WLZ_ERR_NONE) {
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: failed to write object (%s).\n",
		       argv[0], errMsg);
	return(1);
      }
      break;
    }
    WlzFreeObj(obj);
  }

  return 0;
}
Exemple #6
0
double WlzMixtureValue(
  WlzObject	*obj1,
  WlzObject	*obj2,
  int		numCatRows,
  int		numCatCols,
  double	**mixing,
  double	**contrib,
  WlzErrorNum	*dstErr)
{
  double	val, con;
  WlzObject	*tmpObj, *tmpObj1, *tmpObj2;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyP		gptr;
  WlzGreyValueWSpace	*gVWSp;
  WlzPixelV		minP, maxP;
  int		i;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* objects must be same type with grey-values */
  if( (obj1 == NULL) || (obj2 == NULL) ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj1->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj2->type != obj1->type ){
	errNum = WLZ_ERR_OBJECT_TYPE;
      }
      else {
	if((obj1->values.core == NULL) || (obj2->values.core == NULL)){
	  errNum = WLZ_ERR_VALUES_NULL;
	}
	else {
	  /* convert to int and check range */
	  if((tmpObj1 = WlzConvertPix(obj1, WLZ_GREY_INT, &errNum)) != NULL){
	    errNum = WlzGreyRange(tmpObj1, &minP, &maxP);
	    if( errNum == WLZ_ERR_NONE ){
	      if((minP.v.inv < 1) || (minP.v.inv > numCatRows) ||
		 (maxP.v.inv < 1) || (maxP.v.inv > numCatRows)){
		errNum = WLZ_ERR_OBJECT_DATA;
		WlzFreeObj(tmpObj1);
	      }
	    }
	    else {
	      WlzFreeObj(tmpObj1);
	    }
	  }
	  if((errNum == WLZ_ERR_NONE) &&
	     (tmpObj2 = WlzConvertPix(obj2, WLZ_GREY_INT, &errNum)) ){
	    errNum = WlzGreyRange(tmpObj2, &minP, &maxP);
	    if( errNum == WLZ_ERR_NONE ){
	      if((minP.v.inv < 1) || (minP.v.inv > numCatCols) ||
		 (maxP.v.inv < 1) || (maxP.v.inv > numCatCols)){
		errNum = WLZ_ERR_OBJECT_DATA;
		WlzFreeObj(tmpObj1);
		WlzFreeObj(tmpObj2);
	      }
	    }
	    else {
	      WlzFreeObj(tmpObj1);
	      WlzFreeObj(tmpObj2);
	    }
	  }
	}
      }
      break;

    case WLZ_3D_DOMAINOBJ:
    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* get the intersection region */
  if( errNum == WLZ_ERR_NONE ){
    if((tmpObj = WlzIntersect2(tmpObj1, tmpObj2, &errNum)) != NULL){
      tmpObj->values = WlzAssignValues(tmpObj1->values, &errNum);
    }
    else {
      WlzFreeObj(tmpObj1);
      WlzFreeObj(tmpObj2);
    }
  }

  /* now calculate the mixture value */
  if( errNum == WLZ_ERR_NONE ){
    errNum = WlzInitGreyScan(tmpObj, &iwsp, &gwsp);
    gVWSp = WlzGreyValueMakeWSp(tmpObj2, &errNum);
    val = 0.0;
    con = 0.0;
    while((errNum == WLZ_ERR_NONE) &&
	  (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE ){

      gptr = gwsp.u_grintptr;
      for (i=0; i<iwsp.colrmn; i++, gptr.inp++){
	WlzGreyValueGet(gVWSp, 0, iwsp.linpos, iwsp.colpos+i);
	val += mixing[(*gptr.inp)-1][gVWSp->gVal[0].inv-1];
	con += contrib[(*gptr.inp)-1][gVWSp->gVal[0].inv-1];
      }
    }
    if( errNum == WLZ_ERR_EOO ){
      errNum = WLZ_ERR_NONE;
    }
    WlzGreyValueFreeWSp(gVWSp);
    WlzFreeObj(tmpObj);
    WlzFreeObj(tmpObj1);
    WlzFreeObj(tmpObj2);
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  if( con > 0.0 ){
    return val/con;
  }
  else {
    return 0.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);
}
Exemple #8
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;
}