1 /*=========================================================================
4 Module: $RCSfile: marGdcmDicom.cpp,v $
6 Date: $Date: 2008/10/31 16:32:55 $
7 Version: $Revision: 1.1 $
9 Copyright: (c) 2002, 2003
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notice for more information.
16 =========================================================================*/
19 #pragma warning ( disable : 4786 )
20 #pragma warning ( disable : 4251 )
25 #include <wx/filename.h>
27 #include <wx/msgdlg.h>
34 #include "vtkGdcmReader.h"
36 #include <vtkImageData.h>
37 #include <vtkImageChangeInformation.h>
38 #include <vtkImageCast.h>
39 #include <vtkImageShiftScale.h>
40 #include <vtkCommand.h>
41 #include <vtkImageAppend.h>
42 #include <vtkImageReader.h>
44 #include "marGdcmDicom.h"
50 //using namespace std;
54 #define _DICOMFILENAME "/DICOMDIR"
56 //----------------------------------------------------------------------------
57 // Callback for the interaction
58 class marProgressObserver : public vtkCommand
61 static marProgressObserver *New()
62 { return new marProgressObserver; }
65 this->FrameGauge = NULL;
67 virtual void Execute(vtkObject *wdg, unsigned long event, void* calldata)
69 if ( this->FrameGauge )
71 int val = this->FrameGauge->GetValue();
72 this->FrameGauge->SetValue( val + 1);
77 //wxSafeYield( this->FrameGauge, FALSE);
82 //----------------------------------------------------------------------------
84 static char* DicomTagsNames[] = {
86 "ID_SOP_Class_UID", //!0008 0016 UI ID SOP Class UID
87 "ID_SOP_Instance_UID", //!0008 0018 UI ID SOP Instance UID
88 "ID_Study_Date", //!0008 0020 DA ID Study Date
89 "ID_Series_Date", //!0008 0021 DA ID Series Date
90 "ID_Acquisition_Date", //!0008 0022 DA ID Acquisition Date
91 "ID_Image_Date", //!0008 0023 DA ID Image Date
92 "ID_Study_Time", //!0008 0030 TM ID Study Time
93 "ID_Series_Time", //!0008 0031 TM ID Series Time
94 "ID_Acquisition_Time", //!0008 0032 TM ID Acquisition Time
95 "ID_Image_Time", //!0008 0033 TM ID Image Time
96 "ID_Modality", //!0008 0060 CS ID Modality
97 "ID_Manufacturer", //!0008 0070 LO ID Manufacturer
98 "ID_Institution_Name", //!0008 0080 LO ID Institution Name
99 "ID_Study_Description", //!0008 1030 LO ID Study Description
100 "ID_Series_Description", //!0008 103e LO ID Series Description
101 "ID_Admitting_Diagnoses_Description", //!0008 1080 LO ID Admitting Diagnoses Description
102 "ID_Patient_Name", //!0010 0010 PN PAT Patient Name
103 "ID_Patient_ID", //!0010 0020 LO PAT Patient ID
104 "ID_Body_Part_Examined", //!0018 0015 CS ACQ Body Part Examined
105 "ID_Scanning_Sequence", //!0018 0020 CS ACQ Scanning Sequence
106 "ID_Sequence_Variant", //!0018 0021 CS ACQ Sequence Variant
107 "ID_Scan_Options", //!0018 0022 CS ACQ Scan Options
108 "ID_MR_Acquisition_Type", //!0018 0023 CS ACQ MR Acquisition Type
109 "ID_Sequence_Name", //!0018 0024 SH ACQ Sequence Name
110 "ID_Slice_Thickness", //!0018 0050 DS ACQ Slice Thickness
111 "ID_Repetition_Time", //!0018 0080 DS ACQ Repetition Time
112 "ID_Echo_Time", //!0018 0081 DS ACQ Echo Time
113 "ID_Inversion_Time", //!0018 0082 DS ACQ Inversion Time
114 "ID_Number_of_Averages", //!0018 0083 DS ACQ Number of Averages
115 "ID_Imaging_Frequency", //!0018 0084 DS ACQ Imaging Frequency
116 "ID_Imaged_Nucleus", //!0018 0085 SH ACQ Imaged Nucleus
117 "ID_Echo_Number", //!0018 0086 IS ACQ Echo Number
118 "ID_Magnetic_Field_Strength", //!0018 0087 DS ACQ Magnetic Field Strength
119 "ID_Spacing_Between_Slices", //!0018 0088 DS ACQ Spacing Between Slices
120 "ID_Echo_Train_Length", //!0018 0091 IS ACQ Echo Train Length
121 "ID_Percent_Sampling", //!0018 0093 DS ACQ Percent Sampling
122 "ID_Percent_Phase_Field_of_View", //!0018 0094 DS ACQ Percent Phase Field of View
123 "ID_Receiving_Coil", //!0018 1250 SH ACQ Receiving Coil
124 "ID_Patient_Position", //!0018 5100 CS ACQ Patient Position
125 "ID_Study_Instance_UID", //!0020 000d UI REL Study Instance UID
126 "ID_Series_Instance_UID", //!0020 000e UI REL Series Instance UID
127 "ID_Study_ID", //!0020 0010 SH REL Study ID
128 "ID_Series_Number", //!0020 0011 IS REL Series Number
129 "ID_Acquisition_Number", //!0020 0012 IS REL Acquisition Number
130 "ID_Image_Number", //!0020 0013 IS REL Image Number
131 "ID_Patient_Orientation", //!0020 0020 CS REL Patient Orientation
132 "ID_Image_Position", //!0020 0030 RET REL Image Position
133 "ID_Image_Position_Patient", //!0020 0032 DS REL Image Position Patient
134 "ID_Image_Orientation", //!0020 0035 RET REL Image Orientation
135 "ID_Image_Orientation_Patient", //!0020 0037 DS REL Image Orientation (Patient)
136 "ID_Location", //!0020 0050 RET REL Location
137 "ID_Frame_of_Reference_UID", //!0020 0052 UI REL Frame of Reference UID
138 "ID_Slice_Location", //!0020 1041 DS REL Slice Location
139 "ID_Image_Comments", //!0020 4000 LT REL Image Comments
140 "ID_Pixel_Spacing", //!0028 0030 DS IMG Pixel Spacing
141 "ID_Window_Center", //!0028 1050 DS IMG Window Center
142 "ID_Window_Width", //!0028 1051 DS IMG Window Width
143 "ID_Rescale_Intercept", //!0028 1052 CT IMG Rescale Intercept
144 "ID_Rescale_Slope", //!0028 1053 CT IMG Rescale Slope
149 // -------------------------------------------------------------------------
150 marGdcmDicom::marGdcmDicom( marParameters* p )
155 //EED Borrame FillDicomInfo( );
158 /** Conversion de wxString en string. */
159 //#define ws2s(as) (string(as.GetData()))
161 /** Conversion de string en wxString. */
162 //#define s2ws(s) (wxString((s).c_str()))
164 /** Conversion de C-string en wxString. */
165 //#define cs2ws(s) (wxString(s))
168 // -------------------------------------------------------------------------
169 wxArrayString marGdcmDicom::gdcmGetExamInfo( wxString directoryname ){
171 wxArrayString temparray;
172 temparray.Alloc( 60 );
174 wxDir dir(directoryname);
176 bool cont = dir.GetFirst( &filename, "*", wxDIR_FILES );
177 filename = directoryname + "/" + filename;
181 GDCM_NAME_SPACE::Header GdcmHeader( filename.c_str() );
182 temparray.Add( filename ); // "ID_File_Name",
183 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0016).c_str() );// "ID_SOP_Class_UID", //0008 0016 UI ID SOP Class UID
184 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0018).c_str() );// "ID_SOP_Instance_UID", //0008 0018 UI ID SOP Instance UID
185 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0020).c_str() );// "ID_Study_Date", //0008 0020 DA ID Study Date
186 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0021).c_str() );// "ID_Series_Date", //0008 0021 DA ID Series Date
187 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0022).c_str() );// "ID_Acquisition_Date", //0008 0022 DA ID Acquisition Date
188 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0023).c_str() );// "ID_Image_Date", //0008 0023 DA ID Image Date
189 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0030).c_str() );// "ID_Study_Time", //0008 0030 TM ID Study Time
190 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0031).c_str() );// "ID_Series_Time", //0008 0031 TM ID Series Time
191 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0032).c_str() );// "ID_Acquisition_Time", //0008 0032 TM ID Acquisition Time
192 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0033).c_str() );// "ID_Image_Time", //0008 0033 TM ID Image Time
193 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0060).c_str() );// "ID_Modality", //0008 0060 CS ID Modality
194 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0070).c_str() );// "ID_Manufacturer", //0008 0070 LO ID Manufacturer
195 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x0080).c_str() );// "ID_Institution_Name", //0008 0080 LO ID Institution Name
196 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x1030).c_str() );// "ID_Study_Description", //0008 1030 LO ID Study Description
197 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x103e).c_str() );// "ID_Series_Description", //0008 103e LO ID Series Description
198 temparray.Add( GdcmHeader.GetEntryByNumber(0x0008,0x1080).c_str() );// "ID_Admitting_Diagnoses_Description", //0008 1080 LO ID Admitting Diagnoses Description
199 temparray.Add( GdcmHeader.GetEntryByNumber(0x0010,0x0010).c_str() );// "ID_Patient_Name", //0010 0010 PN PAT Patient Name
200 temparray.Add( GdcmHeader.GetEntryByNumber(0x0010,0x0020).c_str() );// "ID_Patient_ID", //0010 0020 LO PAT Patient ID
201 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0015).c_str() );// "ID_Body_Part_Examined", //0018 0015 CS ACQ Body Part Examined
202 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0020).c_str() );// "ID_Scanning_Sequence", //0018 0020 CS ACQ Scanning Sequence
203 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0021).c_str() );// "ID_Sequence_Variant", //0018 0021 CS ACQ Sequence Variant
204 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0022).c_str() );// "ID_Scan_Options", //0018 0022 CS ACQ Scan Options
205 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0023).c_str() );// "ID_MR_Acquisition_Type", //0018 0023 CS ACQ MR Acquisition Type
206 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0024).c_str() );// "ID_Sequence_Name", //0018 0024 SH ACQ Sequence Name
207 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0050).c_str() );// "ID_Slice_Thickness", //0018 0050 DS ACQ Slice Thickness
208 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0080).c_str() );// "ID_Repetition_Time", //0018 0080 DS ACQ Repetition Time
209 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0081).c_str() );// "ID_Echo_Time", //0018 0081 DS ACQ Echo Time
210 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0082).c_str() );// "ID_Inversion_Time", //0018 0082 DS ACQ Inversion Time
211 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0083).c_str() );// "ID_Number_of_Averages", //0018 0083 DS ACQ Number of Averages
212 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0084).c_str() );// "ID_Imaging_Frequency", //0018 0084 DS ACQ Imaging Frequency
213 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0085).c_str() );// "ID_Imaged_Nucleus", //0018 0085 SH ACQ Imaged Nucleus
214 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0086).c_str() );// "ID_Echo_Number", //0018 0086 IS ACQ Echo Number
215 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0087).c_str() );// "ID_Magnetic_Field_Strength", //0018 0087 DS ACQ Magnetic Field Strength
216 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0088).c_str() );// "ID_Spacing_Between_Slices", //0018 0088 DS ACQ Spacing Between Slices
217 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0091).c_str() );// "ID_Echo_Train_Length", //0018 0091 IS ACQ Echo Train Length
218 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0093).c_str() );// "ID_Percent_Sampling", //0018 0093 DS ACQ Percent Sampling
219 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x0094).c_str() );// "ID_Percent_Phase_Field_of_View", //0018 0094 DS ACQ Percent Phase Field of View
220 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x1250).c_str() );// "ID_Receiving_Coil", //0018 1250 SH ACQ Receiving Coil
221 temparray.Add( GdcmHeader.GetEntryByNumber(0x0018,0x5100).c_str() );// "ID_Patient_Position", //0018 5100 CS ACQ Patient Position
222 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x000d).c_str() );// "ID_Study_Instance_UID", //0020 000d UI REL Study Instance UID
223 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x000e).c_str() );// "ID_Series_Instance_UID", //0020 000e UI REL Series Instance UID
224 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0010).c_str() );// "ID_Study_ID", //0020 0010 SH REL Study ID
225 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0011).c_str() );// "ID_Series_Number", //0020 0011 IS REL Series Number
226 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0012).c_str() );// "ID_Acquisition_Number", //0020 0012 IS REL Acquisition Number
227 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0013).c_str() );// "ID_Image_Number", //0020 0013 IS REL Image Number
228 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0020).c_str() );// "ID_Patient_Orientation", //0020 0020 CS REL Patient Orientation
229 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0030).c_str() );// "ID_Image_Position", //0020 0030 RET REL Image Position
230 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0032).c_str() );// "ID_Image_Position_Patient", //0020 0032 DS REL Image Position Patient
231 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0035).c_str() );// "ID_Image_Orientation", //0020 0035 RET REL Image Orientation
232 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0037).c_str() );// "ID_Image_Orientation_Patient", //0020 0037 DS REL Image Orientation (Patient)
233 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0050).c_str() );// "ID_Location", //0020 0050 RET REL Location
234 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x0052).c_str() );// "ID_Frame_of_Reference_UID", //0020 0052 UI REL Frame of Reference UID
235 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x1041).c_str() );// "ID_Slice_Location", //0020 1041 DS REL Slice Location
236 temparray.Add( GdcmHeader.GetEntryByNumber(0x0020,0x4000).c_str() );// "ID_Image_Comments", //0020 4000 LT REL Image Comments
237 temparray.Add( GdcmHeader.GetEntryByNumber(0x0028,0x0030).c_str() );// "ID_Pixel_Spacing", //0028 0030 DS IMG Pixel Spacing
238 temparray.Add( GdcmHeader.GetEntryByNumber(0x0028,0x1050).c_str() );// "ID_Window_Center", //0028 1050 DS IMG Window Center
239 temparray.Add( GdcmHeader.GetEntryByNumber(0x0028,0x1051).c_str() );// "ID_Window_Width", //0028 1051 DS IMG Window Width
240 temparray.Add( GdcmHeader.GetEntryByNumber(0x0028,0x1052).c_str() );// "ID_Rescale_Intercept", //0028 1052 CT IMG Rescale Intercept
241 temparray.Add( GdcmHeader.GetEntryByNumber(0x0028,0x1053).c_str() );// "ID_Rescale_Slope", //0028 1053 CT IMG Rescale Slope
250 // ----------------------------------------------------------------------------
251 GDCM_NAME_SPACE::DicomDir* marGdcmDicom::getGdcmDicomDir() {
256 // ----------------------------------------------------------------------------
257 void marGdcmDicom::CreateDicomFile( ){
258 wxString rootdir = getParameters( )->getStringParam( marParameters::e_dicom_images_directory );
259 // EED Borrame GDCM_NAME_SPACE::DicomDir *tmp_dicomDir = new GDCM_NAME_SPACE::DicomDir( rootdir.c_str() , true );
260 GDCM_NAME_SPACE::DicomDir *tmp_dicomDir = GDCM_NAME_SPACE::DicomDir::New();
261 tmp_dicomDir->SetFileName( (const char*)(rootdir.mb_str()) );
262 tmp_dicomDir->ParseDirectory();
263 wxString strDicomDir(rootdir + wxString(_DICOMFILENAME, wxConvUTF8) );
264 tmp_dicomDir->Write( (const char*)(strDicomDir.mb_str()) );
265 tmp_dicomDir->Delete();
268 // ----------------------------------------------------------------------------
269 void marGdcmDicom::FillDicomInfo(bool parseDir){
272 wxString rootdir = getParameters( )->getStringParam( marParameters::e_dicom_images_directory );
273 wxString strDICOMDIR( rootdir );
274 if (parseDir==false){
275 strDICOMDIR= strDICOMDIR + (wxChar)(_DICOMFILENAME);
277 //EED Borrame _dicomDir = new GDCM_NAME_SPACE::DicomDir( strDICOMDIR.c_str() , parseDir );
278 _dicomDir = GDCM_NAME_SPACE::DicomDir::New();
279 _dicomDir->SetFileName( (const char*)(strDICOMDIR.mb_str()) );
281 _dicomDir->ParseDirectory();
287 //-------------------------------------------------------------------------
288 void marGdcmDicom::setActualPatient(GDCM_NAME_SPACE::DicomDirPatient *patient){
289 _actualPatient = patient;
291 //-------------------------------------------------------------------------
292 void marGdcmDicom::setActualStudy(GDCM_NAME_SPACE::DicomDirStudy *study){
293 _actualStudy = study;
295 //-------------------------------------------------------------------------
296 void marGdcmDicom::setActualSerie(GDCM_NAME_SPACE::DicomDirSerie *serie){
297 _actualSerie = serie;
299 GDCM_NAME_SPACE::DicomDirImage *im;
301 im = serie->GetFirstImage();
302 while ( im ) { // on degouline les Images de cette serie
304 im = serie->GetNextImage();
306 setEndSlice( numOfImg );
308 //-------------------------------------------------------------------------
309 void marGdcmDicom::setIniSlice(int iniSlice){
312 //-------------------------------------------------------------------------
313 void marGdcmDicom::setEndSlice(int endSlice){
316 //-------------------------------------------------------------------------
317 GDCM_NAME_SPACE::DicomDirSerie *marGdcmDicom::getActualSerie(){
321 //-------------------------------------------------------------------------
322 GDCM_NAME_SPACE::DicomDirStudy* marGdcmDicom::getActualStudy(){
327 // -------------------------------------------------------------------------
328 bool marGdcmDicom::SerieVerificationEqImageSize( GDCM_NAME_SPACE::FileList *gdcmFileList ){
336 for (i=(*gdcmFileList).size(); i<(*gdcmFileList).size() ; i++){
337 GDCM_NAME_SPACE::File *gdcmFile = (GDCM_NAME_SPACE::File*)(*gdcmFileList)[i];
339 ww = gdcmFile->GetXSize();
340 hh = gdcmFile->GetYSize();
343 if (ww!=wwBak){ ok=false; }
348 if (hh!=hhBak){ ok=false; }
359 // -------------------------------------------------------------------------
360 bool marGdcmDicom::SerieVerificationEqImageOrientation( gdcmPub::FileList *gdcmFileList ){
362 float ox=-1,oy=-1,oz-1;
363 float oxBak=-99999,oyBak=-99999,ozBak=-99999;
364 gdcmPub::SerieHeader::GdcmHeaderList gdcmheaderlist = serieheader->GetGdcmFileList();
366 // gdcmPub::ListDicomDirImage::const_iterator itImage;
367 // itImage = (serie->GetDicomDirImages()).begin();
370 for ( gdcmPub::SerieHeader::GdcmHeaderList::const_iterator
371 it = gdcmheaderlist.begin();
372 it != gdcmheaderlist.end(); ++it ){
373 (*it)->GetImageOrientationPatient( iop );
374 normal[0] = iop[1]*iop[5] - iop[2]*iop[4];
375 normal[1] = iop[2]*iop[3] - iop[0]*iop[5];
376 normal[2] = iop[0]*iop[4] - iop[1]*iop[3];
378 falta terminar esto .....
382 prodouit_vectorial(ox,oy,oz , oxBak,oyBak,ozBak , &rox,&roy,&roz);
383 if ( (abs(rox)>0.000001) || (abs(roy)>0.000001) || (abs(roz)>0.000001)){
392 // The same image orientation verification
393 while (itImage != serie->GetDicomDirImages().end() ) { // on degouline les SERIES de cette study
396 wxString strImgOriPat=(*itImage)->GetEntryByNumber(0x0020, 0x0037).c_str();
399 if (strImgOriPat.Cmp( gdcmPub::GDCM_UNFOUND.c_str() )!=0){
401 strSub=strImgOriPat.Mid(0);
403 pp=strSub.First('\');
404 strNum=strSub.Mid(0, pp-1 );
405 strNum.ToDouble(&x1);
406 strSub=strSub.Mid(pp+1);
408 pp=strSub.First('\');
409 strNum=strSub.Mid(0, pp-1 );
410 strNum.ToDouble(&y1);
411 strSub=strSub.Mid(pp+1);
413 pp=strSub.First('\');
414 strNum=strSub.Mid(0, pp-1 );
415 strNum.ToDouble(&z1);
416 strSub=strSub.Mid(pp+1);
418 pp=strSub.First('\');
419 strNum=strSub.Mid(0, pp-1 );
420 strNum.ToDouble(&x2);
421 strSub=strSub.Mid(pp+1);
423 pp=strSub.First('\');
424 strNum=strSub.Mid(0, pp-1 );
425 strNum.ToDouble(&y2);
426 strSub=strSub.Mid(pp+1);
428 pp=strSub.First('\');
429 strNum=strSub.Mid(0, pp-1 );
430 strNum.ToDouble(&z2);
431 strSub=strSub.Mid(pp+1);
433 normalize(&x1,&y1,&z1);
434 normalize(&x2,&y2,&z2);
435 prodouit_vectorial(x1,y1,z1 , x2,y2,z2 , &ox,&oy,&oz);
436 normalize(&ox,&oy,&oz);
439 prodouit_vectorial(ox,oy,oz , oxBak,oyBak,ozBak , &rox,&roy,&roz);
440 if ( (abs(rox)>0.000001) || (abs(roy)>0.000001) || (abs(roz)>0.000001)){
452 // -------------------------------------------------------------------------
456 bool marGdcmDicom::SerieVerification( GDCM_NAME_SPACE::FileList *gdcmFileList ){
460 ok1=SerieVerificationEqImageSize(gdcmFileList);
461 // ok2=SerieVerificationEqImageOrientation(gdcmFileList);
462 // ok3=SerieVerificationDifImagePositionPatient(gdcmFileList);
464 wxMessageDialog *msg = new wxMessageDialog(NULL, _T("The size of all images aren't the same."), _T("Warning"), wxOK );
468 return ok1 && ok2 && ok3;
472 // -------------------------------------------------------------------------
473 void marGdcmDicom::CreateEmptyVoxel(){
475 GDCM_NAME_SPACE::File *gdcmFile=_gdcmFileList[0];
476 int wx = gdcmFile->GetXSize();
477 int wy = gdcmFile->GetYSize();
478 int wz = _gdcmFileList.size();
485 double spx= (double)gdcmFile->GetXSpacing ();
486 double spy= (double)gdcmFile->GetYSpacing ();
487 double spz= (double)gdcmFile->GetZSpacing ();
488 kVolume *vol =new kVolume( kVolume::USHORT, wx, wy, wz,spx, spy, spz, malloc(sizeof(unsigned short)*wx*wy*wz ) );
491 // -------------------------------------------------------------------------
492 void marGdcmDicom::PrepareLoadVolumeDispers(){
496 ExtactInterceptSlope();
500 // -------------------------------------------------------------------------
501 void marGdcmDicom::ExtactSpacing(){
502 GDCM_NAME_SPACE::File *gdcmFile=_gdcmFileList[0];
503 float sx = gdcmFile->GetXSpacing();
504 float sy = gdcmFile->GetYSpacing();
505 // float sz = gdcmFile->GetZSpacing();
508 float xx1 = (_gdcmFileList[0])->GetXOrigin();
509 float yy1 = (_gdcmFileList[0])->GetYOrigin();
510 float zz1 = (_gdcmFileList[0])->GetZOrigin();
512 (_gdcmFileList[1])->Load();
513 float xx2 = (_gdcmFileList[1])->GetXOrigin();
514 float yy2 = (_gdcmFileList[1])->GetYOrigin();
515 float zz2 = (_gdcmFileList[1])->GetZOrigin();
521 float sz=sqrt( xx*xx + yy*yy+ zz*zz );
523 getParameters( )->setDoubleParam( marParameters::e_voxel_x_dimension, sx );
524 getParameters( )->setDoubleParam( marParameters::e_voxel_y_dimension, sy );
525 getParameters( )->setDoubleParam( marParameters::e_voxel_z_dimension, sz );
527 // -------------------------------------------------------------------------
528 void marGdcmDicom::ExtactInterceptSlope(){
529 GDCM_NAME_SPACE::File *gdcmFile=_gdcmFileList[0];
530 float slope = gdcmFile->GetRescaleSlope();
531 float intercept = gdcmFile->GetRescaleIntercept();
532 getParameters( )->setDoubleParam( marParameters::e_RescaleIntercept , intercept );
533 getParameters( )->setDoubleParam( marParameters::e_RescaleSlope , slope );
537 // -------------------------------------------------------------------------
538 bool marGdcmDicom::loadFileDicom(void* p_vol,int *dim,char *namefile)
541 GDCM_NAME_SPACE::File *gdcmFile = GDCM_NAME_SPACE::File::New();
542 // gdcmFile->SetLoadMode(GDCM_NAME_SPACE::LD_NOSHADOW);
543 gdcmFile->SetFileName( namefile );
544 bool ok = gdcmFile->Load();
547 dataSize=sizeof(unsigned short)*dim[0]*dim[1];
549 bool manualLecture=false;
550 if ( (gdcmFile->GetTransferSyntaxName()=="Implicit VR - Little Endian") ||
551 (gdcmFile->GetTransferSyntaxName()=="Explicit VR - Little Endian") ||
552 (gdcmFile->GetTransferSyntaxName()=="Explicit VR - Big Endian") )
557 if (manualLecture==true){
558 long int offset = gdcmFile->GetPixelOffset();
559 FILE *ff=fopen(namefile, "r" );
560 fseek (ff,offset,SEEK_SET);
561 fread( (char*)p_vol , dataSize,1, ff);
564 // gdcm/Dics/dicomTS.dic
565 // champ DICOM >> 0002|0010
566 if (gdcmFile->GetTransferSyntaxName()=="Explicit VR - Big Endian")
570 char *pp=(char*)p_vol;
571 dataSize=dim[0]*dim[1];
572 for (i=0;i<dataSize;i++)
581 GDCM_NAME_SPACE::FileHelper *fh = GDCM_NAME_SPACE::FileHelper::New(gdcmFile);
582 memcpy((char*)p_vol, fh->GetImageDataRaw() , dataSize);
588 // -------------------------------------------------------------------------
591 bool marGdcmDicom::loadImage(int i)
595 GDCM_NAME_SPACE::File *gdcmFileTEMP;
597 gdcmFileTEMP = _gdcmFileList[i];
598 vtkImageData *vol = getVolume( )->castVtk();
599 void *p_vol=(void*)getVolume( )->castVtk()->GetScalarPointer(0,0,i);
600 vol->GetDimensions(dim);
601 bool ok=loadFileDicom( p_vol ,dim, (char *)gdcmFileTEMP->GetFileName().c_str() );
605 char *ss = (char *)gdcmFileTEMP->GetFileName().c_str();
606 _lstFileNotReaded.push_back( ss );
613 // -------------------------------------------------------------------------
615 void marGdcmDicom::loadImage(int i)
618 GDCM_NAME_SPACE::File *gdcmFileTEMP=_gdcmFileList[i];
619 GDCM_NAME_SPACE::File *gdcmFile = GDCM_NAME_SPACE::File::New();
620 gdcmFile->SetLoadMode(GDCM_NAME_SPACE::LD_NOSHADOW);
621 gdcmFile->SetFileName( gdcmFileTEMP->GetFileName().c_str() );
622 bool ok = gdcmFile->Load();
623 offset = gdcmFile->GetPixelOffset();
626 std::ifstream infile;
627 FILE *ff=fopen(gdcmFileTEMP->GetFileName().c_str(), "r" );
628 vtkImageData *vol = getVolume( )->castVtk();
630 vol->GetDimensions(dim);
631 int US=sizeof(unsigned short);
632 int dataSize=US*dim[0];
634 for (y=0;y<sizeY;y++){
635 fseek (ff,offset,SEEK_SET);
636 void *p_vol = vol->GetScalarPointer(0,y,i);
637 fread( (char*)p_vol , dataSize,1, ff);
638 offset=offset+dataSize;
643 // -------------------------------------------------------------------------
646 void marGdcmDicom::loadImage(int i)
649 GDCM_NAME_SPACE::File *gdcmFileTEMP;
650 gdcmFileTEMP = _gdcmFileList[i];
653 GDCM_NAME_SPACE::File *gdcmFile = GDCM_NAME_SPACE::File::New();
654 gdcmFile->SetLoadMode(GDCM_NAME_SPACE::LD_NOSHADOW);
655 gdcmFile->SetFileName( gdcmFileTEMP->GetFileName().c_str() );
656 bool ok = gdcmFile->Load();
657 long int offset = gdcmFile->GetPixelOffset();
660 std::ifstream infile;
661 infile.open( gdcmFileTEMP->GetFileName().c_str() , ifstream::in );
662 if (infile.is_open()==true){
663 vtkImageData *vol = getVolume( )->castVtk();
664 void *p_vol = vol->GetScalarPointer(0,0,i);
666 vol->GetDimensions(dim);
667 int dataSize=2*dim[0]*dim[1];
668 int US=sizeof(unsigned short);
669 char *temp=new char [dataSize];
670 infile.seekg( 0 , ios_base::beg );
671 // int a=infile.readsome( (char*)p_vol , dataSize );
672 // int a=infile.readsome( temp , dataSize );
675 while (infile.good())
677 length += infile.readsome (temp,100);
684 // -------------------------------------------------------------------------
689 void marGdcmDicom::loadImage(int i){
690 vtkGdcmReader *gdcmReader = NULL;
692 GDCM_NAME_SPACE::File *gdcmFile;
693 gdcmFile = _gdcmFileList[i];
696 gdcmReader = vtkGdcmReader::New();
697 const char *fileName = gdcmFile->GetFileName().c_str();
698 gdcmReader->SetFileName( fileName );
699 gdcmReader->UpdateWholeExtent();
701 //To simplyfy calculation later I turn Origin to (0, 0, 0)
702 //this shouldn't be 'trop grave'
703 vtkImageChangeInformation *change = vtkImageChangeInformation::New();
705 change->SetInput( gdcmReader->GetOutput() );
706 change->SetOutputOrigin( 0, 0, 0);
708 //Our algorithm are made based on unsigned short pixel/voxel:
709 //We need to cast our imagedata
710 vtkImageCast *cast = vtkImageCast::New();
711 cast->SetInput( change->GetOutput() );
712 cast->SetOutputScalarTypeToUnsignedShort();
713 cast->Update(); //important
716 vtkImageData *imagedata = cast->GetOutput();
717 vtkImageData *vol = getVolume( )->castVtk();
719 void *p_imagedata = imagedata->GetScalarPointer(0,0,0);
720 void *p_vol = vol->GetScalarPointer(0,0,i);
722 imagedata->GetDimensions(dim);
724 memcpy( p_vol, p_imagedata , sizeof(unsigned short)*dim[0]*dim[1] );
727 if(gdcmReader) gdcmReader->Delete();
732 // -------------------------------------------------------------------------
733 void marGdcmDicom::Cleaning_gdcmFileList(){
734 GDCM_NAME_SPACE::File *gdcmFile;
736 for (i=0; i<_gdcmFileList.size(); i++ ){
737 gdcmFile=_gdcmFileList[i];
740 _gdcmFileList.clear();
743 // -------------------------------------------------------------------------
744 void marGdcmDicom::CreateSerieHelper(){ // Virtual
746 rootdir = getParameters( )->getStringParam( marParameters::e_dicom_images_directory );
747 GDCM_NAME_SPACE::DicomDirImage *im;
750 _serieHelper = new GDCM_NAME_SPACE::SerieHelper();
752 im = _actualSerie->GetFirstImage();
753 while ( im ) { // on degouline les Images de cette serie
755 if ((iSlice>=_iniSlice) && (iSlice<=_endSlice)){
756 wxString tmp( rootdir);
758 tmp=tmp+im->GetEntryValue(0x0004, 0x1500).c_str(); // File name
759 _serieHelper->AddFileName( tmp.c_str() );
762 im = _actualSerie->GetNextImage();
765 _serieHelper->OrderGdcmFileList( _serieHelper->GetFirstCoherentFileList() );
769 GDCM_NAME_SPACE::SerieHelper *serieHelper = new GDCM_NAME_SPACE::SerieHelper();
771 im = _actualSerie->GetFirstImage();
772 while ( im ) { // on degouline les Images de cette serie
774 if ((iSlice>=_iniSlice) && (iSlice<=_endSlice)){
775 wxString tmp( rootdir);
777 tmp=tmp+im->GetEntryValue(0x0004, 0x1500).c_str(); // File name
778 serieHelper->AddFileName( tmp.c_str() );
781 im = _actualSerie->GetNextImage();
784 GDCM_NAME_SPACE::GdcmFileList* tmpGdcmFileList=serieHelper->GetFirstCoherentFileList();
785 serieHelper->OrderGdcmFileList( tmpGdcmFileList );
786 for (int i=0; i <tmpGdcmFileList->size() ; i++){
787 _gdcmFileList.push_back( (*tmpGdcmFileList)[i] );
792 Cleaning_gdcmFileList();
795 GDCM_NAME_SPACE::File *gdcmFile;
797 im = _actualSerie->GetFirstImage();
798 while ( im ) { // on degouline les Images de cette serie
799 if ((iSlice>=_iniSlice) && (iSlice<=_endSlice)){
800 wxString fileName( rootdir);
801 fileName=fileName+"/";
802 fileName=fileName+im->GetEntryString(0x0004, 0x1500).c_str(); // File name
804 if (_gdcmFileList.size()==0){
805 //EED Borrame gdcmFile = new GDCM_NAME_SPACE::File(fileName.c_str());
806 gdcmFile = GDCM_NAME_SPACE::File::New();
807 gdcmFile->SetFileName( fileName.c_str() );
809 gdcmFile = GDCM_NAME_SPACE::File::New();
810 //EED Borrame GDCM_NAME_SPACE::DocEntry *entry = im->GetFirstString();
811 GDCM_NAME_SPACE::DocEntry *entry = im->GetFirstEntry();
813 //EED Borrame GDCM_NAME_SPACE::ValEntry *newEntry = new GDCM_NAME_SPACE::ValEntry(entry->GetDictEntry());
814 GDCM_NAME_SPACE::DocEntry *newEntry = new GDCM_NAME_SPACE::DocEntry();
816 newEntry->Copy(entry);
817 gdcmFile->AddEntry(newEntry);
818 entry = im->GetNextEntry();
820 gdcmFile->SetFileName( fileName.c_str() );
822 _gdcmFileList.push_back(gdcmFile);
824 im = _actualSerie->GetNextImage();
829 GDCM_NAME_SPACE::File *gdcmFile;
831 im = _actualSerie->GetFirstImage();
832 while ( im ) { // on degouline les Images de cette serie
833 if ((iSlice>=_iniSlice) && (iSlice<=_endSlice)){
834 wxString fileName( rootdir);
835 fileName=fileName+_T("/");
836 fileName=fileName + wxString(im->GetEntryString(0x0004, 0x1500).c_str(), wxConvUTF8); // File name
838 gdcmFile = GDCM_NAME_SPACE::File::New();
839 gdcmFile->SetFileName( (const char*)(fileName.mb_str()) );
840 _gdcmFileList.push_back(gdcmFile);
842 im = _actualSerie->GetNextImage();
847 GDCM_NAME_SPACE::SerieHelper *serieHelper = GDCM_NAME_SPACE::SerieHelper::New();
848 serieHelper->OrderFileList( &_gdcmFileList );
851 if (getParameters( )->getInvestSliceOrder()==true){
852 GDCM_NAME_SPACE::File *tmpGdcmFile;
853 int i,size=_gdcmFileList.size();
854 for (i=0, size=_gdcmFileList.size()-1 ; i<=size; i++, size--){
855 tmpGdcmFile=_gdcmFileList[i];
856 _gdcmFileList[i]=_gdcmFileList[size];
857 _gdcmFileList[size]=tmpGdcmFile;
861 if ( !SerieVerification( &_gdcmFileList ) ){
862 wxMessageDialog *msg = new wxMessageDialog(NULL, _T("This series doesn't look like a good series for Maracas.\nDo you want to continue?"), _T("Warning"), wxOK | wxCANCEL );
869 //-------------------------------------------------------------------------
870 void marGdcmDicom::loadActualSerie( wxGauge* gauge)
872 loadVolume( true , gauge);
875 // -------------------------------------------------------------------------
876 void marGdcmDicom::loadVolume( bool force , wxGauge *gauge)
879 PrepareLoadVolumeDispers();
885 vtkImageData *vol = getVolume( )->castVtk();
886 vol->GetDimensions(dim);
887 for (i=0; i<dim[2]; i++){
893 vtkGdcmReader *gdcmReader = NULL;
895 if( force || !getVolume() ){
899 ExtactInterceptSlope();
900 GDCM_NAME_SPACE::File *gdcmFile;
901 GDCM_NAME_SPACE::GdcmFileList *lstGdcmFile = _serieHelper->GetFirstCoherentFileList();
902 gdcmReader = vtkGdcmReader::New();
904 for ( i=0;i<lstGdcmFile->size();i++){
905 gdcmFile = (*lstGdcmFile)[i];
906 gdcmReader->AddFileName( gdcmFile->GetFileName().c_str() );
908 gdcmReader->UpdateWholeExtent();
909 gdcmReader->Update();
912 marProgressObserver *progressEvent = marProgressObserver::New();
913 progressEvent->FrameGauge = gauge;
914 //gdcmReader->AddObserver( vtkCommand::ProgressEvent, progressEvent);
915 progressEvent->Delete();
917 //To simplyfy calculation later I turn Origin to (0, 0, 0)
918 //this shouldn't be 'trop grave'
919 vtkImageChangeInformation *change = vtkImageChangeInformation::New();
921 change->SetInput( gdcmReader->GetOutput() );
922 change->SetOutputOrigin( 0, 0, 0);
924 //Our algorithm are made based on unsigned short pixel/voxel:
925 //We need to cast our imagedata
926 vtkImageCast *cast = vtkImageCast::New();
927 cast->SetInput( change->GetOutput() );
928 cast->SetOutputScalarTypeToUnsignedShort();
929 cast->Update(); //important
931 //FIXME: kVolume doesn't need to be -again- matrix rotated (done in vtkGdcmReader)!!
932 kVolume *volume = new kVolume( cast->GetOutput() );
936 if(gdcmReader) gdcmReader->Delete();
942 // -------------------------------------------------------------------------
943 void marGdcmDicom::reset( ){
945 Cleaning_gdcmFileList();
952 // -------------------------------------------------------------------------
953 wxString marGdcmDicom::GetPatientName(){
954 GDCM_NAME_SPACE::File *gdcmFile=_gdcmFileList[0];
955 return wxString( wxString(gdcmFile->GetEntryString(0x0010,0x0010).c_str(), wxConvUTF8) ).Trim();//0010 0010 PN PAT Patient Name
958 // -------------------------------------------------------------------------
959 void marGdcmDicom::copyFrom( const marObject& from )
963 // -------------------------------------------------------------------------
964 bool marGdcmDicom::save( std::ofstream& os )
966 /* int s = _actualStudy.length( );
968 os.write( ( const char* )&s, sizeof( int ) );
969 os.write( ( char* )_actualStudy.c_str( ), s * sizeof( char ) );
971 s = _actualSerie.length( );
973 os.write( ( const char* )&s, sizeof( int ) );
974 os.write( ( char* )_actualSerie.c_str( ), s * sizeof( char ) );*/
976 for(std::vector<SerieInfo>::iterator it1 = m_DicomInfo.begin();
977 it1 != m_DicomInfo.end(); it1++ )
979 for(std::vector<wxArrayString>::iterator it2 = it1->begin();
980 it2 != it1->end(); it2++ )
982 for(int i=0; i<it2->GetCount(); i++)
984 //wxString temp( it2->Item(i) );
985 os << it2->Item(i); //temp;
993 // -------------------------------------------------------------------------
994 bool marGdcmDicom::load( std::ifstream& is )
1000 is.read( ( char* )&s, sizeof( int ) );
1001 _actualStudy.resize( s );
1002 is.read( ( char* )_actualStudy.c_str( ), s * sizeof( char ) );
1003 is.read( ( char* )&s, sizeof( int ) );
1004 _actualSerie.resize( s );
1005 is.read( ( char* )_actualSerie.c_str( ), s * sizeof( char ) );*/
1007 for(std::vector<SerieInfo>::iterator it1 = m_DicomInfo.begin();
1008 it1 != m_DicomInfo.end(); it1++ )
1010 for(std::vector<wxArrayString>::iterator it2 = it1->begin();
1011 it2 != it1->end(); it2++ )
1013 for(int i=0; i<it2->GetCount(); i++)
1017 it2->Add( wxString(temp.c_str(), wxConvUTF8) );
1026 // -------------------------------------------------------------------------
1027 // -------------------------------------------------------------------------
1028 // -------------------------------------------------------------------------
1030 marGdcmDicomILPD::marGdcmDicomILPD( marParameters* p )
1034 // -------------------------------------------------------------------------
1035 void marGdcmDicomILPD::CreateSerieHelper()
1037 GDCM_NAME_SPACE::File *gdcmFile;
1038 Cleaning_gdcmFileList();
1039 int i,max=_lstString.size();
1042 if (_gdcmFileList.size()==0){
1043 gdcmFile = GDCM_NAME_SPACE::File::New();
1044 gdcmFile->SetLoadMode(GDCM_NAME_SPACE::LD_ALL);
1045 gdcmFile->SetFileName( _lstString[i] -> c_str() );
1046 bool ok = gdcmFile->Load();
1048 gdcmFile = GDCM_NAME_SPACE::File::New();
1049 gdcmFile->SetFileName( _lstString[i] -> c_str() );
1051 _gdcmFileList.push_back(gdcmFile);
1055 // -------------------------------------------------------------------------