From: regrain Date: Mon, 7 Feb 2005 09:51:01 +0000 (+0000) Subject: * gdcmPython/gdcm.i : bug fix. Now string are correctly converted in python X-Git-Tag: Version1.0.bp~64 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=25c9af365d9221bd45f3fbe27275ff0f66a265b1;p=gdcm.git * gdcmPython/gdcm.i : bug fix. Now string are correctly converted in python string type * src/gdcmDict.h : remove commented code * src/gdcmDocument.cxx : initialize values * src/gdcmFile.cxx : bug fix when reading values * gdcmPython/demo/ : change file names. Remove useless files -- BeNours --- diff --git a/ChangeLog b/ChangeLog index d7b8f046..f035da73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,19 @@ -2005-04-31 Benoit Regrain +2005-02-07 Benoit Regrain + * gdcmPython/gdcm.i : bug fix. Now string are correctly converted in python + string type + * src/gdcmDict.h : remove commented code + * src/gdcmDocument.cxx : initialize values + * src/gdcmFile.cxx : bug fix when reading values + * gdcmPython/demo/ : change file names. Remove useless files + +2005-02-04 Benoit Regrain * src/gdcmFile.cxx : remove the default array of initialization. The static array contained pointers to non-static values (comming from strings). To have coherences, when creating files, these values can't be static. So, the array can't be static, too ! To simplify, the array have been replaced by repeted lines to insert values in the File -2005-03-31 Benoit Regrain +2005-02-03 Benoit Regrain * src/gdcmBinEntry.cxx : bug fix for BIG_ENDIAN part when writing the content * gdcmPython/gdcm.i : rename gdcmHeader to gdcmHelper diff --git a/gdcmPython/demo/CMakeLists.txt b/gdcmPython/demo/CMakeLists.txt index 66da5850..b3bde10c 100644 --- a/gdcmPython/demo/CMakeLists.txt +++ b/gdcmPython/demo/CMakeLists.txt @@ -19,8 +19,8 @@ IF(PYTHON_EXECUTABLE) ADD_TEST(Python-PrintDict ${PYTHON_EXECUTABLE} ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintDict.py ) - ADD_TEST(Python-PrintHeader ${PYTHON_EXECUTABLE} - ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintHeader.py + ADD_TEST(Python-PrintFile ${PYTHON_EXECUTABLE} + ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintFile.py ) ADD_TEST(Python-PrintDicomDir ${PYTHON_EXECUTABLE} ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintDicomDir.py @@ -34,8 +34,8 @@ ENDIF(PYTHON_EXECUTABLE) # Copy all the demo directory content to the cmake bin # Without it, tests can't be launched CONFIGURE_FILE( - ${GDCM_SOURCE_DIR}/gdcmPython/demo/PrintHeader.py.in - ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintHeader.py + ${GDCM_SOURCE_DIR}/gdcmPython/demo/PrintFile.py.in + ${GDCM_BINARY_DIR}/gdcmPython/demo/PrintFile.py ) CONFIGURE_FILE( diff --git a/gdcmPython/demo/PrintDicomDir.py b/gdcmPython/demo/PrintDicomDir.py deleted file mode 100644 index a4c534f3..00000000 --- a/gdcmPython/demo/PrintDicomDir.py +++ /dev/null @@ -1,27 +0,0 @@ -from gdcmPython import * -import sys - -### Get filename from command line or default it -try: - fileName = sys.argv[1] -except IndexError: - fileName = os.path.join(GDCM_DATA_PATH, "DICOMDIR") - -try: - printLevel = int(sys.argv[2]) -except IndexError: - printLevel = 1 - -### Build the header element list -dicomdir = gdcmDicomDir(fileName) -if not dicomdir.IsReadable(): - print "The '", fileName, "' DicomDir is not readable with gdcm. Sorry." - sys.exit() - -print "##############################################################" -print "## Display all the elements and their respective values" -print "## found in the ", fileName, " file." -print "##############################################################" -dicomdir.SetPrintLevel(-1) -dicomdir.Print() - diff --git a/gdcmPython/demo/PrintHeader.py.in b/gdcmPython/demo/PrintFile.py.in similarity index 100% rename from gdcmPython/demo/PrintHeader.py.in rename to gdcmPython/demo/PrintFile.py.in diff --git a/gdcmPython/demo/PrintHeader.py b/gdcmPython/demo/PrintHeader.py deleted file mode 100644 index 1019c49a..00000000 --- a/gdcmPython/demo/PrintHeader.py +++ /dev/null @@ -1,42 +0,0 @@ -from gdcmPython.core import * -import sys -import os - -### Get filename from command line or default it -try: - fileName = sys.argv[1] -except IndexError: - fileName = os.path.join(GDCM_DATA_PATH, "test.acr") - -try: - printLevel = int(sys.argv[2]) -except IndexError: - printLevel = 1 - -#if not os.path.isfile(FileName): -# print "Cannot open file ", FileName -# sys.exit() - -# On debugging purposes uncomment the next line -#s = raw_input("Hit any key in this window to exit") - -### Build the header element list -print fileName, type(fileName) -header = gdcm.Header(fileName) -if not header.IsReadable(): - print "The '", fileName, "' file is not readable with gdcm. Sorry." - sys.exit() - -print "##############################################################" -print "### Display all the elements and their respective values" -print "## found in the ", fileName, " file." -print "##############################################################" - -header.InitTraversal() -val=header.GetNextEntry() -while(val): - val.Print() - print "" - val=header.GetNextEntry() -val=None - diff --git a/gdcmPython/demo/vtkGdcmDemo.py b/gdcmPython/demo/vtkGdcmDemo.py deleted file mode 100644 index 12802960..00000000 --- a/gdcmPython/demo/vtkGdcmDemo.py +++ /dev/null @@ -1,215 +0,0 @@ -## A small demo that displays with VTK a dicom image parsed with gdcm. -## Warning: the parsing of header of the dicom file is done with gdcm -## but the process of in-memory loading of the image is performed -## by vtkImageReader (classical vtk operator). Since vtkImageReader -## has no special knowledge of Dicom file format, this demo -## will only work for a restrained sub-set of Dicom files (basically -## non compressed and with "HighBit + 1 != BitsStored"). -## When those conditions are not met try using vtkgdcmReader.py... -import sys -import vtk -from gdcmPython import gdcmHeader - -class vtkHistogram: - '''Some medical images might have a poor dynamic. This is because - some additional visual tags-like the patient name- are sometimes - written/drawn on top of the image : to avoid interference with - the image itself, the level used for this additional text is - usually way above the maximum level of the image. Hence we use - some cumulative histograme die-hard technique to remove some - arbitrary small portion of the dynamic.''' - def __init__(self, imagereader): - self.vtkReader = imagereader - self.__Histo = None - self.__CumulHisto = None - self.__LevelMin = self.vtkReader.GetOutput().GetScalarRange()[0] - self.__LevelMax = self.vtkReader.GetOutput().GetScalarRange()[1] - self.__NumberOfBins = 255 # See VTKImageAccumulate - self.__Spacing = (self.__LevelMax - self.__LevelMin)/self.__NumberOfBins - - def ComputeHisto(self): - self.__Histo = vtk.vtkImageAccumulate() - self.__Histo.SetComponentExtent(0, self.__NumberOfBins, 0, 0, 0, 0) - self.__Histo.SetInput(self.vtkReader.GetOutput()) - self.__Histo.SetComponentSpacing(self.__Spacing, 0.0, 0.0) - self.__Histo.Update() - - def ComputeCumulativeHisto(self): - ''' Compyte the Cumulative histogram of the image.''' - if not self.__Histo: - self.ComputeHisto() - self.__CumulHisto = [] - histo = self.__Histo.GetOutput() - self.__CumulHisto.append(int(histo.GetScalarComponentAsDouble(0,0,0,0))) - for i in range(1, self.__NumberOfBins): - value = int(histo.GetScalarComponentAsDouble(i,0,0,0)) - self.__CumulHisto.append( self.__CumulHisto[i-1] + value) - - def GetTruncateLevels(self, LostPercentage): - ''' Compute the level below which (respectively above which) - the LostPercentage percentage of the pixels shall be disregarded. - ''' - if LostPercentage < 0.0 or LostPercentage >1.0: - print " vtkHistogram::GetTruncateLevels: defaulting to 5%" - LostPercentage = 0.05 - if not self.__CumulHisto: - self.ComputeCumulativeHisto() - NumPixels = self.__CumulHisto[self.__NumberOfBins - 1] - NumLostPixels = NumPixels * LostPercentage - AboveLevel = None - BelowLevel = None - # FIXME : not really clean loop... - for i in range(0, self.__NumberOfBins-1): - if not BelowLevel: - if self.__CumulHisto[i] > NumLostPixels: - BelowLevel = self.__LevelMin + self.__Spacing * i - if not AboveLevel: - if self.__CumulHisto[i] > NumPixels - NumLostPixels: - AboveLevel = self.__LevelMin + self.__Spacing * i - if not AboveLevel or not BelowLevel: - print " vtkHistogram::GetTruncateLevels: Mistakes were made..." - return BelowLevel, AboveLevel - -class vtkGdcmImage(gdcmHeader): - ''' All informations required for VTK display - * VTK pipeline - * Lut (or associated Window/Level reductive control parameters)''' - def __init__(self, filename): - gdcmHeader.__init__(self, filename) - self.filename = filename - # LUT reductive parameters - self.__LevelMin = 0 # Minimum value of pixel intensity - self.__LevelMax = 0 # Maximun value of pixel intensity - self.__Level = 0 # Current Level value (treshold below - # which the image is represented as black) - self.__Window = 0 # Width of displayed pixels (linearly). - # Above Level + Window pixel are represented - # as white. - self.__VTKplaneActor = None - self.vtkSetup() - - def VTKreaderSetup(self): - self.__VTKReader = vtk.vtkImageReader() - self.__VTKReader.SetFileName(self.filename) - type = self.GetPixelType() - if type == "8U": - self.__VTKReader.SetDataScalarTypeToUnsignedChar() - elif type == "8S": - self.__VTKReader.SetDataScalarTypeTodChar() - elif type == "16U": - self.__VTKReader.SetDataScalarTypeToUnsignedShort() - elif type == "16S": - self.__VTKReader.SetDataScalarTypeToShort() - self.__VTKReader.SetDataByteOrderToLittleEndian() - #self.__VTKReader.SetDataByteOrderToBigEndian() - else: - print "vtkGdcmImage::VTKreaderSetup: unkown encoding:", type - sys.exit() - self.__VTKReader.SetHeaderSize(self.GetPixelOffset()) - self.__VTKReader.SetDataExtent (0, self.GetXSize()-1, - 0, self.GetYSize()-1, - 1, 1) - self.__VTKReader.UpdateWholeExtent() - - def vtkSetup(self, orgx = -0.5, orgy = -0.5, - ix = 0.5, iy = -0.5, jx = -0.5, jy = 0.5): - # ImageReader ---> Texture \ - # | ==> PlaneActor - # PlaneSource ---> PolyDataMapper / - self.VTKreaderSetup() - ### LookupTable - self.__VTKtable = vtk.vtkLookupTable() - self.__VTKtable.SetNumberOfColors(1000) - self.__VTKtable.SetTableRange(0,1000) - self.CallibrateWindowLevel() # calls the SetTableRange - self.__VTKtable.SetSaturationRange(0,0) - self.__VTKtable.SetHueRange(0,1) - self.__VTKtable.SetValueRange(0,1) - self.__VTKtable.SetAlphaRange(1,1) - self.__VTKtable.Build() - ### Texture - self.__VTKtexture = vtk.vtkTexture() - self.__VTKtexture.SetInput(self.__VTKReader.GetOutput()) - self.__VTKtexture.InterpolateOn() - self.__VTKtexture.SetLookupTable(self.__VTKtable) - ### PlaneSource - self.__VTKplane = vtk.vtkPlaneSource() - self.__VTKplane.SetOrigin( orgx, orgy, 0.0) - self.__VTKplane.SetPoint1( ix, iy, 0.0) - self.__VTKplane.SetPoint2( jx, jy, 0.0) - ### PolyDataMapper - self.__VTKplaneMapper = vtk.vtkPolyDataMapper() - self.__VTKplaneMapper.SetInput(self.__VTKplane.GetOutput()) - ### Actor - self.__VTKplaneActor = vtk.vtkActor() - self.__VTKplaneActor.SetTexture(self.__VTKtexture) - self.__VTKplaneActor.SetMapper(self.__VTKplaneMapper) - self.__VTKplaneActor.PickableOn() - - def CallibrateWindowLevel(self): - vtkreader = self.__VTKReader - self.__LevelMin = vtkreader.GetOutput().GetScalarRange()[0] - self.__LevelMax = vtkreader.GetOutput().GetScalarRange()[1] - histo = vtkHistogram(vtkreader) - self.__Level, above = histo.GetTruncateLevels(0.05) - self.__Window = above - self.__Level - self.__VTKtable.SetTableRange(self.__Level, - self.__Level + self.__Window) - - def GetVTKActor(self): - return self.__VTKplaneActor - -###################################################################### -import os -from gdcmPython import GDCM_DATA_PATH - -### Get filename from command line or default it -try: - FileName = sys.argv[1] -except IndexError: - FileName = os.path.join(GDCM_DATA_PATH, "test.acr") - -if not os.path.isfile(FileName): - print "Cannot open file ", FileName - sys.exit() - -### The default vtkImageReader is unable to read some type of images: -check = gdcmHeader(FileName) -if not check.IsReadable(): - print "The ", FileName, " file is not " - print " readable with gdcm. Sorry." - sys.exit() -check = check.GetEntry() -try: - HighBit = check["High Bit"] - if len(HighBit) == 0 or HighBit == "gdcm::Unfound": - raise KeyError -except KeyError: - print "Gdcm couldn't find the Bits Allocated Dicom tag in file ", FileName - sys.exit() -try: - BitsStored = check["Bits Stored"] - if len(BitsStored) == 0 or BitsStored == "gdcm::Unfound": - raise KeyError -except KeyError: - print "Gdcm couldn't find the Bits Stored Dicom tag in file ", FileName - sys.exit() -if int(HighBit) + 1 != int(BitsStored): - print "vtkImageReader cannot read the file ", FileName - print " because the High Bit is offseted from the BitsStored." - print " You should consider using vtkGdcmReader as opposed to the" - print " vtkImageReader python class present in this demo. Please" - print " see gdcmPython/demo/vtkGdcmReader.py for a demo." - sys.exit() - -### Display in a vtk RenderWindow -image = vtkGdcmImage(FileName) -ren = vtk.vtkRenderer() -renwin = vtk.vtkRenderWindow() -renwin.AddRenderer(ren) -iren = vtk.vtkRenderWindowInteractor() -iren.SetRenderWindow(renwin) -ren.AddActor(image.GetVTKActor()) -ren.SetBackground(0,0,0.5) -renwin.Render() -iren.Start() diff --git a/gdcmPython/demo/vtkGdcmReader.py b/gdcmPython/demo/vtkGdcmReader.py deleted file mode 100644 index f9818065..00000000 --- a/gdcmPython/demo/vtkGdcmReader.py +++ /dev/null @@ -1,65 +0,0 @@ -## This demo illustrates the usage of the python-wrappers of vtkGdcmReader -## native C++ vtk class. vtkGdcmReader.cxx is a C++ level wrapper of -## gdcm which offers a vtk class vtkGdcmReader (inheriting from vtkImageReader, -## see gdcm/vtk/vtkGdcmReader.cxx). vtkgdcmPython wraps this class for -## python (by using vtk wrappers). -from vtk import * -from gdcmPython import * -from gdcmPython.vtkgdcmPython import * -import sys - -### Get filename from command line or default it -try: - FileName = sys.argv[1] -except IndexError: - FileName = os.path.join(GDCM_DATA_PATH, "test.acr") - -### Build the header element list -test = gdcmHeader(FileName) -if not test.IsReadable(): - print "The ", FileName, " file is not readable with gdcm. Sorry." - sys.exit() -del test -toDisplay = vtkGdcmReader() -toDisplay.AddFileName(FileName) -###toDisplay.DebugOn() - -VTKtable = vtkLookupTable() -VTKtable.SetNumberOfColors(1000) -VTKtable.SetTableRange(0,1000) -VTKtable.SetSaturationRange(0,0) -VTKtable.SetHueRange(0,1) -VTKtable.SetValueRange(0,1) -VTKtable.SetAlphaRange(1,1) -VTKtable.Build() - -VTKtexture = vtkTexture() -VTKtexture.SetInput(toDisplay.GetOutput()) -VTKtexture.InterpolateOn() -VTKtexture.SetLookupTable(VTKtable) - -VTKplane = vtkPlaneSource() -VTKplane.SetOrigin( -0.5, -0.5, 0.0) -VTKplane.SetPoint1( 0.5, -0.5, 0.0) -VTKplane.SetPoint2( -0.5, 0.5, 0.0) - -VTKplaneMapper = vtkPolyDataMapper() -VTKplaneMapper.SetInput(VTKplane.GetOutput()) - -VTKplaneActor = vtkActor() -VTKplaneActor.SetTexture(VTKtexture) -VTKplaneActor.SetMapper(VTKplaneMapper) -VTKplaneActor.PickableOn() - -ren = vtkRenderer() -renwin = vtkRenderWindow() -renwin.AddRenderer(ren) -iren = vtkRenderWindowInteractor() -iren.SetRenderWindow(renwin) -ren.AddActor(VTKplaneActor) -ren.SetBackground(0,0,0.5) -renwin.Render() -iren.Start() - - - diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i index 4148b717..399f6f4f 100644 --- a/gdcmPython/gdcm.i +++ b/gdcmPython/gdcm.i @@ -281,11 +281,21 @@ typedef unsigned long long uint64_t; //////////////////// STL string versus Python str //////////////////////// // Convertion returning a C++ string. -%typemap(out) string, std::string +%typemap(out) std::string { $result = PyString_FromString(($1).c_str()); } +%typemap(out) string +{ + $result = PyString_FromString(($1).c_str()); +} + +%typemap(out) std::string const & +{ + $result = PyString_FromString(($1)->c_str()); +} + // Convertion of incoming Python str to STL string %typemap(python, in) const std::string, std::string { diff --git a/src/gdcmDict.h b/src/gdcmDict.h index 36e57984..56db9453 100644 --- a/src/gdcmDict.h +++ b/src/gdcmDict.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDict.h,v $ Language: C++ - Date: $Date: 2005/02/02 15:07:41 $ - Version: $Revision: 1.37 $ + Date: $Date: 2005/02/07 09:51:03 $ + Version: $Revision: 1.38 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -32,9 +32,6 @@ namespace gdcm //----------------------------------------------------------------------------- typedef std::string DictKey; typedef std::map TagKeyHT; -//typedef std::list EntryNamesList; -//typedef std::map > EntryNamesByCatMap; //----------------------------------------------------------------------------- /** * \brief Dict acts a memory representation of a dicom dictionary i.e. diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index bc70151d..9c12f0ce 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2005/02/06 14:39:35 $ - Version: $Revision: 1.224 $ + Date: $Date: 2005/02/07 09:51:03 $ + Version: $Revision: 1.225 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -416,7 +416,7 @@ std::ifstream *Document::OpenFile() return 0; } - uint16_t zero; + uint16_t zero = 0; Fp->read((char*)&zero, (size_t)2); if( Fp->eof() ) { @@ -439,7 +439,7 @@ std::ifstream *Document::OpenFile() //DICOM Fp->seekg(126L, std::ios::cur); - char dicm[4]; + char dicm[4] = {' ',' ',' ',' '}; Fp->read(dicm, (size_t)4); if( Fp->eof() ) { diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 0644f920..71d26f61 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2005/02/06 14:39:35 $ - Version: $Revision: 1.213 $ + Date: $Date: 2005/02/07 09:51:03 $ + Version: $Revision: 1.214 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -370,7 +370,7 @@ float File::GetXSpacing() float xspacing, yspacing; const std::string &strSpacing = GetEntryValue(0x0028,0x0030); - if ( strSpacing == GDCM_UNFOUND ) + if( strSpacing == GDCM_UNFOUND ) { gdcmWarningMacro( "Unfound Pixel Spacing (0028,0030)" ); return 1.; @@ -380,11 +380,12 @@ float File::GetXSpacing() if( ( nbValues = sscanf( strSpacing.c_str(), "%f\\%f", &yspacing, &xspacing)) != 2 ) { + // if no values, xspacing is set to 1.0 + if( nbValues == 0 ) + xspacing = 1.0; // if single value is found, xspacing is defaulted to yspacing - if ( nbValues == 1 ) - { + if( nbValues == 1 ) xspacing = yspacing; - } if ( xspacing == 0.0 ) xspacing = 1.0; @@ -425,7 +426,11 @@ float File::GetYSpacing() } // if sscanf cannot read any float value, it won't affect yspacing - sscanf( strSpacing.c_str(), "%f", &yspacing); + int nbValues = sscanf( strSpacing.c_str(), "%f", &yspacing); + + // if no values, xspacing is set to 1.0 + if( nbValues == 0 ) + yspacing = 1.0; if ( yspacing == 0.0 ) yspacing = 1.0;