00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "nrro.h"
00023 #include "nrroKernel.h"
00024 #include "nrroDispatch.h"
00025 #include <sstream>
00026 #include <typeinfo>
00027
00028 using namespace gutz;
00029 using namespace std;
00030
00031
00032
00033
00034 NrroSP Nrro::slice(int axis, int pos)
00035 {
00036 if(!_nrrd)
00037 return NrroSP();
00038
00039 if(!dim())
00040 return NrroSP();
00041
00042 Nrrd *nnew = nrrdNew();
00043
00044 if(_kind & PROXY)
00045 {
00046 nnew->dim = dim() - 1;
00047 int *axesC = new int[dim() -1];
00048 for(int i=0; i<axis; ++i)
00049 axesC[i] = i;
00050 for(int i=axis +1; i< int(dim()) -1; ++i)
00051 axesC[i-1] = i;
00052
00053
00054 nnew->data = 0;
00055 nnew->type = _nrrd->type;
00056 nrrdCommentCopy(nnew, _nrrd);
00057 }
00058 else if(nrrdSlice(nnew, _nrrd, axis, pos))
00059 {
00060 char *berr = biffGetDone(NRRD);
00061 NrroErr("slice(), failed", berr);
00062 nrrdNuke(nnew);
00063 return NrroSP();
00064 }
00065
00066 NrroSP nret(new Nrro(nnew));
00067 nret->setKind(nret->guessKind());
00068
00069 ostringstream ss;
00070 ss << _name << "_slc" << axis << "-" << pos;
00071 nret->_name = ss.str();
00072
00073 nret->setModified();
00074 nret->update();
00075 return nret;
00076 }
00077
00078
00079
00080
00081 SmartPtr<Nrro> Nrro::crop(int min[], int max[])
00082 {
00083 if(!_nrrd)
00084 return NrroSP();
00085
00086
00087
00088
00089 for(int i=0; i<dim(); ++i)
00090 {
00091 if(min[i] == -1)
00092 {
00093 min[i] = 0;
00094 }
00095 else if(min[i] < 0)
00096 {
00097 NrroErr("crop(), axis min less than 0, should pad this axis");
00098 return NrroSP();
00099 }
00100 if(max[i] == -1)
00101 max[i] = dim(i)-1;
00102 else if(max[i] > int(dim(i))-1)
00103 {
00104 NrroErr("crop(), axis max greater than axis dim, should pad this axis");
00105 return NrroSP();
00106 }
00107 }
00108
00109 Nrrd *nnew = nrrdNew();
00110 if(nrrdCrop(nnew, _nrrd, min, max))
00111 {
00112 char *berr = biffGetDone(NRRD);
00113 NrroErr("crop(), crop failed", berr);
00114 nrrdNuke(nnew);
00115 return NrroSP();
00116 }
00117 NrroSP nret(new Nrro(nnew));
00118
00119 nret->setKind(getKind());
00120
00121
00122 if(dim() == 3)
00123 {
00124 float xp = float(AIR_AFFINE(0,min[0],dim(0)-1,_pos.x,_pos.x+axisSize(0)));
00125 float yp = float(AIR_AFFINE(0,min[1],dim(1)-1,_pos.y,_pos.y+axisSize(1)));
00126 float zp = float(AIR_AFFINE(0,min[2],dim(2)-1,_pos.z,_pos.z+axisSize(2)));
00127 nret->setPos(vec3f(xp,yp,zp));
00128 }
00129 else if(dim()==4)
00130 {
00131 float xp = float(AIR_AFFINE(0,min[1],dim(1)-1,_pos.x,_pos.x+axisSize(1)));
00132 float yp = float(AIR_AFFINE(0,min[2],dim(2)-1,_pos.y,_pos.y+axisSize(2)));
00133 float zp = float(AIR_AFFINE(0,min[3],dim(3)-1,_pos.z,_pos.z+axisSize(3)));
00134 nret->setPos(vec3f(xp,yp,zp));
00135 }
00136
00137
00138 for(int i=0; i<dim(); ++i)
00139 {
00140 if(min[i] < int(_pads[i].x))
00141 nret->_pads[i].x = _pads[i].x - min[i];
00142 else
00143 nret->_pads[i].x = 0;
00144 if(max[i] > int(_pads[i].y))
00145 nret->_pads[i].y = nret->dim(i) - max[i] - _pads[i].y - 1;
00146 else
00147 nret->_pads[i].y = nret->dim(i) - 1;
00148 }
00149
00150 ostringstream ss;
00151 ss << _name << "_c";
00152 for(int i=0; i<int(dim())-1; ++i)
00153 ss << min[i] << "-" << max[i] << "_";
00154 ss << min[int(dim())-1] << "-" << max[int(dim())-1];
00155 nret->_name = ss.str();
00156
00157 nret->setModified();
00158 nret->update();
00159 return nret;
00160 }
00161
00162
00163
00164
00165 SmartPtr<Nrro> Nrro::pad(int min[], int max[], int bound, double padval)
00166 {
00167 if(!_nrrd)
00168 return NrroSP();
00169
00170
00171
00172 for(int i=0; i<dim(); ++i)
00173 {
00174 if(min[i] > 0)
00175 {
00176 NrroErr("pad(), min setting greater than 0, should crop this axis");
00177 return NrroSP();
00178 }
00179 if(max[i] < int(dim(i))-1)
00180 {
00181 NrroErr("pad(), max setting less than dim of axis, should crop this axis");
00182 return NrroSP();
00183 }
00184 }
00185
00186 Nrrd *nnew = nrrdNew();
00187 if(nrrdPad_nva(nnew, _nrrd, min, max, bound, padval))
00188 {
00189 char *berr = biffGetDone(NRRD);
00190 NrroErr("pad(), pad failed", berr);
00191 nrrdNuke(nnew);
00192 return NrroSP();
00193 }
00194 NrroSP nret(new Nrro(nnew));
00195
00196 nret->setKind(getKind());
00197
00198
00199
00200
00201 for(int i=0; i<dim(); ++i)
00202 {
00203 nret->_pads[i].x = _pads[i].x - min[i];
00204 nret->_pads[i].y = nret->dim(i) - 1 - (max[i] - _pads[i].y);
00205 }
00206
00207 ostringstream ss;
00208 ss << _name << "_p_";
00209 for(int i=0; i<int(dim())-1; ++i)
00210 ss << min[i] << "-" << max[i] << "_";
00211 ss << min[int(dim())-1] << "-" << max[int(dim())-1];
00212 nret->_name = ss.str();
00213
00214 nret->setModified();
00215 nret->update();
00216 return nret;
00217 }
00218
00219
00220
00221 NrroSP Nrro::cropPad(int min[], int max[], int bound, double padval)
00222 {
00223 if(!_nrrd)
00224 return NrroSP();
00225
00226 int *cmin = new int[dim()];
00227 int *cmax = new int[dim()];
00228 int *pmin = new int[dim()];
00229 int *pmax = new int[dim()];
00230
00231
00232 for(int i=0; i< int(dim()); ++i)
00233 {
00234
00235
00236 cmin[i] = clamp(int(0), min[i], int(dim(i))-1);
00237 cmax[i] = clamp(int(0), max[i], int(dim(i))-1);
00238
00239
00240 if(cmin[i] > 0)
00241 pmin[i] = 0;
00242 else
00243 pmin[i] = min[i];
00244
00245
00246 if(cmax[i] < int(dim(i))-1)
00247 pmax[i] = cmax[i] - pmin[i];
00248 else
00249 pmax[i] = cmax[i] - cmin[i] + max[i] - (dim(i)-1);
00250 }
00251
00252 NrroSP ret = crop(cmin, cmax);
00253 return ret->pad(pmin, pmax, bound, padval);
00254 }
00255
00256
00257
00258
00259 SmartPtr<Nrro> Nrro::quantize(int bits, double min, double max)
00260 {
00261 if(!_nrrd)
00262 return NrroSP();
00263
00264 if(min != AIR_NAN)
00265 {
00266 _nrrd->min = min;
00267 }
00268 if(max != AIR_NAN)
00269 {
00270 _nrrd->max = max;
00271 }
00272
00273 Nrrd *nnew = nrrdNew();
00274
00275 if(nrrdQuantize(nnew, _nrrd, bits))
00276 {
00277 char *berr = biffGetDone(NRRD);
00278 NrroErr("quantize(), quantize failed", berr);
00279 nrrdNuke(nnew);
00280 return NrroSP();
00281 }
00282
00283 NrroSP nret(new Nrro(nnew));
00284 nret->_pads = _pads;
00285 nret->_pos = _pos;
00286 nret->_kind = _kind;
00287
00288 ostringstream ss;
00289 ss << _name << "_q" << bits;
00290 nret->_name = ss.str();
00291
00292 nret->setModified();
00293 nret->update();
00294 return nret;
00295 }
00296
00297
00298
00299
00300 int Nrro::insertAxis(unsigned int axis)
00301 {
00302 if(!_nrrd)
00303 return 1;
00304
00305 Nrrd *nnew = nrrdNew();
00306 if(nrrdAxesInsert(nnew, _nrrd, axis))
00307 {
00308 char *berr = biffGetDone(NRRD);
00309 NrroErr("insertAxis(), insert failed", berr);
00310 nrrdNuke(nnew);
00311 return 1;
00312 }
00313 nrrdNuke(_nrrd);
00314 _nrrd = nnew;
00315 for(int i=int(dim())-1; i>int(axis); --i)
00316 {
00317 _pads[i] = _pads[i-1];
00318 }
00319 _pads[axis] = vec2ui(0,0);
00320
00321 setModified();
00322 update();
00323 return 0;
00324 }
00325
00326
00327
00328
00329
00330 template<class T>
00331 vec2d minmaxFunc(Nrro::NrroIter<T> ni)
00332 {
00333 if(!ni.isValid()){
00334 cerr << "invalid volume " << typeid(ni).name()
00335 << " pos = " << ni.pos() << endl;
00336 return vec2d(0,0);
00337 }
00338
00339 T min = *ni;
00340 T max = *ni;
00341 ++ni;
00342 while(ni.isValid())
00343 {
00344 min = g_min(*ni,min);
00345 max = g_max(*ni,max);
00346 ++ni;
00347 }
00348 return vec2d(double(min),double(max));
00349 }
00350
00351 void Nrro::updateMinMax()
00352 {
00353
00354
00355 _incCount();
00356 retDispatchIter1(_minmax,minmaxFunc,this);
00357 _decCount();
00358
00359 _nrrd->min = _minmax.x;
00360 _nrrd->max = _minmax.y;
00361 }
00362
00363
00364
00365
00366 template<class TO, class TI>
00367 bool nearestResamp(Nrro::NrroIter<TO> nii, Nrro::NrroIter<TI> nio)
00368 {
00369 if(nii->dim() != nio->dim()) return true;
00370 }
00371
00372 gutz::SmartPtr<Nrro> Nrro::resample(int dims[], const NrroKernel &kern,
00373 int bound, int typeOut)
00374 {
00375 if(!_nrrd)
00376 return NrroSP();
00377
00378
00379 bool go = false;
00380
00381
00382 NrrdResampleInfo *rsmpInfo = nrrdResampleInfoNew();
00383
00384
00385 for(int i=0; i<int(dim()); ++i)
00386 {
00387
00388 if(-1 != dims[i])
00389 {
00390 rsmpInfo->kernel[i] = kern.getNrrdKernel();
00391 rsmpInfo->samples[i] = dims[i];
00392 memcpy(rsmpInfo->parm[i], kern.getParams(),
00393 (kern.getNrrdKernel())->numParm*sizeof(double));
00394
00395 if (!AIR_EXISTS(_nrrd->axis[i].min)) {
00396 _nrrd->axis[i].min = 0.0;
00397 }
00398 if (!AIR_EXISTS(_nrrd->axis[i].max)) {
00399 _nrrd->axis[i].max = dim(i) -1;
00400 }
00401
00402 rsmpInfo->min[i] = _nrrd->axis[i].min;
00403 rsmpInfo->max[i] = _nrrd->axis[i].max;
00404 _nrrd->axis[i].center = nrrdCenterNode;
00405 go = true;
00406 }
00407
00408 else
00409 {
00410 rsmpInfo->kernel[i] = 0;
00411 }
00412 }
00413
00414 rsmpInfo->boundary = bound;
00415 if(typeOut == UNKNOWN)
00416 {
00417 rsmpInfo->type = getType();
00418 }
00419 else
00420 {
00421 rsmpInfo->type = typeOut;
00422 }
00423
00424 Nrrd *nnew = nrrdNew();
00425
00426 if(go)
00427 {
00428 if (nrrdSpatialResample(nnew, _nrrd, rsmpInfo))
00429 {
00430 char *berr = biffGetDone(NRRD);
00431 NrroErr("resample(), resample failed", berr);
00432 nrrdNuke(nnew);
00433 return NrroSP();
00434 }
00435 }
00436 else
00437 {
00438 if (nrrdCopy(nnew, _nrrd))
00439 {
00440 char *berr = biffGetDone(NRRD);
00441 NrroErr("resample(), resample/copy failed", berr);
00442 nrrdNuke(nnew);
00443 return NrroSP();
00444 }
00445 }
00446
00447 NrroSP nret = new Nrro(nnew);
00448 nret->setKind(nret->guessKind());
00449
00450 return nret;
00451 }
00452
00453
00454
00455
00456 gutz::SmartPtr<Nrro> Nrro::resample(float pct)
00457 {
00458 cerr << " Nrro::resample(float pct) not implemented yet " << endl;
00459 return NrroSP();
00460 }
00461