Пример #1
0
int
pullScaleTracePlotAdd(pullContext *pctx, Nrrd *nwild, Nrrd *nccd,
                      Nrrd *nmask, double mth, airArray *insideArr,
                      double velHalf, pullTrace *pts) {
  static const char me[]="pullScaleTracePlotAdd";
  double ssr[2], *pos, *velo, *wild, *ccd, *mask;
  unsigned int pnum, pidx, sizeS, sizeV;

  if (!(pctx && nwild && nccd && pts)) {
    biffAddf(PULL, "%s: got NULL pointer", me);
    return 1;
  }
  if (!nrrdSameSize(nwild, nccd, AIR_TRUE)) {
    biffMovef(PULL, NRRD, "%s: nwild not same size as nccd", me);
    return 1;
  }
  if (nmask || insideArr) {
    if (!insideArr) {
      biffAddf(PULL, "%s: got nmask but not insideArr", me);
      return 1;
    }
    if (!nmask) {
      biffAddf(PULL, "%s: got insideArr but not nmask", me);
      return 1;
    }
    if (nrrdTypeDouble != nmask->type) {
      biffAddf(PULL, "%s: nmask has type %s but want %s", me,
               airEnumStr(nrrdType, nmask->type),
               airEnumStr(nrrdType, nrrdTypeDouble));
      return 1;
    }
    if (!nrrdSameSize(nwild, nmask, AIR_TRUE)) {
      biffMovef(PULL, NRRD, "%s: nwild not same size as nmask", me);
      return 1;
    }
    if (!nrrdSameSize(nccd, nmask, AIR_TRUE)) {
      biffMovef(PULL, NRRD, "%s: nccd not same size as nmask", me);
      return 1;
    }
    if (!AIR_EXISTS(mth)) {
      biffAddf(PULL, "%s: got non-existent mask thresh %g", me, mth);
      return 1;
    }
  }
  ssr[0] = nwild->axis[0].min;
  ssr[1] = nwild->axis[0].max;
  sizeS = AIR_CAST(unsigned int, nwild->axis[0].size);
  sizeV = AIR_CAST(unsigned int, nwild->axis[1].size);
  wild = AIR_CAST(double *, nwild->data);
  ccd = AIR_CAST(double *, nccd->data);
  if (nmask) {
    mask = AIR_CAST(double *, nmask->data);
  } else {
Пример #2
0
/*
******** nrrdArithTerneryOp
**
** HEY: UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED
**
** this is a simplified version of nrrdArithIterTernaryOp, written after
** that, in a hurry, to operate directly on three nrrds, instead with
** the NrrdIter nonsense
*/
int
nrrdArithTernaryOp(Nrrd *nout, int op, const Nrrd *ninA,
                   const Nrrd *ninB, const Nrrd *ninC) {
  static const char me[]="nrrdArithTernaryOp";
  char *contA, *contB, *contC;
  size_t N, I, size[NRRD_DIM_MAX];
  double (*ins)(void *v, size_t I, double d),
    (*lupA)(const void *v, size_t I), (*lupB)(const void *v, size_t I),
    (*lupC)(const void *v, size_t I),
    (*top)(double a, double b, double c), valA, valB, valC;

  if (!( nout && !nrrdCheck(ninA) && !nrrdCheck(ninB) && !nrrdCheck(ninC) )) {
    biffAddf(NRRD, "%s: NULL pointer or invalid args", me);
    return 1;
  }
  if (!( nrrdSameSize(ninA, ninB, AIR_TRUE) &&
         nrrdSameSize(ninA, ninC, AIR_TRUE) )) {
    biffAddf(NRRD, "%s: size mismatch between arguments", me);
    return 1;
  }
  if (airEnumValCheck(nrrdTernaryOp, op)) {
    biffAddf(NRRD, "%s: ternary op %d invalid", me, op);
    return 1;
  }

  nrrdAxisInfoGet_nva(ninA, nrrdAxisInfoSize, size);
  if (!( nout == ninA || nout == ninB || nout == ninC)) {
    if (_nrrdMaybeAllocMaybeZero_nva(nout, ninA->type, ninA->dim, size,
                                     AIR_FALSE /* zero when no realloc */)) {
      biffAddf(NRRD, "%s: couldn't allocate output nrrd", me);
      return 1;
    }
    if (nrrdAxisInfoCopy(nout, ninA, NULL, NRRD_AXIS_INFO_NONE)) {
      biffAddf(NRRD, "%s:", me);
      return 1;
    }
    nrrdBasicInfoCopy(nout, ninA, (NRRD_BASIC_INFO_DATA_BIT
                                   | NRRD_BASIC_INFO_TYPE_BIT
                                   | NRRD_BASIC_INFO_DIMENSION_BIT
                                   | NRRD_BASIC_INFO_CONTENT_BIT
                                   | NRRD_BASIC_INFO_COMMENTS_BIT
                                   | (nrrdStateKeyValuePairsPropagate
                                      ? 0
                                      : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT)));
  }
  nrrdBasicInfoInit(nout,
                    NRRD_BASIC_INFO_ALL ^ (NRRD_BASIC_INFO_OLDMIN_BIT
                                           | NRRD_BASIC_INFO_OLDMAX_BIT));
  top = _nrrdTernaryOp[op];

  N = nrrdElementNumber(ninA);
  lupA = nrrdDLookup[ninA->type];
  lupB = nrrdDLookup[ninB->type];
  lupC = nrrdDLookup[ninC->type];
  ins = nrrdDInsert[nout->type];
  for (I=0; I<N; I++) {
    /* HEY: there is a loss of precision issue here with 64-bit ints */
    valA = lupA(ninA->data, I);
    valB = lupB(ninB->data, I);
    valC = lupC(ninC->data, I);
    ins(nout->data, I, top(valA, valB, valC));
  }

  contA = _nrrdContentGet(ninA);
  contB = _nrrdContentGet(ninB);
  contC = _nrrdContentGet(ninC);
  if (_nrrdContentSet_va(nout, airEnumStr(nrrdTernaryOp, op),
                         contA, "%s,%s", contB, contC)) {
    biffAddf(NRRD, "%s:", me);
    free(contA); free(contB); free(contC); return 1;
  }
  free(contA);
  free(contB);
  free(contC);

  return 0;
}
Пример #3
0
/*
******** nrrdHisto()
**
** makes a 1D histogram of a given size and type
**
** pre-NrrdRange policy:
** this looks at nin->min and nin->max to see if they are both non-NaN.
** If so, it uses these as the range of the histogram, otherwise it
** finds the min and max present in the volume.  If nin->min and nin->max
** are being used as the histogram range, then values which fall outside
** this are ignored (they don't contribute to the histogram).
**
** post-NrrdRange policy:
*/
int
nrrdHisto(Nrrd *nout, const Nrrd *nin, const NrrdRange *_range,
          const Nrrd *nwght, size_t bins, int type) {
  static const char me[]="nrrdHisto", func[]="histo";
  size_t I, num, idx;
  airArray *mop;
  NrrdRange *range;
  double min, max, eps, val, count, incr, (*lup)(const void *v, size_t I);

  if (!(nin && nout)) {
    /* _range and nwght can be NULL */
    biffAddf(NRRD, "%s: got NULL pointer", me);
    return 1;
  }
  if (nout == nin) {
    biffAddf(NRRD, "%s: nout==nin disallowed", me);
    return 1;
  }
  if (!(bins > 0)) {
    biffAddf(NRRD, "%s: bins value (" _AIR_SIZE_T_CNV ") invalid", me, bins);
    return 1;
  }
  if (airEnumValCheck(nrrdType, type) || nrrdTypeBlock == type) {
    biffAddf(NRRD, "%s: invalid nrrd type %d", me, type);
    return 1;
  }
  if (nwght) {
    if (nout==nwght) {
      biffAddf(NRRD, "%s: nout==nwght disallowed", me);
      return 1;
    }
    if (nrrdTypeBlock == nwght->type) {
      biffAddf(NRRD, "%s: nwght type %s invalid", me,
               airEnumStr(nrrdType, nrrdTypeBlock));
      return 1;
    }
    if (!nrrdSameSize(nin, nwght, AIR_TRUE)) {
      biffAddf(NRRD, "%s: nwght size mismatch with nin", me);
      return 1;
    }
    lup = nrrdDLookup[nwght->type];
  } else {
    lup = NULL;
  }

  if (nrrdMaybeAlloc_va(nout, type, 1, bins)) {
    biffAddf(NRRD, "%s: failed to alloc histo array (len " _AIR_SIZE_T_CNV
             ")", me, bins);
    return 1;
  }
  mop = airMopNew();
  /* nout->axis[0].size set */
  nout->axis[0].spacing = AIR_NAN;
  nout->axis[0].thickness = AIR_NAN;
  if (nout && AIR_EXISTS(nout->axis[0].min) && AIR_EXISTS(nout->axis[0].max)) {
    /* HEY: total hack to externally nail down min and max of histogram:
       use the min and max already set on axis[0] */
    /* HEY: shouldn't this blatent hack be further restricted by also 
       checking the existence of range->min and range->max ? */
    min = nout->axis[0].min;
    max = nout->axis[0].max;
  } else {
    if (_range) {
      range = nrrdRangeCopy(_range);
      nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
    } else {
      range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeState);
    }
    airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
    min = range->min;
    max = range->max;
    nout->axis[0].min = min;
    nout->axis[0].max = max;
  }
  eps = (min == max ? 1.0 : 0.0);
  nout->axis[0].center = nrrdCenterCell;
  /* nout->axis[0].label set below */
  
  /* make histogram */
  num = nrrdElementNumber(nin);
  for (I=0; I<num; I++) {
    val = nrrdDLookup[nin->type](nin->data, I);
    if (AIR_EXISTS(val)) {
      if (val < min || val > max+eps) {
        /* value is outside range; ignore it */
        continue;
      }
      if (AIR_IN_CL(min, val, max)) {
        idx = airIndex(min, val, max+eps, AIR_CAST(unsigned int, bins));
        /*
        printf("!%s: %d: index(%g, %g, %g, %d) = %d\n", 
               me, (int)I, min, val, max, bins, idx);
        */
        /* count is a double in order to simplify clamping the
           hit values to the representable range for nout->type */
        count = nrrdDLookup[nout->type](nout->data, idx);
        incr = nwght ? lup(nwght->data, I) : 1;
        count = nrrdDClamp[nout->type](count + incr);
        nrrdDInsert[nout->type](nout->data, idx, count);
      }
    }
  }

  if (nrrdContentSet_va(nout, func, nin, "%d", bins)) {
    biffAddf(NRRD, "%s:", me);
    airMopError(mop); return 1;
  }
  nout->axis[0].label = (char *)airFree(nout->axis[0].label);
  nout->axis[0].label = (char *)airStrdup(nout->content);
  if (!nrrdStateKindNoop) {
    nout->axis[0].kind = nrrdKindDomain;
  }

  airMopOkay(mop);
  return 0;
}
Пример #4
0
int
main(int argc, const char *argv[]) {
  const char *me;
  hestOpt *hopt;
  hestParm *hparm;
  airArray *mop;

  char **ninStr, *err, *outS, doneStr[13];
  Nrrd *nin0, *nin, *nrgb, *nout, *nhist[2], *npreout, *nhproj[3];
  float *rgb;
  float *out, *preout, *hist[2], maxSum,
    upSample, overSampleScale;
  unsigned int size0, sX, sY, sH, ninLen, ti, overSampleNum;
  NrrdResampleContext *rsmc;
  NrrdKernelSpec *ksp;

  me = argv[0];
  mop = airMopNew();
  hopt = NULL;
  hparm = hestParmNew();
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  hparm->respFileEnable = AIR_TRUE;
  hestOptAdd(&hopt, "i", "images", airTypeString, 1, -1, &ninStr, NULL,
             "input image sequence", &ninLen, NULL, NULL);
  hestOptAdd(&hopt, "sh", "histo size", airTypeUInt, 1, 1, &sH, "500",
             "histogram size");
  hestOptAdd(&hopt, "k", "kern", airTypeOther, 1, 1, &ksp,
             "tent", "kernel for upsampling images",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "us", "upsampling", airTypeFloat, 1, 1, &upSample,
             "1", "amount of upsampling of image");
  hestOptAdd(&hopt, "osn", "# oversmp", airTypeUInt, 1, 1, &overSampleNum,
             "1", "number of sample per (upsampled) pixel");
  hestOptAdd(&hopt, "osc", "scaling", airTypeFloat, 1, 1, &overSampleScale,
             "1", "scaling with oversampling");
  hestOptAdd(&hopt, "ms", "max sum", airTypeFloat, 1, 1, &maxSum,
             "10", "per-hue histogram summation is non-linearly and "
             "asymptotically clamped to this maximum");
  hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-",
             "output filename", NULL);

  hestParseOrDie(hopt, argc-1, argv+1, hparm,
                 me, mchistInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  if (0 == overSampleNum) {
    fprintf(stderr, "%s: overSampleNum must be > 0\n", me);
    airMopError(mop);
    return 1;
  }
  nin0 = nrrdNew();
  airMopAdd(mop, nin0, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdLoad(nin0, ninStr[0], NULL)) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: couldn't load first image:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  if (!( (3 == nin0->axis[0].size || 4 == nin0->axis[0].size)
         && 3 == nin0->dim
         && nrrdTypeUChar == nin0->type )) {
    fprintf(stderr, "%s: 1st image not 3D (3-or-4)-by-X-by-Y %s array "
            "(got %u-D %s array)\n", me,
            airEnumStr(nrrdType, nrrdTypeUChar),
            nin0->dim,
            airEnumStr(nrrdType, nin0->type));
    airMopError(mop);
    return 1;
  }
  rsmc = nrrdResampleContextNew();
  airMopAdd(mop, rsmc, (airMopper)nrrdResampleContextNix, airMopAlways);
  size0 = AIR_CAST(unsigned int, nin0->axis[0].size);
  sX = AIR_CAST(unsigned int, upSample*nin0->axis[1].size);
  sY = AIR_CAST(unsigned int, upSample*nin0->axis[2].size);
  nrgb = nrrdNew();
  airMopAdd(mop, nrgb, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdResampleDefaultCenterSet(rsmc, nrrdCenterCell)
      || nrrdResampleInputSet(rsmc, nin0)
      || nrrdResampleKernelSet(rsmc, 1, ksp->kernel, ksp->parm)
      || nrrdResampleKernelSet(rsmc, 2, ksp->kernel, ksp->parm)
      || nrrdResampleSamplesSet(rsmc, 1, sX)
      || nrrdResampleSamplesSet(rsmc, 2, sY)
      || nrrdResampleRangeFullSet(rsmc, 1)
      || nrrdResampleRangeFullSet(rsmc, 2)
      || nrrdResampleTypeOutSet(rsmc, nrrdTypeFloat)
      || nrrdResampleRenormalizeSet(rsmc, AIR_TRUE)
      || nrrdResampleExecute(rsmc, nrgb)) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error resampling slice:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  nhist[0] = nrrdNew();
  airMopAdd(mop, nhist[0], (airMopper)nrrdNuke, airMopAlways);
  nhist[1] = nrrdNew();
  airMopAdd(mop, nhist[1], (airMopper)nrrdNuke, airMopAlways);
  if (nrrdMaybeAlloc_va(nhist[0], nrrdTypeFloat, 2,
                        AIR_CAST(size_t, sH),
                        AIR_CAST(size_t, sH))
      || nrrdMaybeAlloc_va(nhist[1], nrrdTypeFloat, 2,
                           AIR_CAST(size_t, sH),
                           AIR_CAST(size_t, sH))) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error allocating histos:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  nhist[0]->axis[0].min = nhist[0]->axis[1].min = 0.0;
  nhist[0]->axis[0].max = nhist[0]->axis[1].max = 1.0;
  nhist[1]->axis[0].min = nhist[1]->axis[1].min = 0.0;
  nhist[1]->axis[0].max = nhist[1]->axis[1].max = 1.0;
  nhproj[0] = nrrdNew();
  airMopAdd(mop, nhproj[0], (airMopper)nrrdNix, airMopAlways);
  nhproj[1] = nrrdNew();
  airMopAdd(mop, nhproj[1], (airMopper)nrrdNix, airMopAlways);
  nhproj[2] = nrrdNew();
  airMopAdd(mop, nhproj[2], (airMopper)nrrdNix, airMopAlways);

  printf("working ...       ");
  hist[0] = AIR_CAST(float *, nhist[0]->data);
  hist[1] = AIR_CAST(float *, nhist[1]->data);
  nin = nrrdNew();
  airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways);
  npreout = nrrdNew();
  airMopAdd(mop, npreout, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdMaybeAlloc_va(npreout, nrrdTypeFloat, 3,
                        AIR_CAST(size_t, 3),
                        AIR_CAST(size_t, sH),
                        AIR_CAST(size_t, ninLen))) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error allocating pre-output:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  preout = AIR_CAST(float *, npreout->data);
  for (ti=0; ti<ninLen; ti++) {
    printf("%s", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout);
    if (nrrdLoad(nin, ninStr[ti], NULL)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: couldn't load image[%u]:\n%s", me, ti, err);
      airMopError(mop);
      return 1;
    }
    if (!nrrdSameSize(nin0, nin, AIR_TRUE)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: nin[%u] not like nin[0]:\n%s", me, ti, err);
      airMopError(mop);
      return 1;
    }
    if (nrrdResampleInputSet(rsmc, nin)
        || nrrdResampleExecute(rsmc, nrgb)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble resampling nin[%u]:\n%s", me, ti, err);
      airMopError(mop);
      return 1;
    }
    if (nrrdWrap_va(nhproj[0], preout + 0*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) ||
        nrrdWrap_va(nhproj[1], preout + 1*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) ||
        nrrdWrap_va(nhproj[2], preout + 2*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH))) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble wrapping output[%u]:\n%s", me, ti, err);
      airMopError(mop);
      return 1;
    }
    rgb = AIR_CAST(float *, nrgb->data);
    imageProc(nhproj, nhist, sH,
              rgb, size0, sX*sY,
              overSampleNum, overSampleScale);
    preout += 3*sH;
  }
  printf("%s\n", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdMaybeAlloc_va(nout, nrrdTypeFloat, 3,
                        AIR_CAST(size_t, 3),
                        AIR_CAST(size_t, sH),
                        AIR_CAST(size_t, ninLen))) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error allocating output:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  out = AIR_CAST(float *, nout->data);
  preout = AIR_CAST(float *, npreout->data);
  for (ti=0; ti<ninLen; ti++) {
    unsigned int hi;
    float hh, vv, ss, scl;
    for (hi=0; hi<sH; hi++) {
      hh = AIR_AFFINE(0, hi, sH, 0, 1);
      if (!preout[hi + 2*sH]) {
        ELL_3V_SET(out + 3*hi, 0, 0, 0);
      } else {
        ss = preout[hi + 2*sH];
        scl = ss/(maxSum + ss);
        vv = scl*preout[hi + 1*sH];
        dyeHSVtoRGB(out + 0 + 3*hi, out + 1 + 3*hi, out + 2 + 3*hi,
                    hh, preout[hi + 0*sH], vv);
      }
    }
    out += 3*sH;
    preout += 3*sH;
  }

  if (nrrdSave(outS, nout, NULL)) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error saving output:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  airMopOkay(mop);
  return 0;
}