Beispiel #1
0
int
main(int argc, char *argv[]) {
  char *me;
  hestOpt *hopt = NULL;
  int center;
  double minPos, maxPos, pos, index, size;

  me = argv[0];
  hestOptAdd(&hopt, NULL, "center", airTypeEnum, 1, 1, &center, NULL,
             "which centering applies to the quantized position.\n "
             "Possibilities are:\n "
             "\b\bo \"cell\": for histogram bins, quantized values, and "
             "pixels-as-squares\n "
             "\b\bo \"node\": for non-trivially interpolated "
             "sample points", NULL, nrrdCenter);
  hestOptAdd(&hopt, NULL, "minPos", airTypeDouble, 1, 1, &minPos, NULL,
             "smallest position associated with index 0");
  hestOptAdd(&hopt, NULL, "maxPos", airTypeDouble, 1, 1, &maxPos, NULL,
             "highest position associated with highest index");
  hestOptAdd(&hopt, NULL, "num", airTypeDouble, 1, 1, &size, NULL,
             "number of intervals into which position has been quantized");
  hestOptAdd(&hopt, NULL, "pos", airTypeDouble, 1, 1, &pos, NULL,
             "the input position, to be converted to an index");
  hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info,
                 AIR_TRUE, AIR_TRUE, AIR_TRUE);

  index = NRRD_IDX(center, minPos, maxPos, size, pos);
  printf("%g\n", index);
  
  hestParseFree(hopt);
  hestOptFree(hopt);
  exit(0);
}
Beispiel #2
0
/*
******** nrrdAxisInfoIdx()
** 
** given a nrrd, an axis, and a (floating point) world space position,
** return the index implied the axis's min, max, and center.
** Does the opposite of nrrdAxisPos().
**
** does not use biff
*/
double
nrrdAxisInfoIdx(const Nrrd *nrrd, unsigned int ax, double pos) {
  int center;
  size_t size;
  double min, max;
  
  if (!( nrrd && ax <= nrrd->dim-1 )) {
    return AIR_NAN;
  }
  center = _nrrdCenter(nrrd->axis[ax].center);
  min = nrrd->axis[ax].min;
  max = nrrd->axis[ax].max;
  size = nrrd->axis[ax].size;

  return NRRD_IDX(center, min, max, size, pos);
}
Beispiel #3
0
int
unrrdu_w2iMain(int argc, const char **argv, const char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  airArray *mop;
  int pret;
  char *err;

  int center;
  double minPos, maxPos, pos, indx, size;

  mop = airMopNew();
  hestOptAdd(&opt, NULL, "center", airTypeEnum, 1, 1, &center, NULL,
             "which centering applies to the quantized position.\n "
             "Possibilities are:\n "
             "\b\bo \"cell\": for histogram bins, quantized values, and "
             "pixels-as-squares\n "
             "\b\bo \"node\": for non-trivially interpolated "
             "sample points", NULL, nrrdCenter);
  hestOptAdd(&opt, NULL, "minPos", airTypeDouble, 1, 1, &minPos, NULL,
             "smallest position associated with index 0");
  hestOptAdd(&opt, NULL, "maxPos", airTypeDouble, 1, 1, &maxPos, NULL,
             "highest position associated with highest index");
  hestOptAdd(&opt, NULL, "num", airTypeDouble, 1, 1, &size, NULL,
             "number of intervals into which position has been quantized");
  hestOptAdd(&opt, NULL, "world", airTypeDouble, 1, 1, &pos, NULL,
             "the input world position, to be converted to index");
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);
  USAGE(_unrrdu_w2iInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  indx = NRRD_IDX(center, minPos, maxPos, size, pos);
  printf("%g\n", indx);

  airMopOkay(mop);
  return 0;
}
Beispiel #4
0
/*
** _nrrdResampleMakeWeightIndex()
**
** _allocate_ and fill the arrays of indices and weights that are
** needed to process all the scanlines along a given axis; also
** be so kind as to set the sampling ratio (<1: downsampling,
** new sample spacing larger, >1: upsampling, new sample spacing smaller)
**
** returns "dotLen", the number of input samples which are required
** for resampling this axis, or 0 if there was an error.  Uses biff.
*/
int
_nrrdResampleMakeWeightIndex(nrrdResample_t **weightP,
                             int **indexP, double *ratioP,
                             const Nrrd *nin, const NrrdResampleInfo *info,
                             unsigned int ai) {
  char me[]="_nrrdResampleMakeWeightIndex", err[BIFF_STRLEN];
  int sizeIn, sizeOut, center, dotLen, halfLen, *index, base, idx;
  nrrdResample_t minIn, maxIn, minOut, maxOut, spcIn, spcOut,
    ratio, support, integral, pos, idxD, wght;
  nrrdResample_t *weight;
  double parm[NRRD_KERNEL_PARMS_NUM];

  int e, i;

  if (!(info->kernel[ai])) {
    sprintf(err, "%s: don't see a kernel for dimension %d", me, ai);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  center = _nrrdCenter(nin->axis[ai].center);
  sizeIn = nin->axis[ai].size;
  sizeOut = info->samples[ai];
  minIn = AIR_CAST(nrrdResample_t, nin->axis[ai].min);
  maxIn = AIR_CAST(nrrdResample_t, nin->axis[ai].max);
  minOut = AIR_CAST(nrrdResample_t, info->min[ai]);
  maxOut = AIR_CAST(nrrdResample_t, info->max[ai]);
  spcIn = NRRD_SPACING(center, minIn, maxIn, sizeIn);
  spcOut = NRRD_SPACING(center, minOut, maxOut, sizeOut);
  *ratioP = ratio = spcIn/spcOut;
  support = AIR_CAST(nrrdResample_t,
                     info->kernel[ai]->support(info->parm[ai]));
  integral = AIR_CAST(nrrdResample_t,
                      info->kernel[ai]->integral(info->parm[ai]));
  /*
  fprintf(stderr, 
          "!%s(%d): size{In,Out} = %d, %d, support = %f; ratio = %f\n", 
          me, d, sizeIn, sizeOut, support, ratio);
  */
  if (ratio > 1) {
    /* if upsampling, we need only as many samples as needed for
       interpolation with the given kernel */
    dotLen = (int)(2*ceil(support));
  } else {
    /* if downsampling, we need to use all the samples covered by
       the stretched out version of the kernel */
    if (info->cheap) {
      dotLen = (int)(2*ceil(support));
    } else {
      dotLen = (int)(2*ceil(support/ratio));
    }
  }
  /*
  fprintf(stderr, "!%s(%d): dotLen = %d\n", me, d, dotLen);
  */

  weight = (nrrdResample_t*)calloc(sizeOut*dotLen, sizeof(nrrdResample_t));
  index = (int*)calloc(sizeOut*dotLen, sizeof(int));
  if (!(weight && index)) {
    sprintf(err, "%s: can't allocate weight and index arrays", me);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  /* calculate sample locations and do first pass on indices */
  halfLen = dotLen/2;
  for (i=0; i<sizeOut; i++) {
    pos = AIR_CAST(nrrdResample_t,
                   NRRD_POS(center, minOut, maxOut, sizeOut, i));
    idxD = AIR_CAST(nrrdResample_t,
                    NRRD_IDX(center, minIn, maxIn, sizeIn, pos));
    base = (int)floor(idxD) - halfLen + 1;
    for (e=0; e<dotLen; e++) {
      index[e + dotLen*i] = base + e;
      weight[e + dotLen*i] = idxD - index[e + dotLen*i];
    }
    /* ********
    if (!i) {
      fprintf(stderr, "%s: sample locations:\n", me);
    }
    fprintf(stderr, "%s: %d (sample locations)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
    ******** */
  }

  /*
  nrrdBoundaryPad,      1: fill with some user-specified value
  nrrdBoundaryBleed,    2: copy the last/first value out as needed
  nrrdBoundaryWrap,     3: wrap-around
  nrrdBoundaryWeight,   4: normalize the weighting on the existing samples;
                        ONLY sensible for a strictly positive kernel
                        which integrates to unity (as in blurring)
  */

  /* figure out what to do with the out-of-range indices */
  for (i=0; i<dotLen*sizeOut; i++) {
    idx = index[i];
    if (!AIR_IN_CL(0, idx, sizeIn-1)) {
      switch(info->boundary) {
      case nrrdBoundaryPad:
      case nrrdBoundaryWeight:  /* this will be further handled later */
        idx = sizeIn;
        break;
      case nrrdBoundaryBleed:
        idx = AIR_CLAMP(0, idx, sizeIn-1);
        break;
      case nrrdBoundaryWrap:
        idx = AIR_MOD(idx, sizeIn);
        break;
      default:
        sprintf(err, "%s: boundary behavior %d unknown/unimplemented", 
                me, info->boundary);
        biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
      }
      index[i] = idx;
    }
  }

  /* run the sample locations through the chosen kernel.  We play a 
     sneaky trick on the kernel parameter 0 in case of downsampling
     to create the blurring of the old index space, but only if !cheap */
  memcpy(parm, info->parm[ai], NRRD_KERNEL_PARMS_NUM*sizeof(double));
  if (ratio < 1 && !(info->cheap)) {
    parm[0] /= ratio;
  }
  info->kernel[ai]->EVALN(weight, weight, dotLen*sizeOut, parm);

  /* ********
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d (sample weights)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
  }
  ******** */

  if (nrrdBoundaryWeight == info->boundary) {
    if (integral) {
      /* above, we set to sizeIn all the indices that were out of 
         range.  We now use that to determine the sum of the weights
         for the indices that were in-range */
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          if (sizeIn != index[e + dotLen*i]) {
            wght += weight[e + dotLen*i];
          }
        }
        for (e=0; e<dotLen; e++) {
          idx = index[e + dotLen*i];
          if (sizeIn != idx) {
            weight[e + dotLen*i] *= integral/wght;
          } else {
            weight[e + dotLen*i] = 0;
          }
        }
      }
    }
  } else {
    /* try to remove ripple/grating on downsampling */
    /* if (ratio < 1 && info->renormalize && integral) { */
    if (info->renormalize && integral) {
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          wght += weight[e + dotLen*i];
        }
        if (wght) {
          for (e=0; e<dotLen; e++) {
            /* this used to normalize the weights so that they summed
               to integral ("*= integral/wght"), which meant that if
               you use a very truncated Gaussian, then your over-all
               image brightness goes down.  This seems very contrary
               to the whole point of renormalization. */
            weight[e + dotLen*i] *= AIR_CAST(nrrdResample_t, 1.0/wght);
          }
        }
      }
    }
  }
  /* ********
  fprintf(stderr, "%s: sample weights:\n", me);
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d\n        ", me, i);
    wght = 0;
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
      wght += weight[e + dotLen*i];
    }
    fprintf(stderr, " (sum = %g)\n", wght);
  }
  ******** */

  *weightP = weight;
  *indexP = index;
  /*
  fprintf(stderr, "!%s: dotLen = %d\n", me, dotLen);
  */
  return dotLen;
}
int
mossLinearTransform (Nrrd *nout, Nrrd *nin, float *bg,
                     double *mat, mossSampler *msp,
                     double xMin, double xMax,
                     double yMin, double yMax,
                     int xSize, int ySize) {
  char me[]="mossLinearTransform", err[BIFF_STRLEN];
  int ncol, xi, yi, ci, ax0, xCent, yCent;
  float *val, (*ins)(void *v, size_t I, float f), (*clamp)(float val);
  double inv[6], xInPos, xOutPos, yInPos, yOutPos;

  if (!(nout && nin && mat && msp && !mossImageCheck(nin))) {
    sprintf(err, "%s: got NULL pointer or bad image", me);
    biffAdd(MOSS, err); return 1;
  }
  if (mossSamplerImageSet(msp, nin, bg) || mossSamplerUpdate(msp)) {
    sprintf(err, "%s: trouble with sampler", me);
    biffAdd(MOSS, err); return 1;
  }
  if (!( xMin != xMax && yMin != yMax && xSize > 1 && ySize > 1 )) {
    sprintf(err, "%s: bad args: {x,y}Min == {x,y}Max or {x,y}Size <= 1", me);
    biffAdd(MOSS, err); return 1;
  }
  ax0 = MOSS_AXIS0(nin);
  if (!( AIR_EXISTS(nin->axis[ax0+0].min)
         && AIR_EXISTS(nin->axis[ax0+0].max)
         && AIR_EXISTS(nin->axis[ax0+1].min)
         && AIR_EXISTS(nin->axis[ax0+1].max) )) {
    sprintf(err, "%s: input axis min,max not set on axes %d and %d", me,
            ax0+0, ax0+1); biffAdd(MOSS, err); return 1;
  }

  ncol = MOSS_NCOL(nin);
  if (mossImageAlloc(nout, nin->type, xSize, ySize, ncol)) {
    sprintf(err, "%s: ", me); biffAdd(MOSS, err); return 1;
  }
  val = (float*)calloc(ncol, sizeof(float));
  if (nrrdCenterUnknown == nout->axis[ax0+0].center)
    nout->axis[ax0+0].center = _mossCenter(nin->axis[ax0+0].center);
  xCent = nout->axis[ax0+0].center;
  if (nrrdCenterUnknown == nout->axis[ax0+1].center)
    nout->axis[ax0+1].center = _mossCenter(nin->axis[ax0+1].center);
  yCent = nout->axis[ax0+1].center;
  nout->axis[ax0+0].min = xMin;
  nout->axis[ax0+0].max = xMax;
  nout->axis[ax0+1].min = yMin;
  nout->axis[ax0+1].max = yMax;
  ins = nrrdFInsert[nin->type];
  clamp = nrrdFClamp[nin->type];
  
  if (mossSamplerSample(val, msp, 0, 0)) {
    sprintf(err, "%s: trouble in sampler", me);
    free(val); biffAdd(MOSS, err); return 1;
  }

  mossMatInvert(inv, mat);
  for (yi=0; yi<ySize; yi++) {
    yOutPos = NRRD_POS(yCent, yMin, yMax, ySize, yi);
    for (xi=0; xi<xSize; xi++) {
      /*
      mossVerbose = ( (36 == xi && 72 == yi) ||
                      (37 == xi && 73 == yi) ||
                      (105 == xi && 175 == yi) );
      */
      xOutPos = NRRD_POS(xCent, xMin, xMax, xSize, xi);
      mossMatApply(&xInPos, &yInPos, inv, xOutPos, yOutPos);
      xInPos = NRRD_IDX(xCent, nin->axis[ax0+0].min, nin->axis[ax0+0].max,
                        nin->axis[ax0+0].size, xInPos);
      yInPos = NRRD_IDX(yCent, nin->axis[ax0+1].min, nin->axis[ax0+1].max,
                        nin->axis[ax0+1].size, yInPos);
      mossSamplerSample(val, msp, xInPos, yInPos);
      for (ci=0; ci<ncol; ci++) {
        ins(nout->data, ci + ncol*(xi + xSize*yi), clamp(val[ci]));
      }
    }
  }

  free(val);
  return 0;
}