예제 #1
0
/*!
* \return	Woolz error code.
* \ingroup	WlzArithmetic
* \brief	Sets the values of the return object from the input object
* 		using simple linear scaling, see WlzScalarMulAdd(). The
* 		objects are known to be 2D, have the same domain.
* \param	rObj
* \param	iObj
* \param	m
* \param	a
*/
static WlzErrorNum WlzScalarMulAddSet2D(WlzObject *rObj, WlzObject *iObj,
				     double m, double a)
{
  int		bufLen;
  WlzGreyWSpace iGWSp,
  		rGWSp;
  WlzIntervalWSpace iIWSp = {0},
  		    rIWSp = {0};
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  bufLen = iObj->domain.i->lastkl - iObj->domain.i->kol1 + 1;
  if((bufLen != iObj->domain.i->lastkl - iObj->domain.i->kol1 + 1) ||
     (bufLen < 0))
  {
    errNum = WLZ_ERR_DOMAIN_DATA;
  }
  else if(bufLen > 0)
  {
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzInitGreyScan(iObj, &iIWSp, &iGWSp);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzInitGreyScan(rObj, &rIWSp, &rGWSp);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      double	*buf = NULL;

      if((buf = AlcMalloc(sizeof(double) * bufLen)) == NULL)
      {
        errNum = WLZ_ERR_MEM_ALLOC;
      }
      else
      {
	while((errNum = WlzNextGreyInterval(&iIWSp)) == WLZ_ERR_NONE)
	{
	  int	t,
	  	idN,
	  	itvLen;
	  double f;


	  itvLen = iIWSp.colrmn;
	  (void )WlzNextGreyInterval(&rIWSp);
	  switch(iGWSp.pixeltype)
	  {
	    case WLZ_GREY_INT:
	      WlzValueCopyIntToDouble(buf, iGWSp.u_grintptr.inp, itvLen);
	      break;
	    case WLZ_GREY_SHORT:
	      WlzValueCopyShortToDouble(buf, iGWSp.u_grintptr.shp, itvLen);
	      break;
	    case WLZ_GREY_UBYTE:
	      WlzValueCopyUByteToDouble(buf, iGWSp.u_grintptr.ubp, itvLen);
	      break;
	    case WLZ_GREY_FLOAT:
	      WlzValueCopyFloatToDouble(buf, iGWSp.u_grintptr.flp, itvLen);
	      break;
	    case WLZ_GREY_DOUBLE:
	      WlzValueCopyDoubleToDouble(buf, iGWSp.u_grintptr.dbp, itvLen);
	      break;
	    case WLZ_GREY_RGBA:
	      WlzValueCopyRGBAToDouble(buf, iGWSp.u_grintptr.rgbp, itvLen);
	      break;
	    default:
	      break;
	  }
	  switch(rGWSp.pixeltype)
	  {
	    case WLZ_GREY_UBYTE:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		f = (buf[idN] * m) + a;
		f = WLZ_CLAMP(f, 0, 255);
		rGWSp.u_grintptr.ubp[idN] = WLZ_NINT(f);
	      }
	      break;
	    case WLZ_GREY_SHORT:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		f = (buf[idN] * m) + a;
		f = WLZ_CLAMP(f, SHRT_MIN, SHRT_MAX);
		rGWSp.u_grintptr.shp[idN] = WLZ_NINT(f);
	      }
	      break;
	    case WLZ_GREY_INT:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		f = (buf[idN] * m) + a;
		f = WLZ_CLAMP(f, INT_MIN, INT_MAX);
		rGWSp.u_grintptr.inp[idN] = WLZ_NINT(f);
	      }
	      break;
	    case WLZ_GREY_RGBA:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		WlzUInt	u;

		f = (buf[idN] * m) + a;
		f = WLZ_CLAMP(f, 0, 255);
		t = WLZ_NINT(f);
                WLZ_RGBA_RGBA_SET(u, t, t, t, 255);
		rGWSp.u_grintptr.inp[idN] = u;
	      }
	    case WLZ_GREY_FLOAT:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		double	t;

		t = (buf[idN] * m) + a;
		rGWSp.u_grintptr.flp[idN] = WLZ_CLAMP(t, -(FLT_MAX), FLT_MAX);
	      }
	      break;
	    case WLZ_GREY_DOUBLE:
	      for(idN = 0; idN < itvLen; ++idN)
	      {
		rGWSp.u_grintptr.dbp[idN] = (buf[idN] * m) + a;
	      }
	      break;
	    default:
	      break;
	  }
	}
	if(errNum == WLZ_ERR_EOO)
	{
	  errNum = WLZ_ERR_NONE;
	}
      }
      AlcFree(buf);
    }
    (void )WlzEndGreyScan(&iIWSp, &iGWSp);
    (void )WlzEndGreyScan(&rIWSp, &rGWSp);
  }
  return(errNum);
}
예제 #2
0
/*!
* \return	New filtered object with new values or NULL on error.
* \ingroup	WlzValuesFilters
* \brief	Applies a seperable filter along the x axis (columns)
* 		to the given object using the given convolution kernel.
* \param	inObj			Input 2 or 3D spatial domain object
* 					to be filtered which must have scalar
* 					values.
* \param	dim			Object's dimension.
* \param	maxThr			Maximum number of threads to use.
* \param	iBuf			Working buffers large enough for any
* 				        line in the image with one for each
* 				        thread.
* \param	rBuf			Buffers as for iBuf. 			
* \param	cBufSz			Convolution kernel size.
* \param	cBuf			Convolution kernel buffer.
* \param	pad			Type of padding.
* \param	padVal			Padding value.
* \param	dstErr			Destination error pointer may be NULL.
*/
static WlzObject		*WlzSepFilterX(WlzObject *inObj,
				  int dim,
				  int maxThr,
				  double **iBuf,
				  double **rBuf,
				  int cBufSz,
				  double *cBuf,
				  AlgPadType pad,
				  double padVal,
				  WlzErrorNum *dstErr)
{
  int		idp,
		poff,
  		nPln;
  WlzObjectType	rGTT;
  WlzDomain	*domains;
  WlzValues	*iVal,
  		*rVal;
  WlzPixelV	zV;
  WlzObject	*rnObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  		
  zV.v.dbv = 0.0;
  zV.type = WLZ_GREY_DOUBLE;
  rGTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, WLZ_GREY_DOUBLE, NULL);
  if(dim == 3)
  {
    WlzPlaneDomain *pDom;
    WlzVoxelValues *vVal;

    pDom = inObj->domain.p;
    vVal = inObj->values.vox;
    nPln = pDom->lastpl - pDom->plane1 + 1;
    domains = pDom->domains;
    iVal = vVal->values;
    poff = pDom->plane1 - vVal->plane1;
    rnObj = WlzNewObjectValues(inObj, rGTT, zV, 1, zV, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      rVal = rnObj->values.vox->values;
    }
  }
  else
  {
    nPln = 1;
    poff = 0;
    domains = &(inObj->domain);
    iVal = &(inObj->values);
    rnObj = WlzNewObjectValues(inObj, rGTT, zV, 1, zV, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      rVal = &(rnObj->values);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
#ifdef _OPENMP
#pragma omp parallel for num_threads(maxThr)
#endif
    for(idp = 0; idp < nPln; ++idp)
    {
      if(errNum == WLZ_ERR_NONE)
      {
	if(domains[idp].core != NULL)
	{
	  int		thrId = 0;
	  WlzObject 	*iObj = NULL,
			*rObj = NULL;
	  WlzIntervalWSpace iIWSp,
			    rIWSp;
	  WlzGreyWSpace	iGWSp,
			rGWSp;
          WlzErrorNum	errNum2 = WLZ_ERR_NONE;

#ifdef _OPENMP
          thrId = omp_get_thread_num();
#endif
	  iObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domains[idp], iVal[idp + poff],
			     NULL, NULL, &errNum2);
	  if(errNum2 == WLZ_ERR_NONE)
	  {
	    rObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domains[idp], rVal[idp],
			       NULL, NULL, &errNum2);
	  }
	  if((errNum2 == WLZ_ERR_NONE) &&
	     ((errNum2 = WlzInitGreyScan(iObj, &iIWSp,
	                                 &iGWSp)) == WLZ_ERR_NONE) &&
	     ((errNum2 = WlzInitGreyScan(rObj, &rIWSp,
	                                 &rGWSp)) == WLZ_ERR_NONE))
	  {
	    while(((errNum2 = WlzNextGreyInterval(&iIWSp)) == WLZ_ERR_NONE) &&
		  ((errNum2 = WlzNextGreyInterval(&rIWSp)) == WLZ_ERR_NONE))
	    {
	      size_t	len;
	      WlzGreyP	iBufGP;

	      
	      iBufGP.dbp = iBuf[thrId];
	      len = iIWSp.rgtpos - iIWSp.lftpos + 1;
	      WlzValueCopyGreyToGrey(iBufGP, 0, WLZ_GREY_DOUBLE,
				     iGWSp.u_grintptr, 0, iGWSp.pixeltype,
				     len);
	      AlgConvolveD(len, rBuf[thrId], cBufSz * 2 + 1, cBuf,
                           len, iBuf[thrId], pad, padVal);
	      WlzValueCopyDoubleToDouble(rGWSp.u_grintptr.dbp,
				         rBuf[thrId], len);
	    }
	    (void )WlzEndGreyScan(&iIWSp, &iGWSp);
	    (void )WlzEndGreyScan(&rIWSp, &rGWSp);
	    if(errNum2 == WLZ_ERR_EOO)
	    {
	      errNum2 = WLZ_ERR_NONE;
	    }
	  }
	  (void )WlzFreeObj(iObj);
	  (void )WlzFreeObj(rObj);
	  if(errNum2 != WLZ_ERR_NONE)
	  {
#ifdef _OPENMP
#pragma omp critical
	    {
#endif
	      if(errNum == WLZ_ERR_NONE)
	      {
		errNum = errNum2;
	      }
#ifdef _OPENMP
	    }
#endif
	  }
	}
      }
    }
  }
  if(errNum != WLZ_ERR_NONE)
  {
    (void )WlzFreeObj(rnObj);
    rnObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rnObj);
}
예제 #3
0
int             main(int argc, char **argv)
{
  int		idB,
  		idD,
  		option,
		numDbn = 0,
		synthesize = 0,
		fitCnt = 0,
		ok = 1,
		usage = 0;
  double	tD0,
		tD1,
		tD2,
		pos,
  		mu,
  		sigma,
		alpha,
		binCnt,
		sumArea,
  		pkSigma = 1.0,
  		pkThresh = 1.0,
		fitTol = 0.1;
  double	*fitMu = NULL,
  		*fitSigma = NULL,
  		*fitAlpha = NULL,
		*fitArea = NULL,
		*synBuf = NULL;
  WlzHistogramDomain *inDom,
  		     *outDom;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  FILE		*fP = NULL;
  WlzObject	*inObj = NULL,
  		*outObj = NULL;
  char 		*outDatFileStr,
  		*inObjFileStr;
  const char	*errMsg;
  static char	optList[] = "l:n:o:s:t:hy",
		outDatFileStrDef[] = "-",
  		inObjFileStrDef[] = "-";

  opterr = 0;
  outDatFileStr = outDatFileStrDef;
  inObjFileStr = inObjFileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'l':
	if(sscanf(optarg, "%lg", &fitTol) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'n':
	if(sscanf(optarg, "%d", &numDbn) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'o':
        outDatFileStr = optarg;
	break;
      case 's':
	if(sscanf(optarg, "%lg", &pkSigma) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 't':
	if(sscanf(optarg, "%lg", &pkThresh) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'y':
	synthesize = 1;
        break;
      case 'h':
      default:
        usage = 1;
	ok = 0;
	break;
    }
  }
  if((inObjFileStr == NULL) || (*inObjFileStr == '\0') ||
     (outDatFileStr == NULL) || (*outDatFileStr == '\0'))
  {
    ok = 0;
    usage = 1;
  }
  if(ok && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
      ok = 0;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if((inObjFileStr == NULL) ||
       (*inObjFileStr == '\0') ||
       ((fP = (strcmp(inObjFileStr, "-")?
	      fopen(inObjFileStr, "r"): stdin)) == NULL) ||
       ((inObj= WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to read object from file %s (%s).\n",
		     *argv, inObjFileStr, errMsg);
    }
    if(fP && strcmp(inObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  if(ok)
  {
    if(inObj->type != WLZ_HISTOGRAM)
    {
      ok = 0;
      (void )fprintf(stderr,
      		     "%s: input object read from file %s not a histogram\n",
		     *argv, inObjFileStr);
    }
  }
  if(ok)
  {
    if(inObj == NULL)
    {
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else if(inObj->type != WLZ_HISTOGRAM)
    {
      errNum = WLZ_ERR_OBJECT_TYPE;
    }
    else if((inDom = inObj->domain.hist) == NULL)
    {
      errNum = WLZ_ERR_DOMAIN_NULL;
    }
    else if((inDom->nBins < 0) || (inDom->maxBins < 0) ||
    	    (inDom->binSize <= DBL_EPSILON))
    {
      errNum = WLZ_ERR_DOMAIN_DATA;
    }
    else if((inDom->type != WLZ_HISTOGRAMDOMAIN_INT) &&
            (inDom->type != WLZ_HISTOGRAMDOMAIN_FLOAT))
    {
      errNum = WLZ_ERR_DOMAIN_TYPE;
    }
  }
  if(ok)
  {
    errNum = WlzHistogramFitPeaks(inObj, numDbn,
    				  pkSigma, pkThresh, fitTol,
				  &fitCnt, &fitMu,
				  &fitCnt, &fitSigma,
				  &fitCnt, &fitAlpha,
				  NULL);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to fit histogram (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok && (inDom->nBins > 0) && (fitCnt > 0))
  {
    if(((fitArea = (double *)AlcMalloc(fitCnt *
    				      sizeof(double))) == NULL) ||
       ((synBuf = (double *)AlcCalloc(inDom->nBins,
    				      sizeof(double))) == NULL))
    {
      errNum = WLZ_ERR_MEM_ALLOC;
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to fit histogram (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok && (fitCnt > 0))
  {
    binCnt = WlzHistogramBinSum(inDom);
    for(idD = 0; idD < fitCnt; ++idD)
    {
      mu = *(fitMu + idD);
      sigma = *(fitSigma + idD);
      alpha = *(fitAlpha + idD);
      tD0 = alpha / (sqrt(2.0 * WLZ_M_PI) * sigma);
      for(idB = 0; idB < inDom->nBins; ++idB)
      {
        pos = inDom->origin + (idB * inDom->binSize) - mu;
	tD1 = pos / sigma;
	tD1 = -0.5 * (tD1 * tD1);
	tD2 = tD0 * exp(tD1);
	*(synBuf + idB) += tD2;
	*(fitArea + idD) += tD2 * inDom->binSize;
	sumArea += tD2 * inDom->binSize;
      }
    }
    tD0 = binCnt / sumArea;
    for(idD = 0; idD < fitCnt; ++idD)
    {
      *(fitArea + idD) *= tD0;
    }
    for(idB = 0; idB < inDom->nBins; ++idB)
    {
      *(synBuf + idB) *= tD0;
    }
    if((fP = (strcmp(outDatFileStr, "-")?
	     fopen(outDatFileStr, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: failed to write output data\n",
		     *argv);
    }
    else
    {
      if(synthesize)
      {
        outObj = WlzMakeHistogram(inDom->type, inDom->nBins, &errNum);
	if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
			 "%s: failed to synthesize histogram (%s).\n",
			 *argv, errMsg);
	}
	else
	{
	  outDom = outObj->domain.hist;
	  outDom->nBins = inDom->nBins;
	  outDom->origin = inDom->origin;
	  outDom->binSize = inDom->binSize;
	  switch(inDom->type)
	  {
	    case WLZ_HISTOGRAMDOMAIN_INT:
	      WlzValueCopyDoubleToInt(outDom->binValues.inp, synBuf,
	      			      inDom->nBins);
	      break;
	    case WLZ_HISTOGRAMDOMAIN_FLOAT:
	      WlzValueCopyDoubleToDouble(outDom->binValues.dbp, synBuf,
	      			         inDom->nBins);
	      break;
	    default:
	      break;
	  }
	  if(WlzWriteObj(fP, outObj) != WLZ_ERR_NONE)
	  {
	    ok = 0;
	    (void )fprintf(stderr,
	    		   "%s: failed to write output object\n",
			   *argv);
	  }
	}
      }
      else
      {
	if(fitCnt > 0)
	{
	  for(idD = 0; idD < fitCnt; ++idD)
	  {
	    fprintf(fP, "%8g %8g %8g %8g\n",
		    *(fitMu + idD), *(fitSigma + idD),
		    *(fitAlpha + idD), *(fitArea + idD));
	  }
	}
      }
      if(strcmp(outDatFileStr, "-"))
      {
	fclose(fP);
      }
    }
  }
  if(inObj)
  {
    WlzFreeObj(inObj);
  }
  if(outObj)
  {
    WlzFreeObj(outObj);
  }
  if(fitArea)
  {
    AlcFree(fitArea);
  }
  if(synBuf)
  {
    AlcFree(synBuf);
  }
  if(fitMu)
  {
    AlcFree(fitMu);
  }
  if(fitSigma)
  {
    AlcFree(fitSigma);
  }
  if(fitAlpha)
  {
    AlcFree(fitAlpha);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%sExample: %s%s",
    *argv,
    " [-h] [-y] [-o<out file>] [-s#] [-t#] [-l#] [<in object>]\n"
    "Options:\n"
    "  -l  Log-liklihood fitting tolerance.\n"
    "  -n  Number of Gaussian distributions.\n"
    "  -o  Output data file name.\n"
    "  -s  Minimum Gaussian sigma (standard deviation).\n"
    "  -t  Threshold value for peak height.\n"
    "  -y  Synthesize a new histogram from the mixture of Gaussians, by\n"
    "      default just the statistics are output.\n"
    "  -h  Help, prints this usage message.\n"
    "Fits a mixture of Gaussian distributions to the given Woolz histogram\n"
    "using a maximum liklihood estimate. If given the number of Gaussian\n"
    "distributions is zero (default) then Gaussians will be fitted to\n"
    "peaks found using WlzHistogramFindPeaks.\n"
    "Either the statistics of the Gaussian mixture are output in the format\n"
    "  <mu (mean)> <sigma (std dev)> <alpha (height)> <area>\n"
    "one record for each fitted Gaussian, or a synthesized histogram built\n"
    "using the statistics is output.\n"
    "Objects/data are read from stdin and written to stdout unless the\n"
    "filenames are given.\n",
    *argv,
    " -s1.0 -t 10.0 myhist.wlz\n"
    "The input Woolz histogram object is read from myhist.wlz. Histogram\n"
    "peaks are detected using a Gaussian smoothing filter with a sigma value\n"
    "of 1.0 and a threshold value of 10.0, the maximum liklihood mixture\n"
    "of Gaussians is computed and the mixture statistics are written to the\n"
    "standard output.\n");
  }
  return(!ok);
}