Ejemplo n.º 1
0
int
unrrdu_minmaxDoit(char *me, char *inS, int blind8BitRange, FILE *fout) {
  char err[BIFF_STRLEN];
  Nrrd *nrrd;
  NrrdRange *range;
  airArray *mop;

  mop = airMopNew();
  airMopAdd(mop, nrrd=nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  if (nrrdLoad(nrrd, inS, NULL)) {
    sprintf(err, "%s: trouble loading \"%s\"", me, inS);
    biffMove(me, err, NRRD); airMopError(mop); return 1;
  }

  range = nrrdRangeNewSet(nrrd, blind8BitRange);
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  airSinglePrintf(fout, NULL, "min: %g\n", range->min);
  airSinglePrintf(fout, NULL, "max: %g\n", range->max);
  if (0 == range->min && 0 == range->max) {
    fprintf(fout, "# min == max == 0.0 exactly\n");
  }
  if (range->hasNonExist) {
    fprintf(fout, "# has non-existent values\n");
  }

  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 2
0
int
main(int argc, char **argv) {
  char *me, *err;
  Nrrd *nrrd;
  NrrdRange *range;

  me = argv[0];
  if (2 != argc)
    usage(me);

  nrrdStateVerboseIO = 10;
  
  if (nrrdLoad(nrrd=nrrdNew(), argv[1], NULL)) {
    fprintf(stderr, "%s: trouble loading \"%s\":\n%s", 
            me, argv[1], err = biffGet(NRRD));
    free(err);
    exit(1);
  }

  range = nrrdRangeNewSet(nrrd, nrrdBlind8BitRangeState);

  printf("%s: min = %g; max = %g, hasNonExist = %d\n", me,
         range->min, range->max, range->hasNonExist);

  nrrdNuke(nrrd);

  exit(0);
}
Ejemplo n.º 3
0
int
nrrdApplyMulti1DRegMap(Nrrd *nout, const Nrrd *nin,
                       const NrrdRange *_range, const Nrrd *nmmap,
                       int typeOut, int rescale) {
  char me[]="nrrdApplyMulti1DRegMap", err[BIFF_STRLEN];
  NrrdRange *range;
  airArray *mop;

  if (!(nout && nmmap && nin)) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err); return 1;
  }
  mop = airMopNew();
  if (_range) {
    range = nrrdRangeCopy(_range);
    nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
  } else {
    range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeState);
  }
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  if (_nrrdApply1DSetUp(nout, nin, range, nmmap, kindRmap, typeOut,
                        rescale, AIR_TRUE)
      || _nrrdApply1DLutOrRegMap(nout, nin, range, nmmap, AIR_TRUE,
                                 rescale, AIR_TRUE)) {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err); airMopError(mop); return 1;
  }
  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 4
0
int main(int argc, char * argv[])
{
	Nrrd *nin = nrrdNew();
	Nrrd *nquantized = nrrdNew();
	char *biffErr;

	if(argc < 4) {
		fprintf(stderr,"Usage: %s centerx centery nrrd\n",argv[0]);
		return 1;
	}

	cx = atoi(argv[1]);
	cy = atoi(argv[2]);

	if(nrrdLoad(nin, argv[3], NULL)) {
		biffErr = biffGetDone(NRRD);
		fprintf(stderr, "Error reading file: %s\n", biffErr);
		free(biffErr);
		return 1;
	}

	printf("Read %d-dimensional nrrd of type %d (%s)\n",
			nin->dim, nin->type, airEnumStr(nrrdType, nin->type));

	printf("Axis dimensions: %d x %d x %d\n", nin->axis[0].size,
			nin->axis[1].size, nin->axis[2].size);

	NrrdRange *range = nrrdRangeNewSet(nin, 0);
	printf("min: %g\tmax: %g\n", range->min, range->max);

	if(nrrdQuantize(nquantized, nin, range, 8)) {
		biffErr = biffGetDone(NRRD);
		fprintf(stderr, "Error quantizing: %s\n", biffErr);
		return 1;
	}

	process_slices(nquantized);

	nrrdRangeNix(range);
	nrrdNuke(nin);
	nrrdNuke(nquantized);

	return 0;
}
Ejemplo n.º 5
0
int
baneGkms_scatMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out[2], *perr, err[BIFF_STRLEN];
  Nrrd *hvol, *nvgRaw, *nvhRaw, *nvgQuant, *nvhQuant;
  NrrdRange *vgRange, *vhRange;
  airArray *mop;
  int pret, E;
  double gamma;

  hestOptAdd(&opt, "g", "gamma", airTypeDouble, 1, 1, &gamma, "1.0",
             "gamma used to brighten/darken scatterplots. "
             "gamma > 1.0 brightens; gamma < 1.0 darkens. "
             "Negative gammas invert values (like in xv). ");
  hestOptAdd(&opt, "i", "hvolIn", airTypeOther, 1, 1, &hvol, NULL,
             "input histogram volume (from \"gkms hvol\")",
             NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&opt, "o", "vgOut vhOut", airTypeString, 2, 2, out, NULL,
             "Filenames to use for two output scatterplots, (gradient "
             "magnitude versus value, and 2nd derivative versus value); "
             "can use PGM or PNG format");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);
  USAGE(_baneGkms_scatInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  nvgRaw = nrrdNew();
  nvhRaw = nrrdNew();
  nvgQuant = nrrdNew();
  nvhQuant = nrrdNew();
  airMopAdd(mop, nvgRaw, (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, nvhRaw, (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, nvgQuant, (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, nvhQuant, (airMopper)nrrdNuke, airMopAlways);
  if (baneRawScatterplots(nvgRaw, nvhRaw, hvol, AIR_TRUE)) {
    sprintf(err, "%s: trouble creating raw scatterplots", me);
    biffAdd(BANE, err); airMopError(mop); return 1;
  }
  vgRange = nrrdRangeNewSet(nvgRaw, nrrdBlind8BitRangeFalse);
  vhRange = nrrdRangeNewSet(nvhRaw, nrrdBlind8BitRangeFalse);
  airMopAdd(mop, vgRange, (airMopper)nrrdRangeNix, airMopAlways);
  airMopAdd(mop, vhRange, (airMopper)nrrdRangeNix, airMopAlways);
  E = 0;
  if (!E) E |= nrrdArithGamma(nvgRaw, nvgRaw, vgRange, gamma);
  if (!E) E |= nrrdArithGamma(nvhRaw, nvhRaw, vhRange, gamma);
  if (!E) E |= nrrdQuantize(nvgQuant, nvgRaw, vgRange, 8);
  if (!E) E |= nrrdQuantize(nvhQuant, nvhRaw, vhRange, 8);
  if (E) {
    sprintf(err, "%s: trouble doing gamma or quantization", me);
    biffMove(BANE, err, NRRD); airMopError(mop); return 1;
  }

  if (!E) E |= nrrdSave(out[0], nvgQuant, NULL);
  if (!E) E |= nrrdSave(out[1], nvhQuant, NULL);
  if (E) {
    sprintf(err, "%s: trouble saving scatterplot images", me);
    biffMove(BANE, err, NRRD); airMopError(mop); return 1;
  }

  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 6
0
int
main(int argc, const char **argv) {
  const char *me;
  char *err;
  hestOpt *hopt=NULL;
  hestParm *hparm;
  airArray *mop;

  /* variables learned via hest */
  Nrrd *nin;
  float camfr[3], camat[3], camup[3], camnc, camfc, camFOV;
  int camortho, hitandquit;
  unsigned int camsize[2];
  double isovalue, sliso, isomin, isomax;

  /* boilerplate hest code */
  me = argv[0];
  mop = airMopNew();
  hparm = hestParmNew();
  hparm->respFileEnable = AIR_TRUE;
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  /* setting up the command-line options */
  hparm->respFileEnable = AIR_TRUE;
  hestOptAdd(&hopt, "i", "volume", airTypeOther, 1, 1, &nin, NULL,
             "input volume to isosurface", NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&hopt, "v", "isovalue", airTypeDouble, 1, 1, &isovalue, "nan",
             "isovalue at which to run Marching Cubes");
  hestOptAdd(&hopt, "fr", "x y z", airTypeFloat, 3, 3, camfr, "3 4 5",
             "look-from point");
  hestOptAdd(&hopt, "at", "x y z", airTypeFloat, 3, 3, camat, "0 0 0",
             "look-at point");
  hestOptAdd(&hopt, "up", "x y z", airTypeFloat, 3, 3, camup, "0 0 1",
             "up direction");
  hestOptAdd(&hopt, "nc", "dist", airTypeFloat, 1, 1, &(camnc), "-2",
             "at-relative near clipping distance");
  hestOptAdd(&hopt, "fc", "dist", airTypeFloat, 1, 1, &(camfc), "2",
             "at-relative far clipping distance");
  hestOptAdd(&hopt, "fov", "angle", airTypeFloat, 1, 1, &(camFOV), "20",
             "vertical field-of-view, in degrees. Full vertical "
             "extent of image plane subtends this angle.");
  hestOptAdd(&hopt, "sz", "s0 s1", airTypeUInt, 2, 2, &(camsize), "640 480",
             "# samples (horz vert) of image plane. ");
  hestOptAdd(&hopt, "ortho", NULL, airTypeInt, 0, 0, &(camortho), NULL,
             "use orthographic instead of (the default) "
             "perspective projection ");
  hestOptAdd(&hopt, "haq", NULL, airTypeBool, 0, 0, &(hitandquit), NULL,
             "save a screenshot rather than display the viewer");

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

  /* learn value range, and set initial isovalue if needed */
  NrrdRange *range = nrrdRangeNewSet(nin, AIR_FALSE);
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  isomin = range->min;
  isomax = range->max;
  if (!AIR_EXISTS(isovalue)) {
    isovalue = (isomin + isomax)/2;
  }

  /* first, make sure we can isosurface ok */
  limnPolyData *lpld = limnPolyDataNew();
  seekContext *sctx = seekContextNew();
  airMopAdd(mop, sctx, (airMopper)seekContextNix, airMopAlways);
  sctx->pldArrIncr = nrrdElementNumber(nin);
  seekVerboseSet(sctx, 0);
  seekNormalsFindSet(sctx, AIR_TRUE);
  if (seekDataSet(sctx, nin, NULL, 0)
      || seekTypeSet(sctx, seekTypeIsocontour)
      || seekIsovalueSet(sctx, isovalue)
      || seekUpdate(sctx)
      || seekExtract(sctx, lpld)) {
    airMopAdd(mop, err=biffGetDone(SEEK), airFree, airMopAlways);
    fprintf(stderr, "trouble with isosurfacing:\n%s", err);
    airMopError(mop);
    return 1;
  }
  if (!lpld->xyzwNum) {
    fprintf(stderr, "%s: warning: No isocontour generated at isovalue %g\n",
            me, isovalue);
  }

  /* then create empty scene */
  Hale::init();
  Hale::Scene scene;
  /* then create viewer (in order to create the OpenGL context) */
  Hale::Viewer viewer(camsize[0], camsize[1], "Iso", &scene);
  viewer.lightDir(glm::vec3(-1.0f, 1.0f, 3.0f));
  viewer.camera.init(glm::vec3(camfr[0], camfr[1], camfr[2]),
                     glm::vec3(camat[0], camat[1], camat[2]),
                     glm::vec3(camup[0], camup[1], camup[2]),
                     camFOV, (float)camsize[0]/camsize[1],
                     camnc, camfc, camortho);
  viewer.refreshCB((Hale::ViewerRefresher)render);
  viewer.refreshData(&viewer);
  sliso = isovalue;
  viewer.slider(&sliso, isomin, isomax);
  viewer.current();


  /* then create geometry, and add it to scene */
  Hale::Polydata hply(lpld, true,  // hply now owns lpld
                      Hale::ProgramLib(Hale::preprogramAmbDiff2SideSolid));
  scene.add(&hply);


  scene.drawInit();
  render(&viewer);
  if (hitandquit) {
    seekIsovalueSet(sctx, isovalue);
    seekUpdate(sctx);
    seekExtract(sctx, lpld);
    hply.rebuffer();

    render(&viewer);
    glfwWaitEvents();
    render(&viewer);
    viewer.snap();
    Hale::done();
    airMopOkay(mop);
    return 0;
  }
  while(!Hale::finishing){
    glfwWaitEvents();
    if (viewer.sliding() && sliso != isovalue) {
      isovalue = sliso;
      printf("%s: isosurfacing at %g\n", me, isovalue);
      seekIsovalueSet(sctx, isovalue);
      seekUpdate(sctx);
      seekExtract(sctx, lpld);
      hply.rebuffer();
    }
    render(&viewer);
  }

  /* clean exit; all okay */
  Hale::done();
  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 7
0
/*
******** nrrdApply1DIrregMap()
**
** Linear interpolation between irregularly spaced control points.
** Obviously, the location of the control point has to be given
** explicitly.  The map nrrd must have dimension 2, and each 
** control point is represented by a scanline along axis 0.  The
** first value is the position of the control point, and the remaining
** value(s) are linearly weighted according to the position of the
** input value among the control point locations.
**
** To allow "coloring" of non-existant values -inf, NaN, and +inf, if
** the very first value of the map (the location of the first control
** point) is non-existant, then the first three control point locations
** must be -inf, NaN, and +inf, in that order, and the information
** about these points will be used for corresponding input values.
** Doing this makes everything slower, however, because airFPClass_f()
** is called on every single value.
**
** This assumes that nrrd1DIrregMapCheck has been called on "nmap",
** and that nrrd1DIrregAclCheck has been called on "nacl" (if it is
** non-NULL).
*/
int
nrrdApply1DIrregMap(Nrrd *nout, const Nrrd *nin, const NrrdRange *_range,
                    const Nrrd *nmap, const Nrrd *nacl,
                    int typeOut, int rescale) {
  char me[]="nrrdApply1DIrregMap", err[BIFF_STRLEN];
  size_t N, I;
  int i, *acl, entLen, posLen, aclLen, mapIdx, aclIdx,
    entSize, colSize, inSize, lo, hi, baseI;
  double val, *pos, domMin, domMax, mapIdxFrac,
    (*mapLup)(const void *v, size_t I),
    (*inLoad)(const void *v), (*outInsert)(void *v, size_t I, double d);
  char *inData, *outData, *entData0, *entData1;
  NrrdRange *range;
  airArray *mop;

  if (!(nout && nmap && nin)) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err); return 1;
  }
  mop = airMopNew();
  if (_range) {
    range = nrrdRangeCopy(_range);
    nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
  } else {
    range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeState);
  }
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  if (_nrrdApply1DSetUp(nout, nin, range, nmap,
                        kindImap, typeOut, rescale, AIR_FALSE)) {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err); airMopError(mop); return 1;
  }
  if (nacl && nrrd1DIrregAclCheck(nacl)) {
    sprintf(err, "%s: given acl isn't valid", me);
    biffAdd(NRRD, err); airMopError(mop); return 1;
  }
  
  if (nacl) {
    acl = (int *)nacl->data;
    aclLen = nacl->axis[1].size;
  } else {
    acl = NULL;
    aclLen = 0;
  }
  pos = _nrrd1DIrregMapDomain(&posLen, &baseI, nmap);
  if (!pos) {
    sprintf(err, "%s: couldn't determine domain", me); 
    biffAdd(NRRD, err); airMopError(mop); return 1;
  }
  airMopAdd(mop, pos, airFree, airMopAlways);
  mapLup = nrrdDLookup[nmap->type];
  
  inData = (char *)nin->data;
  inLoad = nrrdDLoad[nin->type];
  inSize = nrrdElementSize(nin);
  mapLup = nrrdDLookup[nmap->type];
  entLen = nmap->axis[0].size;    /* entLen is really 1 + entry length */
  entSize = entLen*nrrdElementSize(nmap);
  colSize = (entLen-1)*nrrdTypeSize[typeOut];
  outData = (char *)nout->data;
  outInsert = nrrdDInsert[nout->type];
  domMin = pos[0];
  domMax = pos[posLen-1];
  
  N = nrrdElementNumber(nin);
  for (I=0;
       I<N;
       I++, inData += inSize, outData += colSize) {
    val = inLoad(inData);
    /* _VV = ( (AIR_EXISTS(val) && (21 == (int)(-val))) 
       || 22400 < I ); */
    /* if (_VV)
       fprintf(stderr, "##%s: (%d) val = % 31.15f\n", me, (int)I, val); */
    if (!AIR_EXISTS(val)) {
      /* got a non-existant value */
      if (baseI) {
        /* and we know how to deal with them */
        switch (airFPClass_d(val)) {
        case airFP_NEG_INF:
          mapIdx = 0;
          break;
        case airFP_SNAN:
        case airFP_QNAN:
          mapIdx = 1;
          break;
        case airFP_POS_INF:
          mapIdx = 2;
          break;
        default:
          mapIdx = 0;
          fprintf(stderr, "%s: PANIC: non-existant value/class %g/%d "
                  "not handled\n",
                  me, val, airFPClass_d(val));
          exit(1);
        }
        entData0 = (char*)(nmap->data) + mapIdx*entSize;
        for (i=1; i<entLen; i++) {
          outInsert(outData, i-1, mapLup(entData0, i));
        }
        continue;  /* we're done! (with this value) */
      } else {
        /* we don't know how to properly deal with this non-existant value:
           we use the first entry, and then fall through to code below */
        mapIdx = 0;
        mapIdxFrac = 0.0;
      }
    } else {
      /* we have an existant value */
      if (rescale) {
        val = AIR_AFFINE(range->min, val, range->max, domMin, domMax);
        /* if (_VV) fprintf(stderr, "   rescaled --> % 31.15f\n", val); */
      }
      val = AIR_CLAMP(domMin, val, domMax);
      if (acl) {
        aclIdx = airIndex(domMin, val, domMax, aclLen);
        lo = acl[0 + 2*aclIdx];
        hi = acl[1 + 2*aclIdx];
      } else {
        lo = 0;
        hi = posLen-2;
      }
      if (lo < hi) {
        mapIdx = _nrrd1DIrregFindInterval(pos, val, lo, hi);
      } else {
        /* acl did its job ==> lo == hi */
        mapIdx = lo;
      }
    }
    mapIdxFrac = AIR_AFFINE(pos[mapIdx], val, pos[mapIdx+1], 0.0, 1.0);
    /* if (_VV) fprintf(stderr, "##%s: val=\n% 31.15f --> "
                     "mapIdx,frac = %d,\n% 31.15f\n",
                     me, val, mapIdx, mapIdxFrac); */
    entData0 = (char*)(nmap->data) + (baseI+mapIdx)*entSize;
    entData1 = (char*)(nmap->data) + (baseI+mapIdx+1)*entSize;
    /* if (_VV) fprintf(stderr, "##%s: 2; %d/\n% 31.15f --> entLen=%d "
                     "baseI=%d -->\n",
                     me, mapIdx, mapIdxFrac, entLen, baseI); */
    for (i=1; i<entLen; i++) {
      val = ((1-mapIdxFrac)*mapLup(entData0, i) +
             mapIdxFrac*mapLup(entData1, i));
      /* if (_VV) fprintf(stderr, "% 31.15f\n", val); */
      outInsert(outData, i-1, val);
    }
    /* if (_VV) fprintf(stderr, "##%s: 3\n", me); */
  }
  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
/*
******** nrrdHistoAxis
**
** replace scanlines along one scanline with a histogram of the scanline
**
** 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
**
** By its very nature, and by the simplicity of this implemention,
** this can be a slow process due to terrible memory locality.  User
** may want to permute axes before and after this, but that can be
** slow too...  
*/
int
nrrdHistoAxis(Nrrd *nout, const Nrrd *nin, const NrrdRange *_range, 
              unsigned int hax, size_t bins, int type) {
  static const char me[]="nrrdHistoAxis", func[]="histax";
  int map[NRRD_DIM_MAX];
  unsigned int ai, hidx;
  size_t szIn[NRRD_DIM_MAX], szOut[NRRD_DIM_MAX], size[NRRD_DIM_MAX],
    coordIn[NRRD_DIM_MAX], coordOut[NRRD_DIM_MAX];
  size_t I, hI, num;
  double val, count;
  airArray *mop;
  NrrdRange *range;

  if (!(nin && nout)) {
    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 (!( hax <= nin->dim-1 )) {
    biffAddf(NRRD, "%s: axis %d is not in range [0,%d]",
             me, hax, nin->dim-1);
    return 1;
  }
  mop = airMopNew();
  if (_range) {
    range = nrrdRangeCopy(_range);
    nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
  } else {
    range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeState);
  }
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size);
  size[hax] = bins;
  if (nrrdMaybeAlloc_nva(nout, type, nin->dim, size)) {
    biffAddf(NRRD, "%s: failed to alloc output nrrd", me);
    airMopError(mop); return 1;
  }
  
  /* copy axis information */
  for (ai=0; ai<nin->dim; ai++) {
    map[ai] = ai != hax ? (int)ai : -1;
  }
  nrrdAxisInfoCopy(nout, nin, map, NRRD_AXIS_INFO_NONE);
  /* axis hax now has to be set manually */
  nout->axis[hax].size = bins;
  nout->axis[hax].spacing = AIR_NAN; /* min and max convey the information */
  nout->axis[hax].thickness = AIR_NAN;
  nout->axis[hax].min = range->min;
  nout->axis[hax].max = range->max;
  nout->axis[hax].center = nrrdCenterCell;
  if (nin->axis[hax].label) {
    nout->axis[hax].label = (char *)calloc(strlen("histax()")
                                           + strlen(nin->axis[hax].label)
                                           + 1, sizeof(char));
    if (nout->axis[hax].label) {
      sprintf(nout->axis[hax].label, "histax(%s)", nin->axis[hax].label);
    } else {
      biffAddf(NRRD, "%s: couldn't allocate output label", me);
      airMopError(mop); return 1;
    }
  } else {
    nout->axis[hax].label = NULL;
  }
  if (!nrrdStateKindNoop) {
    nout->axis[hax].kind = nrrdKindDomain;
  }

  /* the skinny: we traverse the input samples in linear order, and
     increment the bin in the histogram for the scanline we're in.
     This is not terribly clever, and the memory locality is a
     disaster */
  nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, szIn);
  nrrdAxisInfoGet_nva(nout, nrrdAxisInfoSize, szOut);
  memset(coordIn, 0, NRRD_DIM_MAX*sizeof(size_t));
  num = nrrdElementNumber(nin);
  for (I=0; I<num; I++) {
    /* get input nrrd value and compute its histogram index */
    val = nrrdDLookup[nin->type](nin->data, I);
    if (AIR_EXISTS(val) && AIR_IN_CL(range->min, val, range->max)) {
      hidx = airIndex(range->min, val, range->max, AIR_CAST(unsigned int, bins));
      memcpy(coordOut, coordIn, nin->dim*sizeof(size_t));
      coordOut[hax] = (unsigned int)hidx;
      NRRD_INDEX_GEN(hI, coordOut, szOut, nout->dim);
      count = nrrdDLookup[nout->type](nout->data, hI);
      count = nrrdDClamp[nout->type](count + 1);
      nrrdDInsert[nout->type](nout->data, hI, count);
    }
    NRRD_COORD_INCR(coordIn, szIn, nin->dim, 0);
  }
Ejemplo n.º 10
0
int
main(int argc, char *argv[]) {
  char *me, *outS;
  hestOpt *hopt;
  hestParm *hparm;
  airArray *mop;

  char *err;
  Nrrd *nin, *nhist;
  double vmin, vmax, rmax, val, cent[2], rad;
  int bins[2], sx, sy, xi, yi, ridx, hidx, rbins, hbins;
  NrrdRange *range;
  double (*lup)(const void *v, size_t I), *hist;
  
  me = argv[0];
  mop = airMopNew();
  hparm = hestParmNew();
  hopt = NULL;
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL,
             "input image", NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&hopt, "b", "rbins hbins", airTypeInt, 2, 2, bins, NULL,
             "# of histogram bins: radial and value");
  hestOptAdd(&hopt, "min", "value", airTypeDouble, 1, 1, &vmin, "nan",
             "Value at low end of histogram. Defaults to lowest value "
             "found in input nrrd.");
  hestOptAdd(&hopt, "max", "value", airTypeDouble, 1, 1, &vmax, "nan",
             "Value at high end of histogram. Defaults to highest value "
             "found in input nrrd.");
  hestOptAdd(&hopt, "rmax", "max radius", airTypeDouble, 1, 1, &rmax, "nan",
             "largest radius to include in histogram");
  hestOptAdd(&hopt, "c", "center x, y", airTypeDouble, 2, 2, cent, NULL,
             "The center point around which to build radial histogram");
  hestOptAdd(&hopt, "o", "filename", airTypeString, 1, 1, &outS, "-",
             "file to write histogram to");
  hestParseOrDie(hopt, argc-1, argv+1, hparm,
                 me, histradInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  if (2 != nin->dim) {
    fprintf(stderr, "%s: need 2-D input (not %d-D)\n", me, nin->dim);
    airMopError(mop); return 1;
  }

  rbins = bins[0];
  hbins = bins[1];
  nhist = nrrdNew();
  airMopAdd(mop, nhist, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdMaybeAlloc_va(nhist, nrrdTypeDouble, 2,
                        AIR_CAST(size_t, rbins),
                        AIR_CAST(size_t, hbins))) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: couldn't allocate histogram:\n%s", me, err);
    airMopError(mop); return 1;
  }

  if (!( AIR_EXISTS(vmin) && AIR_EXISTS(vmax) )) {
    range = nrrdRangeNewSet(nin, nrrdStateBlind8BitRange);
    airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
    vmin = AIR_EXISTS(vmin) ? vmin : range->min;
    vmax = AIR_EXISTS(vmax) ? vmax : range->max;
  }

#define DIST(x0, y0, x1, y1) (sqrt((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1)))

  sx = nin->axis[0].size;
  sy = nin->axis[1].size;
  if (!AIR_EXISTS(rmax)) {
    rmax = 0;
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, 0));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, 0));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, sy-1));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, sy-1));
  }
  
  lup = nrrdDLookup[nin->type];
  hist = (double*)(nhist->data);
  for (xi=0; xi<sx; xi++) {
    for (yi=0; yi<sy; yi++) {
      rad = DIST(cent[0], cent[1], xi, yi);
      if (!AIR_IN_OP(0, rad, rmax)) {
        continue;
      }
      val = lup(nin->data, xi + sx*yi);
      if (!AIR_IN_OP(vmin, val, vmax)) {
        continue;
      }
      ridx = airIndex(0, rad, rmax, rbins);
      hidx = airIndex(vmin, val, vmax, hbins);
      hist[ridx + rbins*hidx] += 1;
    }
  }
  
  nhist->axis[0].min = 0;
  nhist->axis[0].max = rmax;
  nhist->axis[1].min = vmin;
  nhist->axis[1].max = vmax;
  if (nrrdSave(outS, nhist, NULL)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: couldn't save output:\n%s", me, err);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  exit(0);
}
Ejemplo n.º 11
0
/*
******** nrrdArithGamma()
**
** map the values in a nrrd through a power function; essentially:
** val = pow(val, 1/gamma), but this is after the val has been normalized
** to be in the range of 0.0 to 1.0 (assuming that the given min and
** max really are the full range of the values in the nrrd).  Thus,
** the given min and max values are fixed points of this
** transformation.  Using a negative gamma means that after the pow()
** function has been applied, the value is inverted with respect to
** min and max (like in xv).
*/
int
nrrdArithGamma(Nrrd *nout, const Nrrd *nin,
               const NrrdRange *_range, double Gamma) {
  static const char me[]="nrrdArithGamma", func[]="gamma";
  double val, min, max;
  size_t I, num;
  NrrdRange *range;
  airArray *mop;
  double (*lup)(const void *, size_t);
  double (*ins)(void *, size_t, double);

  if (!(nout && nin)) {
    /* _range can be NULL */
    biffAddf(NRRD, "%s: got NULL pointer", me);
    return 1;
  }
  if (!( AIR_EXISTS(Gamma) )) {
    biffAddf(NRRD, "%s: gamma doesn't exist", me);
    return 1;
  }
  if (!( nrrdTypeBlock != nin->type && nrrdTypeBlock != nout->type )) {
    biffAddf(NRRD, "%s: can't deal with %s type", me,
             airEnumStr(nrrdType, nrrdTypeBlock));
    return 1;
  }
  if (nout != nin) {
    if (nrrdCopy(nout, nin)) {
      biffAddf(NRRD, "%s: couldn't initialize by copy to output", me);
      return 1;
    }
  }
  mop = airMopNew();
  if (_range) {
    range = nrrdRangeCopy(_range);
    nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
  } else {
    range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeTrue);
  }
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  min = range->min;
  max = range->max;
  if (min == max) {
    /* this is stupid.  We want min < max to avoid making NaNs */
    max += 1;
  }
  lup = nrrdDLookup[nin->type];
  ins = nrrdDInsert[nout->type];
  Gamma = 1/Gamma;
  num = nrrdElementNumber(nin);
  if (Gamma < 0.0) {
    Gamma = -Gamma;
    for (I=0; I<num; I++) {
      val = lup(nin->data, I);
      val = AIR_AFFINE(min, val, max, 0.0, 1.0);
      val = pow(val, Gamma);
      val = AIR_AFFINE(1.0, val, 0.0, min, max);
      ins(nout->data, I, val);
    }
  } else {
    for (I=0; I<num; I++) {
      val = lup(nin->data, I);
      val = AIR_AFFINE(min, val, max, 0.0, 1.0);
      val = pow(val, Gamma);
      val = AIR_AFFINE(0.0, val, 1.0, min, max);
      ins(nout->data, I, val);
    }
  }
  if (nrrdContentSet_va(nout, func, nin, "%g,%g,%g", min, max, Gamma)) {
    biffAddf(NRRD, "%s:", me);
    airMopError(mop); return 1;
  }
  if (nout != nin) {
    nrrdAxisInfoCopy(nout, nin, NULL, NRRD_AXIS_INFO_NONE);
  }
  /* basic info handled by nrrdCopy above */

  airMopOkay(mop);
  return 0;
}