00001
00002 #include "ContourExtractData.h"
00003
00004
00005
00006 ContourExtractData::ContourExtractData( bool okImagesResults)
00007 {
00008 this->imagedata = NULL;
00009 imagedataValueResult = NULL;
00010 imagedataMaskResult = NULL;
00011 this->okImagesResults = okImagesResults;
00012 _typeOperation = 0;
00013 }
00014
00015
00016
00017 ContourExtractData::~ContourExtractData()
00018 {
00019 }
00020
00021
00022
00023 void ContourExtractData::SetImage( vtkImageData* imagedata)
00024 {
00025 this->imagedata = imagedata;
00026 this->imagedata->GetScalarRange(scalarRange);
00027
00028
00029 int ext[6];
00030 this->imagedata->GetWholeExtent(ext);
00031 _sizeImageY = ext[3]-ext[2]+1;
00032
00033
00034 if (this->okImagesResults==true){ InitVtkImagesResult(); }
00035 }
00036
00037 void ContourExtractData::SetZtoBeAnalys( int z )
00038 {
00039 this->zImage = z;
00040 }
00041
00042
00043 void ContourExtractData::SetLstManualContourModel( std::vector<manualBaseModel*> lstManConMod)
00044 {
00045 this->lstManConMod = lstManConMod;
00046 }
00047
00048
00049
00050 void ContourExtractData::GetMinMaxPoint(int *minPoint,
00051 int *maxPoint,
00052 manualBaseModel *manualcontourmodel
00053 )
00054 {
00055 int i;
00056
00057
00058
00059
00060 int nps = manualcontourmodel->GetNumberOfPointsSpline();
00061
00062
00063
00064
00065 double x,y,z;
00066
00067 manualcontourmodel->UpdateSpline();
00068 for (i=0; i<nps; i++)
00069 {
00070
00071
00072 manualcontourmodel->GetSpline_i_Point(i,&x,&y,&z);
00073 if (x<minPoint[0]){ minPoint[0]=(int)x; }
00074 if (y<minPoint[1]){ minPoint[1]=(int)y; }
00075 if (x>maxPoint[0]){ maxPoint[0]=(int)x; }
00076 if (y>maxPoint[1]){ maxPoint[1]=(int)y; }
00077 }
00078 minPoint[0]--;
00079 minPoint[1]--;
00080 maxPoint[0]++;
00081 maxPoint[1]++;
00082
00083 }
00084
00085
00086 void ContourExtractData::GetMinMaxPoint_Of_LstManConMod( int *minPoint,
00087 int *maxPoint
00088 )
00089
00090 {
00091 int i,size = lstManConMod.size();
00092
00093 for(i=0 ; i<size ; i++)
00094 {
00095 GetMinMaxPoint(minPoint,maxPoint,lstManConMod[i]);
00096 }
00097 }
00098
00099
00100
00101 int ContourExtractData::AnalisisContourInsideV2(int x, int y, int iContour )
00102 {
00103 bool inBorder=false;
00104 int result = 0;
00105 int i;
00106
00107 int nps=_lstlstlstVecX1[iContour][y].size();
00108
00109 double x1,y1,x2,y2;
00110 double borderX, borderY;
00111 double xx1, yy1,xx2, yy2;
00112 double xx=x, yy=y;
00113 double d;
00114
00115 for (i=0; i<nps; i++)
00116 {
00117 x1=_lstlstlstVecX1[iContour][y][i];
00118 y1=_lstlstlstVecY1[iContour][y][i];
00119 x2=_lstlstlstVecX2[iContour][y][i];
00120 y2=_lstlstlstVecY2[iContour][y][i];
00121
00122 borderX=x1;
00123 borderY=y1;
00124
00125 if (y1<y2)
00126 {
00127 xx1=x1; yy1=y1; xx2=x2; yy2=y2;
00128 } else {
00129 xx1=x2; yy1=y2; xx2=x1; yy2=y1;
00130 }
00131
00132 double difxx2xx1=fabs(xx2-xx1);
00133 if (difxx2xx1==0) difxx2xx1=0.0000000001;
00134
00135
00136 if ( (yy>=yy1)&&(yy<=yy2) )
00137 {
00138
00139 d = ( fabs(xx2-xx1)*(yy-yy1) ) / (yy2-yy1) ;
00140 if ( (xx1<=xx2)&&(x<(xx1+d)) ) { result++; }
00141 if ( (xx1>xx2)&&(x<(xx1-d)) ) { result++; }
00142
00143 if ( (yy2-yy1)/difxx2xx1 >= 1.0)
00144 {
00145 if (xx1<=xx2)
00146 {
00147 borderX = xx1+d;
00148 borderY = y;
00149 } else {
00150 borderX = xx1-d;
00151 borderY = y;
00152 }
00153 }
00154 }
00155
00156
00157
00158 if ( ((xx1<=xx2)&&(xx>=xx1)&&(xx<xx2)) || ((xx1>xx2)&&(xx>=xx2)&&(xx<xx1)) )
00159 {
00160 if ( (yy2-yy1)/difxx2xx1 <= 1.0)
00161 {
00162
00163 d = ( fabs(xx1-xx)*(yy2-yy1) ) / difxx2xx1;
00164 if (yy1+d<=yy2) {
00165 borderX=x;
00166 borderY=yy1+d;
00167 }
00168 }
00169 }
00170
00171
00172
00173 if ( (x==(int)borderX) && (y==(int)borderY) ) { inBorder=true; }
00174
00175
00176 if ( ((int)y1==(int)y2) && ((int)y1==y) && (x1<x2) && (x>=x1) && (x<=x2)) { inBorder=true; }
00177 if ( ((int)y1==(int)y2) && ((int)y1==y) && (x2<x1) && (x>=x2) && (x<=x1)) { inBorder=true; }
00178
00179 if (inBorder==true){ i=nps; }
00180 }
00181
00182 if (inBorder==true) { result=1; }
00183
00184 return result;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 bool ContourExtractData::isInside(int x, int y, int typeOperation)
00194 {
00195 bool result = false;
00196 int numberLeft = 0;
00197 int i,size = this->lstManConMod.size();
00198 int numberInside = 0;
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 if (typeOperation==0)
00209 {
00210 for (i=0;i<size;i++)
00211 {
00212
00213
00214 manualBaseModel *mbm = lstManConMod[i];
00215 if(mbm->GetTypeModel()==7)
00216 {
00217 if(mbm->IsPoint(x,y)==true)
00218 {
00219 numberLeft=1;
00220 }
00221 }
00222 else
00223 {
00224 numberLeft = AnalisisContourInsideV2(x,y, i );
00225 }
00226
00227 if ( (numberLeft % 2) ==1){ numberInside++; }
00228 }
00229 if ( numberInside == (size) ){ result=true; }
00230 }
00231
00232 numberLeft=0;
00233
00234 if (typeOperation==1)
00235 {
00236 for (i=0;i<size;i++)
00237 {
00238
00239
00240 manualBaseModel *mbm = lstManConMod[i];
00241 if(mbm->GetTypeModel()==7)
00242 {
00243 if(mbm->IsPoint(x,y)==true)
00244 {
00245 numberLeft=1;
00246 }
00247 }
00248 else
00249 {
00250 numberLeft = AnalisisContourInsideV2(x,y, i );
00251 }
00252 if ( (numberLeft % 2) ==1){ result=true; }
00253 }
00254 }
00255
00256 numberLeft=0;
00257
00258 if (typeOperation==2)
00259 {
00260 for (i=0;i<size;i++)
00261 {
00262
00263
00264 manualBaseModel *mbm = lstManConMod[i];
00265 if(mbm->GetTypeModel()==7)
00266 {
00267 if(mbm->IsPoint(x,y)==true)
00268 {
00269 numberLeft=1;
00270 }
00271 }
00272 else
00273 {
00274 numberLeft = numberLeft + AnalisisContourInsideV2(x,y, i );
00275 }
00276
00277 }
00278 if ( numberLeft % 2 ==1){ result = true; }
00279 }
00280
00281
00282
00283
00284
00285 return result;
00286 }
00287
00288
00289
00290 double ContourExtractData::GetDataValue(int x, int y, int z)
00291 {
00292
00293
00294
00295
00296
00297 double result;
00298 void *p;
00299 p = imagedata->GetScalarPointer(x,y,z);
00300
00301 if (imagedata->GetScalarType()==VTK_CHAR)
00302 {
00303 char *pp = (char*)p;
00304 result = (double)(*pp);
00305 }
00306 else if (imagedata->GetScalarType()==VTK_SIGNED_CHAR)
00307 {
00308 signed char *pp = (signed char*)p;
00309 result = (double)(*pp);
00310 }
00311 else if (imagedata->GetScalarType()==VTK_UNSIGNED_CHAR)
00312 {
00313 unsigned char *pp = (unsigned char*)p;
00314 result = (double)(*pp);
00315 }
00316 else if (imagedata->GetScalarType()==VTK_SHORT)
00317 {
00318 short *pp = (short*)p;
00319 result = (double)(*pp);
00320 }
00321 else if (imagedata->GetScalarType()==VTK_UNSIGNED_SHORT)
00322 {
00323 unsigned short *pp = (unsigned short*)p;
00324 result = (double)(*pp);
00325 }
00326 else if (imagedata->GetScalarType()==VTK_INT)
00327 {
00328 int *pp = (int*)p;
00329 result = (double)(*pp);
00330 }
00331 else if (imagedata->GetScalarType()==VTK_UNSIGNED_INT)
00332 {
00333 unsigned int *pp = (unsigned int*)p;
00334 result = (double)(*pp);
00335 }
00336 else if (imagedata->GetScalarType()==VTK_LONG)
00337 {
00338 long *pp = (long*)p;
00339 result = (double)(*pp);
00340 }
00341 else if (imagedata->GetScalarType()==VTK_UNSIGNED_LONG)
00342 {
00343 unsigned long *pp = (unsigned long*)p;
00344 result = (double)(*pp);
00345 }
00346 else if (imagedata->GetScalarType()==VTK_FLOAT)
00347 {
00348 float *pp = (float*)p;
00349 result = (double)(*pp);
00350 }
00351 else if (imagedata->GetScalarType()==VTK_DOUBLE)
00352 {
00353 double *pp = (double*)p;
00354 result = (double)(*pp);
00355 }
00356
00357 return result;
00358 }
00359
00360
00361
00362 void ContourExtractData::PutVtkImageDataResultValue( int x, int y, int z, double value )
00363 {
00364 unsigned short *pValue;
00365 unsigned short *pMask;
00366 pValue = (unsigned short *)imagedataValueResult->GetScalarPointer(x,y,z);
00367 pMask = (unsigned short *)imagedataMaskResult->GetScalarPointer(x,y,z);
00368 *pMask = 255;
00369 *pValue = (unsigned short)value;
00370 }
00371
00372
00373 void ContourExtractData::ResetImageResult(int z)
00374 {
00375 if (okImagesResults==true)
00376 {
00377 unsigned short *pValue;
00378 unsigned short *pMask;
00379 pValue = (unsigned short *)imagedataValueResult->GetScalarPointer(0,0,z);
00380 pMask = (unsigned short *)imagedataMaskResult->GetScalarPointer(0,0,z);
00381
00382 int ext[6];
00383 imagedataValueResult->GetExtent(ext);
00384
00385 int size = (ext[1]-ext[0]+1) * (ext[3]-ext[2]+1);
00386 memset(pValue,0,size*2);
00387 memset(pMask,0,size*2);
00388 }
00389 }
00390
00391
00392
00393 void ContourExtractData::CalculateImageResult()
00394 {
00395 if (okImagesResults==true)
00396 {
00397 ResetImageResult(zImage);
00398
00399 int minPoint[2];
00400 int maxPoint[2];
00401 int i,j;
00402 double value;
00403
00404 minPoint[0] = 999999;
00405 minPoint[1] = 999999;
00406 maxPoint[0] = -999999;
00407 maxPoint[1] = -999999;
00408
00409 GetMinMaxPoint_Of_LstManConMod(minPoint,maxPoint);
00410 InitLstContoursLinesYPoints();
00411
00412 for (j=minPoint[1]; j<=maxPoint[1]; j++)
00413 {
00414 for (i=minPoint[0]; i<=maxPoint[0]; i++)
00415 {
00416
00417
00418 int ext[6];
00419 imagedata->GetExtent(ext);
00420
00421 if ((i>=0) && (i<=ext[1]) && (j>=0) && (j<=ext[3]))
00422 {
00423 if (isInside(i,j,_typeOperation)==true)
00424 {
00425 value = GetDataValue(i,j,zImage);
00426 if ( (value>=scalarRange[0]) && (value<=scalarRange[1]) )
00427 {
00428 PutVtkImageDataResultValue(i,j,zImage, value );
00429 }
00430 }
00431
00432 }
00433 }
00434 }
00435
00436
00437 imagedataValueResult->Modified();
00438 imagedataMaskResult->Modified();
00439 imagedataValueResult->Update();
00440 imagedataMaskResult->Update();
00441 }
00442
00443 }
00444
00445
00446 void ContourExtractData::GetValuesInsideCrown( int *numberOfPixels,
00447 std::vector<double> *pLstValue,
00448 std::vector<double> *pLstValuePosX,
00449 std::vector<double> *pLstValuePosY,
00450 std::vector<double> *pLstValuePosZ)
00451 {
00452 pLstValue->clear();
00453 pLstValuePosX->clear();
00454 pLstValuePosY->clear();
00455 pLstValuePosZ->clear();
00456
00457
00458
00459
00460
00461
00462 int minPoint[2];
00463 int maxPoint[2];
00464 int i,j;
00465 double value;
00466 int acum=0;
00467
00468 minPoint[0] = 999999;
00469 minPoint[1] = 999999;
00470 maxPoint[0] = -999999;
00471 maxPoint[1] = -999999;
00472
00473 GetMinMaxPoint_Of_LstManConMod(minPoint,maxPoint);
00474 InitLstContoursLinesYPoints();
00475
00476 for (j=minPoint[1]; j<=maxPoint[1]; j++)
00477 {
00478 for (i=minPoint[0]; i<=maxPoint[0]; i++)
00479 {
00480
00481 int ext[6];
00482 imagedata->GetExtent(ext);
00483
00484 if ((i>=0) && (i<=ext[1]) && (j>=0) && (j<=ext[3]))
00485 {
00486 if (isInside(i,j,_typeOperation)==true)
00487 {
00488
00489 acum++;
00490 value = GetDataValue(i,j,zImage);
00491 if ( (value>=scalarRange[0]) && (value<=scalarRange[1]) )
00492 {
00493 pLstValue -> push_back( value );
00494 pLstValuePosX -> push_back( i );
00495 pLstValuePosY -> push_back( j );
00496 pLstValuePosZ -> push_back( -1 );
00497 }
00498 }
00499 }
00500 }
00501 }
00502
00503 *numberOfPixels = acum;
00504 }
00505
00506
00507
00508 vtkImageData *ContourExtractData::GetVtkImageValueResult()
00509 {
00510 return imagedataValueResult;
00511 }
00512
00513 vtkImageData *ContourExtractData::GetVtkImageMaskResult()
00514 {
00515 return imagedataMaskResult;
00516 }
00517
00518 void ContourExtractData::InitVtkImagesResult()
00519 {
00520 int ext[6];
00521 int newDim[3];
00522 double spc[3];
00523 int scalartype;
00524
00525 imagedata->GetSpacing(spc);
00526 imagedata->GetExtent(ext);
00527 newDim[0]=ext[1]-ext[0]+1;
00528 newDim[1]=ext[3]-ext[2]+1;
00529 newDim[2]=ext[5]-ext[4]+1;
00530 scalartype = imagedata->GetScalarType();
00531
00532 if (imagedataValueResult!=NULL)
00533 {
00534 imagedataValueResult->Delete();
00535 }
00536 imagedataValueResult = vtkImageData::New();
00537
00538 imagedataValueResult->SetScalarTypeToUnsignedShort();
00539 imagedataValueResult->SetSpacing(spc);
00540 imagedataValueResult->SetDimensions( newDim );
00541 imagedataValueResult->AllocateScalars();
00542
00543 if (imagedataMaskResult!=NULL)
00544 {
00545 imagedataMaskResult->Delete();
00546 }
00547 imagedataMaskResult = vtkImageData::New();
00548
00549 imagedataMaskResult->SetScalarTypeToUnsignedShort();
00550 imagedataMaskResult->SetSpacing(spc);
00551 imagedataMaskResult->SetDimensions( newDim );
00552 imagedataMaskResult->AllocateScalars();
00553 }
00554
00555
00556
00557 void ContourExtractData::InitVolumeStatistics()
00558 {
00559 vol_rCountRange = 0;
00560 vol_rsize = 0;
00561 vol_minValue = 9999999;
00562 vol_maxValue =-9999999;
00563 vol_acum_average = 0;
00564 vol_acum_standardeviation = 0;
00565 }
00566
00567
00568 void ContourExtractData::SetVolumeStatistics(int rCountRange,
00569 int rsize,
00570 double minValue,
00571 double maxValue,
00572 double acum_average,
00573 double acum_standardeviation)
00574 {
00575 vol_rCountRange = vol_rCountRange + rCountRange;
00576 vol_rsize = vol_rsize + rsize;
00577
00578 if (minValue<vol_minValue){ vol_minValue = minValue; }
00579 if (maxValue>vol_maxValue){ vol_maxValue = maxValue; }
00580
00581 vol_acum_average = vol_acum_average + acum_average;
00582 vol_acum_standardeviation = vol_acum_standardeviation + acum_standardeviation;
00583 }
00584
00585
00586 void ContourExtractData::GetVolumeStatistics(int *vol_rCountRange,
00587 int *vol_rsize,
00588 double *vol_minValue,
00589 double *vol_maxValue,
00590 double *vol_average,
00591 double *vol_standardeviation)
00592 {
00593 *vol_rCountRange = this->vol_rCountRange;
00594 *vol_rsize = this->vol_rsize;
00595 *vol_minValue = this->vol_minValue;
00596 *vol_maxValue = this->vol_maxValue;
00597 *vol_average = this->vol_acum_average / this->vol_rsize;
00598 *vol_standardeviation = sqrt(this->vol_acum_standardeviation / this->vol_rsize);
00599 }
00600
00601
00602
00603 void ContourExtractData::Statistics( std::vector<double> *inputLstValue,
00604 int grayRangeMin,
00605 int grayRangeMax,
00606 int *rCountRange,
00607 int *rsize,
00608 double *rmin,
00609 double *rmax,
00610 double *raverage,
00611 double *rstandardeviation
00612 )
00613 {
00614 double min = 0;
00615 double max = 0;
00616 double average = 0;
00617 double standardeviation = 0;
00618 double acum_average = 0;
00619 double acum_standardeviation = 0;
00620 int size = 0;
00621 int countRange = 0;
00622 double ng;
00623
00624 if (inputLstValue!=NULL)
00625 {
00626 size=inputLstValue->size();
00627 if (size>0){
00628 max=(*inputLstValue)[0];
00629 min=(*inputLstValue)[0];
00630
00631 int i;
00632 for ( i=0; i<size; i++ )
00633 {
00634 ng=(*inputLstValue)[i];
00635 acum_average = acum_average + ng;
00636 if (max<ng) max=ng;
00637 if (min>ng) min=ng;
00638 if ((ng>=grayRangeMin) && (ng<=grayRangeMax)) countRange++;
00639 }
00640 average = acum_average / size;
00641
00642
00643 acum_standardeviation=0;
00644 double tmp;
00645 for ( i=0; i<size; i++ )
00646 {
00647 tmp = (*inputLstValue)[i] - average;
00648 acum_standardeviation = acum_standardeviation + tmp*tmp;
00649 }
00650 standardeviation = sqrt(acum_standardeviation/size);
00651 SetVolumeStatistics(countRange, (*rsize),
00652 min,max,
00653 acum_average,acum_standardeviation);
00654 }
00655 }
00656
00657
00658 *rsize = size;
00659 *rCountRange = countRange;
00660 *rmin = min;
00661 *rmax = max;
00662 *raverage = average;
00663 *rstandardeviation = standardeviation;
00664 }
00665
00666
00667 void ContourExtractData::SetTypeOperation(int type)
00668 {
00669 _typeOperation=type;
00670 }
00671
00672
00673 void ContourExtractData::Fill_lstlstlstVecXY(int iContour, int sizeY)
00674 {
00675 int i,y;
00676 double x1,y1,z1,x2,y2,z2;
00677 manualBaseModel *manualcontourmodel= lstManConMod[iContour];
00678 int nps = manualcontourmodel->GetNumberOfPointsSpline();
00679 manualcontourmodel->UpdateSpline();
00680
00681
00682 for (y=0;y<sizeY;y++)
00683 {
00684 manualcontourmodel->GetSpline_i_Point(0,&x1,&y1,&z1);
00685 x1=x1+0.5; y1=y1+0.5;
00686 for (i=1; i<nps; i++)
00687 {
00688 manualcontourmodel->GetSpline_i_Point(i,&x2,&y2,&z2);
00689 x2=x2+0.5; y2=y2+0.5;
00690 if ( ((y1<y2)&&(y>=y1)&&(y<=y2)) || ((y1>y2)&&(y>=y2)&&(y<=y1)) || ((int)y1==y) || ((int)y2==y) )
00691 {
00692 _lstlstlstVecX1[iContour][y].push_back(x1);
00693 _lstlstlstVecY1[iContour][y].push_back(y1);
00694 _lstlstlstVecX2[iContour][y].push_back(x2);
00695 _lstlstlstVecY2[iContour][y].push_back(y2);
00696 }
00697 x1=x2; y1=y2; z1=z2;
00698 }
00699 }
00700
00701 }
00702
00703 void ContourExtractData::InitLstContoursLinesYPoints()
00704 {
00705
00706 int i;
00707
00708 _lstlstlstVecX1.clear();
00709 _lstlstlstVecY1.clear();
00710 _lstlstlstVecX2.clear();
00711 _lstlstlstVecY2.clear();
00712
00713
00714
00715
00716
00717
00718 std::vector<double> vecDouble;
00719 std::vector< std::vector<double> > vecVecDouble;
00720 for ( i=0 ; i<_sizeImageY ; i++ )
00721 {
00722 vecVecDouble.push_back( vecDouble );
00723 }
00724
00725
00726 int sizeContours = lstManConMod.size();
00727 for( i=0 ; i<sizeContours ; i++ )
00728 {
00729 _lstlstlstVecX1.push_back( vecVecDouble );
00730 _lstlstlstVecY1.push_back( vecVecDouble );
00731 _lstlstlstVecX2.push_back( vecVecDouble );
00732 _lstlstlstVecY2.push_back( vecVecDouble );
00733 Fill_lstlstlstVecXY(i,_sizeImageY);
00734 }
00735
00736 }
00737
00738 void ContourExtractData::SetScalarRange(double min, double max)
00739 {
00740 scalarRange[0]=min;
00741 scalarRange[1]=max;
00742 }
00743
00744 void ContourExtractData::SetSizeImageY(int pSizeImageY)
00745 {
00746 _sizeImageY=pSizeImageY;
00747 }