]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/Contour/ContourExtractData.cxx
no message
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / Contour / ContourExtractData.cxx
1
2 #include "ContourExtractData.h"
3
4
5 //----------------------------------------------------------------------
6 ContourExtractData::ContourExtractData( bool okImagesResults)
7   {
8     this->imagedata                     = NULL;
9         imagedataValueResult    = NULL;
10         imagedataMaskResult             = NULL;
11         this->okImagesResults   = okImagesResults;
12         _typeOperation                  = 0;
13   }
14
15   // ------------------------------------------------------------------------
16
17   ContourExtractData::~ContourExtractData()
18   {
19   }
20
21
22 //----------------------------------------------------------------------
23 void ContourExtractData::SetImage( vtkImageData* imagedata)
24   {
25         this->imagedata                 = imagedata;
26                 
27         // init vtk image result : valuesImage maskImage  
28         if (this->okImagesResults==true){  InitVtkImagesResult(); }
29   }
30 //----------------------------------------------------------------------
31 void ContourExtractData::SetZtoBeAnalys( int z )
32   {
33         this->zImage                    = z;
34   }
35
36 //------------------------------------------------------------------------
37   void ContourExtractData::SetLstManualContourModel( std::vector<manualContourModel*> lstManConMod)
38   {
39           this->lstManConMod = lstManConMod;
40   }
41
42
43 //------------------------------------------------------------------------
44 void ContourExtractData::GetMinMaxPoint(int *minPoint, 
45                                                                                   int *maxPoint, 
46                                                                                   manualContourModel *manualcontourmodel
47                                                                                   )
48 {
49         int i;
50         //int   np              = manualcontourmodel->GetSizeLstPoints( );  // number of control points // JPRx
51
52 // JSTG 26-02-08 ---------------------------------------------------------------------------------------
53         //int nps = manualviewbaseecontour->GetNumberOfPointsSpline(); // number of points in the spline
54         int nps = manualcontourmodel->GetNumberOfPointsSpline(); // number of points in the spline
55 //------------------------------------------------------------------------------------------------------
56         
57 // JSTG 26-02-08 ---------------------------------------------------------------------------------------
58         //double x,y,z,t;
59         double x,y,z;
60         //double delta=( double ) ( np  ) / ( double ) ( nps  );
61         manualcontourmodel->UpdateSpline();
62         for (i=0; i<nps; i++)
63         {
64                 //t= delta * (double)i;
65                 //manualcontourmodel->GetSplinePoint(t,x,y,z);
66                 manualcontourmodel->GetSpline_i_Point(i,&x,&y,&z);
67                 if (x<minPoint[0]){ minPoint[0]=(int)x; }
68                 if (y<minPoint[1]){ minPoint[1]=(int)y; }
69                 if (x>maxPoint[0]){ maxPoint[0]=(int)x; }
70                 if (y>maxPoint[1]){ maxPoint[1]=(int)y; }
71         }
72         minPoint[0]--;
73         minPoint[1]--;
74         maxPoint[0]++;
75         maxPoint[1]++;
76 //------------------------------------------------------------------------------------------------------
77 }
78
79 //------------------------------------------------------------------------
80 void ContourExtractData::GetMinMaxPoint_Of_LstManConMod(        int *minPoint, 
81                                                                                         int *maxPoint
82                                                                                 )
83
84 {
85         int i,size = lstManConMod.size();
86         for(i=0 ; i<size ; i++)
87         {
88                 GetMinMaxPoint(minPoint,maxPoint,lstManConMod[i]);
89         }
90 }
91
92
93 //------------------------------------------------------------------------
94 int ContourExtractData::AnalisisContourInsideV2(int x, int y, int iContour )
95 {
96         bool inBorder=false;
97         int result      = 0;
98         int i;
99
100         int nps=_lstlstlstVecX1[iContour][y].size();
101         
102         double x1,y1,x2,y2;
103         double borderX, borderY;
104         double xx1, yy1,xx2, yy2;
105         double xx=x, yy=y;
106         double d;
107
108         for (i=0; i<nps; i++)
109         {
110                 x1=_lstlstlstVecX1[iContour][y][i];
111                 y1=_lstlstlstVecY1[iContour][y][i];
112                 x2=_lstlstlstVecX2[iContour][y][i];
113                 y2=_lstlstlstVecY2[iContour][y][i];
114
115                 borderX=x1;
116                 borderY=y1;
117                 
118                 if (y1<y2) 
119                 { 
120                         xx1=x1; yy1=y1; xx2=x2; yy2=y2;
121                 } else {
122                         xx1=x2; yy1=y2; xx2=x1; yy2=y1; 
123                 } 
124                 
125                 double difxx2xx1=fabs(xx2-xx1);
126                 if (difxx2xx1==0) difxx2xx1=0.0000000001;
127                 
128                 // Finding border looking in vertical direction  AND  verifing if pixel is at right of the line 
129                 if  ( (yy>=yy1)&&(yy<=yy2) ) 
130                 {
131                         //by triangle similarity
132                         d = ( fabs(xx2-xx1)*(yy-yy1) ) / (yy2-yy1) ;
133                         if ( (xx1<=xx2)&&(x<(xx1+d)) )  {       result++;       }
134                         if ( (xx1>xx2)&&(x<(xx1-d)) )   {       result++;       } 
135                         
136                         if ( (yy2-yy1)/difxx2xx1 >= 1.0)
137                         {
138                                 if (xx1<=xx2)   
139                                 { 
140                                         borderX = xx1+d;
141                                         borderY = y;
142                                 } else { 
143                                         borderX = xx1-d;
144                                         borderY = y;
145                                 } 
146                         } 
147                 } // if point inside y 
148                 
149                 
150                 // Finding border looking in vertical direction
151                 if ( ((xx1<=xx2)&&(xx>=xx1)&&(xx<xx2)) || ((xx1>xx2)&&(xx>=xx2)&&(xx<xx1)) )
152                 {
153                         if ( (yy2-yy1)/difxx2xx1 <= 1.0)
154                         {
155                                 //by triangle similarity
156                                 d = ( fabs(xx1-xx)*(yy2-yy1) ) / difxx2xx1;
157                                 if (yy1+d<=yy2) {
158                                         borderX=x;
159                                         borderY=yy1+d;
160                                 }
161                         }                       
162                 } // if point inside x                  
163                 
164                 
165                 //Border verification
166                 if (   (x==(int)borderX) && (y==(int)borderY)   )  { inBorder=true; }// if point in border
167                 
168                 // Verification : border in horizontal line 
169                 if ( ((int)y1==(int)y2)  &&  ((int)y1==y) && (x1<x2) && (x>=x1) && (x<=x2))             { inBorder=true;        }
170                 if ( ((int)y1==(int)y2)  &&  ((int)y1==y) && (x2<x1) && (x>=x2) && (x<=x1))             { inBorder=true;        }
171                 
172                 if (inBorder==true){ i=nps; }           
173         } // for i
174         
175         if (inBorder==true)     { result=1;     }
176         
177         return result;
178 }
179
180
181
182 //------------------------------------------------------------------------
183 bool ContourExtractData::isInside(int x, int y, int typeOperation)
184 {
185         bool result                             = false;
186         int numberLeft                  = 0;
187         int i,size                              = this->lstManConMod.size();
188         int numberInside        = 0;
189
190         int ext[6];
191         imagedata->GetExtent(ext);
192
193         if ((x>=0) && (x<=ext[1]) && (y>=0) && (y<=ext[3]))
194         {
195
196                 if (typeOperation==0)  // AND  Intersection
197                 {
198                         for (i=0;i<size;i++)
199                         {
200                                 numberLeft =  AnalisisContourInsideV2(x,y, i );
201                                 if ( (numberLeft % 2) ==1){         numberInside++;  }
202                         }
203                         if ( numberInside == (size) ){ result=true; }
204                 } // AND  Intersection
205
206
207                 if (typeOperation==1)  // OR  All
208                 {
209                         for (i=0;i<size;i++)
210                         {
211                                 numberLeft =  AnalisisContourInsideV2(x,y, i );
212                                 if ( (numberLeft % 2) ==1){ result=true;  }
213                         }
214                 } // OR  All
215
216                 if (typeOperation==2)  // XOR  crown
217                 {
218                         for (i=0;i<size;i++)
219                         {
220                                 numberLeft = numberLeft + AnalisisContourInsideV2(x,y, i );
221                         }
222                         if ( numberLeft % 2 ==1){       result = true;  } 
223                 }// XOR  crown
224
225
226
227         }
228
229         return result;
230 }
231
232 //------------------------------------------------------------------------
233
234 double ContourExtractData::GetDataValue(int x, int y, int z)
235 {
236 //      wxVtk2DBaseView *wxvtk2dbaseview = (wxVtk2DBaseView*)wxvtkbaseview;
237 //      int z = (int)wxvtk2dbaseview->GetVtkBaseData()->GetZ();
238         //JSTG 13-03-08-----
239 //EED OJO avec JS       _zz = z;
240         //------------------
241         double result;
242         void *p;
243         p = imagedata->GetScalarPointer(x,y,z);
244
245         if (imagedata->GetScalarType()==VTK_CHAR)
246         {
247                 char *pp = (char*)p;
248                 result = (double)(*pp);
249         }
250         else if (imagedata->GetScalarType()==VTK_SIGNED_CHAR)
251         {
252                 signed char *pp = (signed char*)p;
253                 result = (double)(*pp);
254         }
255         else if (imagedata->GetScalarType()==VTK_UNSIGNED_CHAR)
256         {
257                 unsigned char *pp = (unsigned char*)p;
258                 result = (double)(*pp);
259         }
260         else if (imagedata->GetScalarType()==VTK_SHORT)
261         {
262                 short *pp = (short*)p;
263                 result = (double)(*pp);
264         }
265         else if (imagedata->GetScalarType()==VTK_UNSIGNED_SHORT)
266         {
267                 unsigned short *pp = (unsigned short*)p;
268                 result = (double)(*pp);
269         }
270         else if (imagedata->GetScalarType()==VTK_INT)
271         {
272                 int *pp = (int*)p;
273                 result = (double)(*pp);
274         }
275         else if (imagedata->GetScalarType()==VTK_UNSIGNED_INT)
276         {
277                 unsigned int *pp = (unsigned int*)p;
278                 result = (double)(*pp);
279         }
280         else if (imagedata->GetScalarType()==VTK_LONG)
281         {
282                 long *pp = (long*)p;
283                 result = (double)(*pp);
284         }
285         else if (imagedata->GetScalarType()==VTK_UNSIGNED_LONG)
286         {
287                 unsigned long *pp = (unsigned long*)p;
288                 result = (double)(*pp);
289         }
290         else if (imagedata->GetScalarType()==VTK_FLOAT)
291         {       
292                 float *pp = (float*)p;
293                 result = (double)(*pp);
294         }
295         else if (imagedata->GetScalarType()==VTK_DOUBLE)
296         {
297                 double *pp = (double*)p;
298                 result = (double)(*pp);
299         }
300
301         return result;
302 }
303
304 //------------------------------------------------------------------------
305
306 void ContourExtractData::PutVtkImageDataResultValue( int x, int y, int z, double value )
307 {
308         unsigned short *pValue;
309         unsigned short *pMask;
310         pValue  = (unsigned short *)imagedataValueResult->GetScalarPointer(x,y,z);
311         pMask   = (unsigned short *)imagedataMaskResult->GetScalarPointer(x,y,z);
312         *pMask  = 255;
313         *pValue = (unsigned short)value;
314 }
315
316 //------------------------------------------------------------------------
317 void ContourExtractData::ResetImageResult(int z)
318 {
319         if (okImagesResults==true)
320         {
321                 unsigned short *pValue;
322                 unsigned short *pMask;
323                 pValue  = (unsigned short *)imagedataValueResult->GetScalarPointer(0,0,z);
324                 pMask   = (unsigned short *)imagedataMaskResult->GetScalarPointer(0,0,z);
325                 
326                 int ext[6];
327                 imagedataValueResult->GetExtent(ext);
328
329                 int size = (ext[1]-ext[0]+1) * (ext[3]-ext[2]+1); 
330                 memset(pValue,0,size*2);
331                 memset(pMask,0,size*2);
332         } // if
333 }
334
335
336 //------------------------------------------------------------------------
337 void ContourExtractData::CalculateImageResult()
338 {
339         if (okImagesResults==true)
340         {
341                 ResetImageResult(zImage);
342
343                 int minPoint[2];
344                 int maxPoint[2];
345                 int i,j;
346                 double value;
347
348                 minPoint[0] = 999999;
349                 minPoint[1] = 999999;
350                 maxPoint[0] = -999999;
351                 maxPoint[1] = -999999;
352
353                 GetMinMaxPoint_Of_LstManConMod(minPoint,maxPoint);
354                 InitLstContoursLinesYPoints();
355                 
356                 for (j=minPoint[1]; j<=maxPoint[1]; j++)
357                 {
358                         for (i=minPoint[0]; i<=maxPoint[0]; i++)
359                         {
360                                 if (isInside(i,j,_typeOperation)==true)
361                                 {
362                                         value = GetDataValue(i,j,zImage);
363                                         PutVtkImageDataResultValue(i,j,zImage,  value );
364                                 } // if
365                         } // for i
366                 } // for j
367
368
369                 imagedataValueResult->Modified();
370                 imagedataMaskResult->Modified();
371                 imagedataValueResult->Update();
372                 imagedataMaskResult->Update();
373         } // if
374
375 }
376
377 //------------------------------------------------------------------------
378 void ContourExtractData::GetValuesInsideCrown(std::vector<double> *pLstValue,
379                                                                                                 std::vector<double> *pLstValuePosX,
380                                                                                                 std::vector<double> *pLstValuePosY,
381                                                                                                 std::vector<double> *pLstValuePosZ)
382 {
383         pLstValue->clear();
384         pLstValuePosX->clear();
385         pLstValuePosY->clear();
386         pLstValuePosZ->clear();
387
388 //      if (okImagesResults==true)
389 //      {
390 //              ResetImageResult(zImage);
391 //      }
392
393         int minPoint[2];
394         int maxPoint[2];
395         int i,j;
396         double value;
397
398
399         minPoint[0] = 999999;
400         minPoint[1] = 999999;
401         maxPoint[0] = -999999;
402         maxPoint[1] = -999999;
403
404         GetMinMaxPoint_Of_LstManConMod(minPoint,maxPoint);
405     InitLstContoursLinesYPoints();
406
407         for (j=minPoint[1]; j<=maxPoint[1]; j++)
408         {
409                 for (i=minPoint[0]; i<=maxPoint[0]; i++)
410                 {
411                         if (isInside(i,j,_typeOperation)==true)
412                         {
413                                 value = GetDataValue(i,j,zImage);
414
415 // Borrame
416 //                              if (okImagesResults==true){
417 //                                      PutVtkImageDataResultValue(i,j,zImage,  value );
418 //                              }
419
420                                 pLstValue               -> push_back( value );
421                                 pLstValuePosX   -> push_back( i );
422                                 pLstValuePosY   -> push_back( j );
423                                 pLstValuePosZ   -> push_back( -1 );
424                         } // if
425                 } // for
426         } // for
427
428
429 // Borrame
430 //      if (this->okImagesResults==true){
431 //              imagedataValueResult->Modified();
432 //              imagedataMaskResult->Modified();
433 //      }
434
435
436 }
437
438 //------------------------------------------------------------------------
439
440 vtkImageData *ContourExtractData::GetVtkImageValueResult()
441 {
442         return imagedataValueResult;
443 }
444 //------------------------------------------------------------------------
445 vtkImageData *ContourExtractData::GetVtkImageMaskResult()
446 {
447         return imagedataMaskResult;
448 }
449 // ------------------------------------------------------------------------
450 void ContourExtractData::InitVtkImagesResult()
451 {
452           int ext[6];
453           int newDim[3];
454           double spc[3];
455           int scalartype;
456
457           imagedata->GetSpacing(spc);
458           imagedata->GetExtent(ext);
459           newDim[0]=ext[1]-ext[0]+1;
460           newDim[1]=ext[3]-ext[2]+1;
461           newDim[2]=ext[5]-ext[4]+1;
462           scalartype = imagedata->GetScalarType();
463
464           if (imagedataValueResult!=NULL)
465           {
466                   imagedataValueResult->Delete();
467           }
468           imagedataValueResult = vtkImageData::New();
469 //        imagedataValueResult->SetScalarType(scalartype);
470           imagedataValueResult->SetScalarTypeToUnsignedShort();
471           imagedataValueResult->SetSpacing(spc);
472           imagedataValueResult->SetDimensions( newDim );
473           imagedataValueResult->AllocateScalars();
474
475           if (imagedataMaskResult!=NULL)
476           {
477                   imagedataMaskResult->Delete();
478           }
479           imagedataMaskResult  = vtkImageData::New();
480 //        imagedataMaskResult->SetScalarType(scalartype);
481           imagedataMaskResult->SetScalarTypeToUnsignedShort();
482           imagedataMaskResult->SetSpacing(spc);
483           imagedataMaskResult->SetDimensions( newDim );
484           imagedataMaskResult->AllocateScalars();
485 }
486
487
488 //------------------------------------------------------------------------
489 void ContourExtractData::InitVolumeStatistics()
490 {
491         vol_rCountRange                         = 0;
492         vol_rsize                                       = 0;
493         vol_minValue                            = 9999999;
494         vol_maxValue                            =-9999999;
495         vol_acum_average                        = 0;
496         vol_acum_standardeviation       = 0;
497 }
498
499 //------------------------------------------------------------------------
500 void ContourExtractData::SetVolumeStatistics(int rCountRange, 
501                                                                                         int rsize,
502                                                                                         double minValue,
503                                                                                         double maxValue,
504                                                                                         double acum_average,
505                                                                                         double acum_standardeviation)
506 {
507         vol_rCountRange                         = vol_rCountRange + rCountRange; 
508         vol_rsize                                       = vol_rsize + rsize; 
509         
510         if (minValue<vol_minValue){ vol_minValue = minValue;  }
511         if (maxValue>vol_maxValue){ vol_maxValue = maxValue;  }
512         
513         vol_acum_average                        = vol_acum_average + acum_average; 
514         vol_acum_standardeviation       = vol_acum_standardeviation + acum_standardeviation; 
515 }
516
517 //------------------------------------------------------------------------
518 void ContourExtractData::GetVolumeStatistics(int *vol_rCountRange, 
519                                                                                          int *vol_rsize,
520                                                                                          double *vol_minValue,
521                                                                                          double *vol_maxValue,
522                                                                                          double *vol_average,
523                                                                                          double *vol_standardeviation)
524 {
525         *vol_rCountRange                = this->vol_rCountRange; 
526         *vol_rsize                              = this->vol_rsize; 
527         *vol_minValue                   = this->vol_minValue; 
528         *vol_maxValue                   = this->vol_maxValue; 
529         *vol_average                    = this->vol_acum_average / this->vol_rsize;
530         *vol_standardeviation   = sqrt(this->vol_acum_standardeviation / this->vol_rsize);
531 }
532
533
534 //------------------------------------------------------------------------
535 void ContourExtractData::Statistics( std::vector<double> *inputLstValue, 
536                                                                         int     grayRangeMin,
537                                                                         int     grayRangeMax,
538                                                                         int             *rCountRange, 
539                                                                         int             *rsize, 
540                                                                         double  *rmin, 
541                                                                         double  *rmax,
542                                                                         double  *raverage,
543                                                                         double  *rstandardeviation
544                                                                                 )
545 {
546           double min                                            = 0;
547           double max                                            = 0;
548           double average                                        = 0;
549           double standardeviation                       = 0;
550           double acum_average                           = 0;
551           double acum_standardeviation          = 0;
552           int    size                                           = 0;
553           int    countRange                                     = 0;
554           double ng;
555
556           if (inputLstValue!=NULL)
557           {
558                 size=inputLstValue->size();
559                 if (size>0){
560                max=(*inputLstValue)[0];
561                    min=(*inputLstValue)[0];
562      // Average , countRange
563                         int i;
564                         for ( i=0; i<size; i++ )
565                         {
566                                 ng=(*inputLstValue)[i];
567                                 acum_average = acum_average + ng;
568                                 if (max<ng) max=ng;             // Max
569                                 if (min>ng) min=ng;     // Min
570                                 if ((ng>=grayRangeMin) && (ng<=grayRangeMax)) countRange++;  // countRange
571                         } // for average
572                         average = acum_average / size;
573
574           // Standar Deviation
575                         acum_standardeviation=0;
576                         double tmp;
577                         for ( i=0; i<size; i++ )
578                         {
579                 tmp = (*inputLstValue)[i] - average;
580                                 acum_standardeviation = acum_standardeviation + tmp*tmp;
581                         } // for standar deviation
582                         standardeviation = sqrt(acum_standardeviation/size);
583                         SetVolumeStatistics(countRange, size,
584                                                                 min,max,
585                                                             acum_average,acum_standardeviation);
586                 } // if size
587           } // if NULL
588
589           // OUTPUT
590                 *rsize                          = size; 
591                 *rCountRange            = countRange;
592                 *rmin                           = min; 
593                 *rmax                           = max;
594                 *raverage                       = average;
595                 *rstandardeviation      = standardeviation;
596 }
597
598 //------------------------------------------------------------------------
599 void ContourExtractData::SetTypeOperation(int type)
600 {
601         _typeOperation=type;
602 }
603
604 //------------------------------------------------------------------------
605 void ContourExtractData::Fill_lstlstlstVecXY(int iContour, int sizeY)
606 {
607         int i,y;
608         double x1,y1,z1,x2,y2,z2;
609         manualContourModel *manualcontourmodel= lstManConMod[iContour]; 
610         int nps = manualcontourmodel->GetNumberOfPointsSpline(); // number of points in the spline
611         manualcontourmodel->UpdateSpline();
612         //------------------------------------------------------------------------------------------------------
613         
614         for (y=0;y<sizeY;y++)
615         {
616                 manualcontourmodel->GetSpline_i_Point(0,&x1,&y1,&z1);
617                 x1=x1+0.5; y1=y1+0.5;
618                 for (i=1; i<nps; i++)
619                 {
620                         manualcontourmodel->GetSpline_i_Point(i,&x2,&y2,&z2);
621                         x2=x2+0.5; y2=y2+0.5;
622                         if ( ((y1<y2)&&(y>=y1)&&(y<=y2)) || ((y1>y2)&&(y>=y2)&&(y<=y1)) || ((int)y1==y) || ((int)y2==y)  )
623                         {
624                                 _lstlstlstVecX1[iContour][y].push_back(x1);
625                                 _lstlstlstVecY1[iContour][y].push_back(y1);
626                                 _lstlstlstVecX2[iContour][y].push_back(x2);
627                                 _lstlstlstVecY2[iContour][y].push_back(y2);
628                         } 
629                         x1=x2; y1=y2; z1=z2;
630                 } // for i  Points in spline
631         } // y
632
633 }
634
635 void ContourExtractData::InitLstContoursLinesYPoints()
636 {
637         // init InInside Optimisation  
638         int i;
639         
640         _lstlstlstVecX1.clear();
641         _lstlstlstVecY1.clear();
642         _lstlstlstVecX2.clear();
643         _lstlstlstVecY2.clear();
644         
645         int ext[6];
646         this->imagedata->GetWholeExtent(ext);
647         int sizeY = ext[3]-ext[2]+1;
648         std::vector<double> vecDouble;
649         std::vector< std::vector<double> > vecVecDouble;
650         for ( i=0 ; i<sizeY ; i++ )
651         {
652                 vecVecDouble.push_back( vecDouble );
653         }
654         
655         //Fill structure with points
656         int sizeContours = lstManConMod.size();
657         for( i=0 ; i<sizeContours ; i++ )
658         {
659                 _lstlstlstVecX1.push_back( vecVecDouble );
660                 _lstlstlstVecY1.push_back( vecVecDouble );
661                 _lstlstlstVecX2.push_back( vecVecDouble );
662                 _lstlstlstVecY2.push_back( vecVecDouble );
663                 Fill_lstlstlstVecXY(i,sizeY);
664         }
665         
666 }
667
668