diff --git a/CMakeLists.txt b/CMakeLists.txt index 7768e76d3..fb65fea65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -289,6 +289,7 @@ FIND_PACKAGE(ZLIB) FIND_PACKAGE(GDAL) FIND_PACKAGE(CURL) FIND_PACKAGE(ITK) +FIND_PACKAGE(OurDCMTK) SET(wxWidgets_USE_LIBS base core gl net) FIND_PACKAGE(wxWidgets) diff --git a/CMakeModules/FindOurDCMTK.cmake b/CMakeModules/FindOurDCMTK.cmake new file mode 100644 index 000000000..5e8ac180a --- /dev/null +++ b/CMakeModules/FindOurDCMTK.cmake @@ -0,0 +1,159 @@ +# - find DCMTK libraries +# + +# DCMTK_INCLUDE_DIR - Directories to include to use DCMTK +# DCMTK_LIBRARIES - Files to link against to use DCMTK +# DCMTK_FOUND - If false, don't try to use DCMTK +# DCMTK_DIR - (optional) Source directory for DCMTK +# +# DCMTK_DIR can be used to make it simpler to find the various include +# directories and compiled libraries if you've just compiled it in the +# source tree. Just set it to the root of the tree where you extracted +# the source. +# +# Written for VXL by Amitha Perera. +# + +FIND_PATH( DCMTK_config_INCLUDE_DIR osconfig.h + ${DCMTK_DIR}/config/include + ${DCMTK_DIR}/include + /usr/local/include/dcmtk/config + /usr/include/dcmtk/config +) + +FIND_PATH( DCMTK_ofstd_INCLUDE_DIR ofstdinc.h + ${DCMTK_DIR}/ofstd/include + ${DCMTK_DIR}/include/ofstd + /usr/local/include/dcmtk/ofstd + /usr/include/dcmtk/ofstd +) + +FIND_LIBRARY( DCMTK_ofstd_LIBRARY ofstd + ${DCMTK_DIR}/ofstd/libsrc + ${DCMTK_DIR}/ofstd/libsrc/Release + ${DCMTK_DIR}/ofstd/libsrc/Debug + ${DCMTK_DIR}/ofstd/Release + ${DCMTK_DIR}/ofstd/Debug + ${DCMTK_DIR}/lib + /usr/local/lib64 + /usr/lib64 + /usr/local/lib + /usr/lib +) + + +FIND_PATH( DCMTK_dcmdata_INCLUDE_DIR dctypes.h + ${DCMTK_DIR}/dcmdata/include + ${DCMTK_DIR}/include/dcmdata + /usr/local/include/dcmtk/dcmdata + /usr/include/dcmtk/dcmdata +) + +FIND_LIBRARY( DCMTK_dcmdata_LIBRARY dcmdata + ${DCMTK_DIR}/dcmdata/libsrc + ${DCMTK_DIR}/dcmdata/libsrc/Release + ${DCMTK_DIR}/dcmdata/libsrc/Debug + ${DCMTK_DIR}/dcmdata/Release + ${DCMTK_DIR}/dcmdata/Debug + ${DCMTK_DIR}/lib + /usr/local/lib64 + /usr/lib64 + /usr/local/lib + /usr/lib +) + + +FIND_PATH( DCMTK_dcmimgle_INCLUDE_DIR dcmimage.h + ${DCMTK_DIR}/dcmimgle/include + ${DCMTK_DIR}/include/dcmimgle + /usr/local/include/dcmtk/dcmimgle + /usr/include/dcmtk/dcmimgle +) + +FIND_LIBRARY( DCMTK_dcmimgle_LIBRARY dcmimgle + ${DCMTK_DIR}/dcmimgle/libsrc + ${DCMTK_DIR}/dcmimgle/libsrc/Release + ${DCMTK_DIR}/dcmimgle/libsrc/Debug + ${DCMTK_DIR}/dcmimgle/Release + ${DCMTK_DIR}/dcmimgle/Debug + ${DCMTK_DIR}/lib + /usr/local/lib64 + /usr/lib64 + /usr/local/lib + /usr/lib +) + +FIND_LIBRARY(DCMTK_imagedb_LIBRARY imagedb + ${DCMTK_DIR}/imagectn/libsrc/Release + ${DCMTK_DIR}/imagectn/libsrc/ + ${DCMTK_DIR}/imagectn/libsrc/Debug + /usr/local/lib64 + /usr/lib64 + /usr/local/lib + /usr/lib +) + +FIND_LIBRARY(DCMTK_dcmnet_LIBRARY dcmnet + ${DCMTK_DIR}/dcmnet/libsrc/Release + ${DCMTK_DIR}/dcmnet/libsrc/Debug + ${DCMTK_DIR}/dcmnet/libsrc/ + /usr/local/lib64 + /usr/lib64 + /usr/local/lib + /usr/lib +) + + +IF( DCMTK_config_INCLUDE_DIR + AND DCMTK_ofstd_INCLUDE_DIR + AND DCMTK_ofstd_LIBRARY + AND DCMTK_dcmdata_INCLUDE_DIR + AND DCMTK_dcmdata_LIBRARY + AND DCMTK_dcmimgle_INCLUDE_DIR + AND DCMTK_dcmimgle_LIBRARY ) + + SET( DCMTK_FOUND "YES" ) + SET( DCMTK_INCLUDE_DIR + ${DCMTK_config_INCLUDE_DIR} + ${DCMTK_ofstd_INCLUDE_DIR} + ${DCMTK_dcmdata_INCLUDE_DIR} + ${DCMTK_dcmimgle_INCLUDE_DIR} + ) + + SET( DCMTK_LIBRARIES + ${DCMTK_dcmimgle_LIBRARY} + ${DCMTK_dcmdata_LIBRARY} + ${DCMTK_ofstd_LIBRARY} + ${DCMTK_config_LIBRARY} + ) + + IF(DCMTK_imagedb_LIBRARY) + SET( DCMTK_LIBRARIES + ${DCMTK_LIBRARIES} + ${DCMTK_imagedb_LIBRARY} + ) + ENDIF(DCMTK_imagedb_LIBRARY) + + IF(DCMTK_dcmnet_LIBRARY) + SET( DCMTK_LIBRARIES + ${DCMTK_LIBRARIES} + ${DCMTK_dcmnet_LIBRARY} + ) + ENDIF(DCMTK_dcmnet_LIBRARY) + + IF( WIN32 ) + SET( DCMTK_LIBRARIES ${DCMTK_LIBRARIES} netapi32 ) + ENDIF( WIN32 ) + +ENDIF( DCMTK_config_INCLUDE_DIR + AND DCMTK_ofstd_INCLUDE_DIR + AND DCMTK_ofstd_LIBRARY + AND DCMTK_dcmdata_INCLUDE_DIR + AND DCMTK_dcmdata_LIBRARY + AND DCMTK_dcmimgle_INCLUDE_DIR + AND DCMTK_dcmimgle_LIBRARY ) + +IF( NOT DCMTK_FOUND ) + SET( DCMTK_DIR "" CACHE PATH "Root of DCMTK source tree (optional)." ) + MARK_AS_ADVANCED( DCMTK_DIR ) +ENDIF( NOT DCMTK_FOUND ) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index dbad28ea8..3c3e7bd47 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -437,6 +437,7 @@ osg::Image* createTexture3D(ImageList& imageList, ProcessRow& processRow, osg::Image* image = itr->get(); GLenum pixelFormat = image->getPixelFormat(); if (pixelFormat==GL_ALPHA || + pixelFormat==GL_INTENSITY || pixelFormat==GL_LUMINANCE || pixelFormat==GL_LUMINANCE_ALPHA || pixelFormat==GL_RGB || @@ -519,6 +520,7 @@ osg::Image* createTexture3D(ImageList& imageList, ProcessRow& processRow, GLenum pixelFormat = image->getPixelFormat(); if (pixelFormat==GL_ALPHA || pixelFormat==GL_LUMINANCE || + pixelFormat==GL_INTENSITY || pixelFormat==GL_LUMINANCE_ALPHA || pixelFormat==GL_RGB || pixelFormat==GL_RGBA) @@ -1849,54 +1851,59 @@ int main( int argc, char **argv ) if (!arguments.isOption(pos)) { std::string filename = arguments[pos]; - - osgDB::FileType fileType = osgDB::fileType(filename); - if (fileType == osgDB::FILE_NOT_FOUND) + if (osgDB::getLowerCaseFileExtension(filename)=="dicom") { - filename = osgDB::findDataFile(filename); - fileType = osgDB::fileType(filename); - } - - if (fileType == osgDB::DIRECTORY) - { - osgDB::DirectoryContents contents = osgDB::getDirectoryContents(filename); - - std::sort(contents.begin(), contents.end()); - - ImageList imageList; - for(osgDB::DirectoryContents::iterator itr = contents.begin(); - itr != contents.end(); - ++itr) - { - std::string localFile = filename + "/" + *itr; - std::cout<<"contents = "< #include - #include - #include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include +#ifdef USE_DCMTK + #define HAVE_CONFIG_H + #include + #include + #include + #include +#endif + +#ifdef USE_ITK + #include + #include + #include + #include + #include + #include + #include +#endif #include #include @@ -91,6 +100,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter return 0; } + +#ifdef USE_ITK virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); @@ -167,6 +178,224 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter return image; } +#endif + +#ifdef USE_DCMTK + + typedef std::vector Files; + bool getDicomFilesInDirectory(const std::string& path, Files& files) const + { + osgDB::DirectoryContents contents = osgDB::getDirectoryContents(path); + + std::sort(contents.begin(), contents.end()); + + for(osgDB::DirectoryContents::iterator itr = contents.begin(); + itr != contents.end(); + ++itr) + { + std::string localFile = path + "/" + *itr; + std::cout<<"contents = "< matrix = new osg::RefMatrix; + osg::ref_ptr image; + unsigned int imageNum = 0; + EP_Representation pixelRep; + unsigned int numPlanes = 0; + GLenum pixelFormat = 0; + GLenum dataType = 0; + unsigned int pixelSize = 0; + + for(Files::iterator itr = files.begin(); + itr != files.end(); + ++itr) + { + std::auto_ptr dcmImage(new DicomImage((*itr).c_str())); + if (dcmImage.get()) + { + if (dcmImage->getStatus()==EIS_Normal) + { + // get the pixel data + const DiPixel* pixelData = dcmImage->getInterData(); + if(!pixelData) return ReadResult::ERROR_IN_READING_FILE; + + if (!image) + { + // read dicom file format to extra spacing info + DcmFileFormat fileformat; + OFCondition status = fileformat.loadFile((*itr).c_str()); + if(!status.good()) return ReadResult::ERROR_IN_READING_FILE; + + // get the dimension of the dicom image + OFString spacingString; + if(fileformat.getDataset()->findAndGetOFString(DCM_PixelSpacing, spacingString).good()) + { + float xy_spacing = atof(spacingString.c_str()); + (*matrix)(0,0) = xy_spacing; + (*matrix)(1,1) = xy_spacing * dcmImage->getWidthHeightRatio(); + } + + // Get slice thickness + if(fileformat.getDataset()->findAndGetOFString(DCM_SliceThickness, spacingString).good()) + { + (*matrix)(2,2) = atof(spacingString.c_str()); + } + + + osg::notify(osg::NOTICE)<<"dicomImage->getWidth() = "<getWidth()<getHeight() = "<getHeight()<getFrameCount() = "<getFrameCount()<getCount() = "<getCount()<getPlanes(); + switch(numPlanes) + { + case(1): + pixelFormat = GL_LUMINANCE; + break; + case(2): + pixelFormat = GL_LUMINANCE_ALPHA; + pixelSize *= 2; + break; + case(3): + pixelFormat = GL_RGB; + pixelSize *= 3; + break; + case(4): + pixelFormat = GL_RGBA; + pixelSize *= 4; + break; + } + + image = new osg::Image; + image->setFileName(fileName.c_str()); + image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), files.size() * dcmImage->getFrameCount(), + pixelFormat, dataType); + + } + + if (pixelData->getPlanes()==numPlanes && + pixelData->getRepresentation()==pixelRep && + dcmImage->getWidth()==image->s() && + dcmImage->getHeight()==image->t()) + { + int numFramesToCopy = std::min(static_cast(image->r()-imageNum), + static_cast(dcmImage->getFrameCount())); + unsigned int numPixels = dcmImage->getWidth() * dcmImage->getHeight() * numFramesToCopy; + unsigned int dataSize = numPixels * pixelSize; + memcpy(image->data(imageNum), pixelData->getData(), dataSize); + imageNum += numFramesToCopy; + } + } + else + { + osg::notify(osg::NOTICE)<<"Error in reading dicom file "<